diff options
author | Michael Gapczynski <GapczynskiM@gmail.com> | 2011-07-04 16:36:30 -0400 |
---|---|---|
committer | Michael Gapczynski <GapczynskiM@gmail.com> | 2011-07-04 16:36:30 -0400 |
commit | 05389827fd8bc70b1092dc2bae1ed0335536cf4c (patch) | |
tree | 84dea83406b3b5d5cc0cf270a4e95875f3956300 | |
parent | e24e2d0e16a360753cc0430f2ba75f903c669b14 (diff) | |
parent | 53ae56097de2098a2ffd1a8dd1076825bc93305d (diff) | |
download | nextcloud-server-05389827fd8bc70b1092dc2bae1ed0335536cf4c.tar.gz nextcloud-server-05389827fd8bc70b1092dc2bae1ed0335536cf4c.zip |
Merge branch 'master' into sharing
Conflicts:
.gitignore
lib/base.php
-rw-r--r-- | .gitignore | 11 | ||||
-rw-r--r-- | .htaccess | 3 | ||||
-rw-r--r-- | 3dparty/MDB2.php | 10 | ||||
-rw-r--r-- | 3dparty/MDB2/Schema/Parser.php | 9 | ||||
-rw-r--r-- | 3dparty/MDB2/Schema/Validate.php | 5 | ||||
-rw-r--r-- | 3dparty/PEAR.php | 12 | ||||
-rw-r--r-- | admin/ajax/changepassword.php | 2 | ||||
-rw-r--r-- | admin/ajax/creategroup.php | 2 | ||||
-rw-r--r-- | admin/ajax/createuser.php | 2 | ||||
-rw-r--r-- | admin/ajax/disableapp.php | 9 | ||||
-rw-r--r-- | admin/ajax/enableapp.php | 9 | ||||
-rw-r--r-- | admin/ajax/removegroup.php | 2 | ||||
-rw-r--r-- | admin/ajax/removeuser.php | 2 | ||||
-rw-r--r-- | admin/ajax/togglegroups.php | 2 | ||||
-rw-r--r-- | admin/appinfo/app.php | 3 | ||||
-rw-r--r-- | admin/apps.php | 98 | ||||
-rw-r--r-- | admin/css/apps.css | 19 | ||||
-rw-r--r-- | admin/js/apps.js | 18 | ||||
-rw-r--r-- | admin/l10n/da.php | 20 | ||||
-rw-r--r-- | admin/l10n/de.php | 20 | ||||
-rw-r--r-- | admin/l10n/nl.php | 20 | ||||
-rw-r--r-- | admin/l10n/pl.php | 21 | ||||
-rw-r--r-- | admin/l10n/xgettextfiles | 5 | ||||
-rw-r--r-- | admin/plugins.php | 52 | ||||
-rw-r--r-- | admin/system.php | 2 | ||||
-rw-r--r-- | admin/templates/app.php | 6 | ||||
-rw-r--r-- | admin/templates/app_noconn.php | 7 | ||||
-rw-r--r-- | admin/templates/apps.php | 8 | ||||
-rw-r--r-- | admin/templates/appsinst.php | 27 | ||||
-rw-r--r-- | admin/templates/plugins.php | 28 | ||||
-rw-r--r-- | admin/templates/system.php | 4 | ||||
-rw-r--r-- | admin/templates/users.php | 40 | ||||
-rw-r--r-- | admin/users.php | 2 | ||||
-rw-r--r-- | apps/files_publiclink/admin.php | 2 | ||||
-rw-r--r-- | apps/files_publiclink/appinfo/database.xml | 2 | ||||
-rw-r--r-- | apps/files_publiclink/js/admin.js | 6 | ||||
-rw-r--r-- | apps/files_publiclink/lib_public.php | 6 | ||||
-rw-r--r-- | apps/files_publiclink/templates/admin.php | 10 | ||||
-rw-r--r-- | apps/files_publiclink/templates/index.php | 6 | ||||
-rw-r--r-- | apps/user_ldap/appinfo/app.php | 39 | ||||
-rw-r--r-- | apps/user_ldap/appinfo/info.xml | 10 | ||||
-rw-r--r-- | apps/user_ldap/settings.php | 52 | ||||
-rw-r--r-- | apps/user_ldap/templates/settings.php | 27 | ||||
-rw-r--r-- | apps/user_ldap/user_ldap.php | 114 | ||||
-rw-r--r-- | apps/user_openid/appinfo/app.php | 47 | ||||
-rw-r--r-- | apps/user_openid/appinfo/info.xml | 10 | ||||
-rw-r--r-- | apps/user_openid/class.openid.v3.php | 328 | ||||
-rw-r--r-- | apps/user_openid/phpmyid.php | 1740 | ||||
-rw-r--r-- | apps/user_openid/settings.php | 24 | ||||
-rw-r--r-- | apps/user_openid/templates/nomode.php | 28 | ||||
-rw-r--r-- | apps/user_openid/templates/settings.php | 7 | ||||
-rw-r--r-- | apps/user_openid/user.php | 47 | ||||
-rw-r--r-- | apps/user_openid/user_openid.php | 71 | ||||
-rwxr-xr-x[-rw-r--r--] | config/.gitignore | 0 | ||||
-rw-r--r-- | core/ajax/translations.php | 34 | ||||
-rw-r--r-- | core/css/images/no.png (renamed from css/images/no.png) | bin | 1300 -> 1300 bytes | |||
-rw-r--r-- | core/css/images/ui-bg_diagonals-thick_90_eeeeee_40x40.png (renamed from css/images/ui-bg_diagonals-thick_90_eeeeee_40x40.png) | bin | 251 -> 251 bytes | |||
-rw-r--r-- | core/css/images/ui-bg_flat_15_cd0a0a_40x100.png (renamed from css/images/ui-bg_flat_15_cd0a0a_40x100.png) | bin | 181 -> 181 bytes | |||
-rw-r--r-- | core/css/images/ui-bg_glass_100_e4f1fb_1x400.png (renamed from css/images/ui-bg_glass_100_e4f1fb_1x400.png) | bin | 119 -> 119 bytes | |||
-rw-r--r-- | core/css/images/ui-bg_glass_50_3baae3_1x400.png (renamed from css/images/ui-bg_glass_50_3baae3_1x400.png) | bin | 131 -> 131 bytes | |||
-rw-r--r-- | core/css/images/ui-bg_glass_80_d7ebf9_1x400.png (renamed from css/images/ui-bg_glass_80_d7ebf9_1x400.png) | bin | 124 -> 124 bytes | |||
-rw-r--r-- | core/css/images/ui-bg_highlight-hard_100_f2f5f7_1x100.png (renamed from css/images/ui-bg_highlight-hard_100_f2f5f7_1x100.png) | bin | 103 -> 103 bytes | |||
-rw-r--r-- | core/css/images/ui-bg_highlight-hard_70_000000_1x100.png (renamed from css/images/ui-bg_highlight-hard_70_000000_1x100.png) | bin | 118 -> 118 bytes | |||
-rw-r--r-- | core/css/images/ui-bg_highlight-soft_100_deedf7_1x100.png (renamed from css/images/ui-bg_highlight-soft_100_deedf7_1x100.png) | bin | 104 -> 104 bytes | |||
-rw-r--r-- | core/css/images/ui-bg_highlight-soft_25_ffef8f_1x100.png (renamed from css/images/ui-bg_highlight-soft_25_ffef8f_1x100.png) | bin | 153 -> 153 bytes | |||
-rw-r--r-- | core/css/images/ui-icons_2694e8_256x240.png (renamed from css/images/ui-icons_2694e8_256x240.png) | bin | 5355 -> 5355 bytes | |||
-rw-r--r-- | core/css/images/ui-icons_2e83ff_256x240.png (renamed from css/images/ui-icons_2e83ff_256x240.png) | bin | 4369 -> 4369 bytes | |||
-rw-r--r-- | core/css/images/ui-icons_3d80b3_256x240.png (renamed from css/images/ui-icons_3d80b3_256x240.png) | bin | 5355 -> 5355 bytes | |||
-rw-r--r-- | core/css/images/ui-icons_72a7cf_256x240.png (renamed from css/images/ui-icons_72a7cf_256x240.png) | bin | 4369 -> 4369 bytes | |||
-rw-r--r-- | core/css/images/ui-icons_ffffff_256x240.png (renamed from css/images/ui-icons_ffffff_256x240.png) | bin | 4369 -> 4369 bytes | |||
-rw-r--r-- | core/css/jquery-ui-1.8.10.custom.css (renamed from css/jquery-ui-1.8.10.custom.css) | 0 | ||||
-rw-r--r-- | core/css/styles.css (renamed from css/styles.css) | 1 | ||||
-rw-r--r-- | core/img/actions/arrow-down.png (renamed from img/actions/arrow-down.png) | bin | 525 -> 525 bytes | |||
-rw-r--r-- | core/img/actions/arrow-left.png (renamed from img/actions/arrow-left.png) | bin | 512 -> 512 bytes | |||
-rw-r--r-- | core/img/actions/arrow-right.png (renamed from img/actions/arrow-right.png) | bin | 527 -> 527 bytes | |||
-rw-r--r-- | core/img/actions/arrow-up.png (renamed from img/actions/arrow-up.png) | bin | 484 -> 484 bytes | |||
-rw-r--r-- | core/img/actions/go-home.png (renamed from img/actions/go-home.png) | bin | 397 -> 397 bytes | |||
-rw-r--r-- | core/img/body_background.jpg (renamed from img/body_background.jpg) | bin | 305 -> 305 bytes | |||
-rw-r--r-- | core/img/drop-arrow.png (renamed from img/drop-arrow.png) | bin | 2899 -> 2899 bytes | |||
-rw-r--r-- | core/img/favicon-touch.png (renamed from img/favicon-touch.png) | bin | 7272 -> 7272 bytes | |||
-rw-r--r-- | core/img/favicon.png (renamed from img/favicon.png) | bin | 565 -> 565 bytes | |||
-rw-r--r-- | core/img/header-a.png (renamed from img/header-a.png) | bin | 2951 -> 2951 bytes | |||
-rw-r--r-- | core/img/header-login.png (renamed from img/header-login.png) | bin | 2402 -> 2402 bytes | |||
-rw-r--r-- | core/img/header-settings-a.png (renamed from img/header-settings-a.png) | bin | 2885 -> 2885 bytes | |||
-rw-r--r-- | core/img/header-settings.png (renamed from img/header-settings.png) | bin | 2887 -> 2887 bytes | |||
-rw-r--r-- | core/img/header.png (renamed from img/header.png) | bin | 2953 -> 2953 bytes | |||
-rw-r--r-- | core/img/layout/back.png (renamed from img/layout/back.png) | bin | 396 -> 396 bytes | |||
-rw-r--r-- | core/img/layout/logout.png (renamed from img/layout/logout.png) | bin | 657 -> 657 bytes | |||
-rw-r--r-- | core/img/layout/settings.png (renamed from img/layout/settings.png) | bin | 695 -> 695 bytes | |||
-rw-r--r-- | core/img/mimetypes/file.png (renamed from img/mimetypes/file.png) | bin | 391 -> 391 bytes | |||
-rw-r--r-- | core/img/owncloud-logo-medium-white.png (renamed from img/owncloud-logo-medium-white.png) | bin | 15478 -> 15478 bytes | |||
-rw-r--r-- | core/img/owncloud-logo-small-white.png (renamed from img/owncloud-logo-small-white.png) | bin | 5444 -> 5444 bytes | |||
-rw-r--r-- | core/img/places/folder.png (renamed from img/places/folder.png) | bin | 386 -> 386 bytes | |||
-rw-r--r-- | core/img/weather-clear.png (renamed from img/weather-clear.png) | bin | 21917 -> 21917 bytes | |||
-rw-r--r-- | core/js/jquery-1.5.min.js (renamed from js/jquery-1.5.min.js) | 0 | ||||
-rw-r--r-- | core/js/jquery-ui-1.8.10.custom.min.js (renamed from js/jquery-ui-1.8.10.custom.min.js) | 0 | ||||
-rw-r--r-- | core/js/js.js | 23 | ||||
-rw-r--r-- | core/js/setup.js (renamed from js/js.js) | 10 | ||||
-rw-r--r-- | core/l10n/da.php | 27 | ||||
-rw-r--r-- | core/l10n/de.php | 27 | ||||
-rw-r--r-- | core/l10n/l10n-de.php | 5 | ||||
-rw-r--r-- | core/l10n/nl.php | 27 | ||||
-rw-r--r-- | core/l10n/pl.php | 27 | ||||
-rw-r--r-- | core/l10n/xgettextfiles | 7 | ||||
-rw-r--r-- | core/templates/404.php (renamed from templates/404.php) | 4 | ||||
-rw-r--r-- | core/templates/error.php (renamed from templates/error.php) | 0 | ||||
-rw-r--r-- | core/templates/installation.php | 70 | ||||
-rw-r--r-- | core/templates/layout.admin.php (renamed from templates/layout.admin.php) | 35 | ||||
-rw-r--r-- | core/templates/layout.guest.php (renamed from templates/layout.guest.php) | 18 | ||||
-rw-r--r-- | core/templates/layout.user.php (renamed from templates/layout.user.php) | 15 | ||||
-rw-r--r-- | core/templates/login.php (renamed from templates/login.php) | 2 | ||||
-rw-r--r-- | core/templates/logout.php | 1 | ||||
-rw-r--r-- | core/templates/part.pagenavi.php (renamed from templates/part.pagenavi.php) | 4 | ||||
-rw-r--r-- | core/templates/part.searchbox.php (renamed from templates/part.searchbox.php) | 2 | ||||
-rw-r--r-- | db_structure.xml | 10 | ||||
-rw-r--r-- | docs/createtranslation.pl | 29 | ||||
-rw-r--r-- | docs/getstrings.pl | 18 | ||||
-rw-r--r-- | files/admin.php | 2 | ||||
-rw-r--r-- | files/appinfo/app.php | 2 | ||||
-rw-r--r-- | files/css/files.css | 2 | ||||
-rw-r--r-- | files/img/drop-arrow.png | bin | 0 -> 2899 bytes | |||
-rw-r--r-- | files/js/fileactions.js | 13 | ||||
-rw-r--r-- | files/js/filelist.js | 8 | ||||
-rw-r--r-- | files/js/files.js | 3 | ||||
-rw-r--r-- | files/templates/admin.php | 30 | ||||
-rw-r--r-- | files/templates/index.php | 14 | ||||
-rw-r--r-- | help/l10n/da.php | 4 | ||||
-rw-r--r-- | help/l10n/de.php | 4 | ||||
-rw-r--r-- | help/l10n/nl.php | 4 | ||||
-rw-r--r-- | help/l10n/pl.php | 4 | ||||
-rw-r--r-- | help/l10n/xgettextfiles | 1 | ||||
-rw-r--r-- | help/templates/index.php | 4 | ||||
-rw-r--r-- | index.php | 4 | ||||
-rw-r--r-- | l10n/da/admin.po | 96 | ||||
-rw-r--r-- | l10n/da/core.po | 118 | ||||
-rw-r--r-- | l10n/da/help.po | 26 | ||||
-rw-r--r-- | l10n/da/log.po | 66 | ||||
-rw-r--r-- | l10n/da/settings.po | 87 | ||||
-rw-r--r-- | l10n/de/admin.po | 91 | ||||
-rw-r--r-- | l10n/de/core.po | 122 | ||||
-rw-r--r-- | l10n/de/help.po | 26 | ||||
-rw-r--r-- | l10n/de/log.po | 67 | ||||
-rw-r--r-- | l10n/de/settings.po | 86 | ||||
-rw-r--r-- | l10n/l10n.pl | 102 | ||||
-rw-r--r-- | l10n/nl/admin.po | 92 | ||||
-rw-r--r-- | l10n/nl/core.po | 122 | ||||
-rw-r--r-- | l10n/nl/help.po | 27 | ||||
-rw-r--r-- | l10n/nl/log.po | 67 | ||||
-rw-r--r-- | l10n/nl/settings.po | 86 | ||||
-rw-r--r-- | l10n/pl/admin.po | 96 | ||||
-rw-r--r-- | l10n/pl/core.po | 123 | ||||
-rw-r--r-- | l10n/pl/help.po | 28 | ||||
-rw-r--r-- | l10n/pl/log.po | 68 | ||||
-rw-r--r-- | l10n/pl/settings.po | 88 | ||||
-rw-r--r-- | l10n/templates/admin.pot | 95 | ||||
-rw-r--r-- | l10n/templates/core.pot | 120 | ||||
-rw-r--r-- | l10n/templates/help.pot | 26 | ||||
-rw-r--r-- | l10n/templates/log.pot | 66 | ||||
-rw-r--r-- | l10n/templates/settings.pot | 86 | ||||
-rw-r--r-- | lib/HTTP/WebDAV/Server/Filesystem.php | 7 | ||||
-rw-r--r-- | lib/MDB2/Driver/Datatype/sqlite3.php | 412 | ||||
-rw-r--r-- | lib/MDB2/Driver/Function/sqlite3.php | 161 | ||||
-rw-r--r-- | lib/MDB2/Driver/Manager/sqlite3.php | 1364 | ||||
-rw-r--r-- | lib/MDB2/Driver/Native/sqlite3.php | 58 | ||||
-rw-r--r-- | lib/MDB2/Driver/Reverse/sqlite3.php | 607 | ||||
-rw-r--r-- | lib/MDB2/Driver/sqlite3.php | 1361 | ||||
-rw-r--r-- | lib/User/backend.php | 126 | ||||
-rw-r--r-- | lib/User/database.php | 97 | ||||
-rw-r--r-- | lib/User/example.php | 97 | ||||
-rw-r--r-- | lib/app.php | 138 | ||||
-rw-r--r-- | lib/base.php | 33 | ||||
-rw-r--r-- | lib/config.php | 5 | ||||
-rw-r--r-- | lib/database.php | 52 | ||||
-rw-r--r-- | lib/files.php | 15 | ||||
-rw-r--r-- | lib/filestorage.php | 2 | ||||
-rw-r--r-- | lib/filesystem.php | 231 | ||||
-rwxr-xr-x[-rw-r--r--] | lib/helper.php | 43 | ||||
-rw-r--r-- | lib/installer.php | 83 | ||||
-rw-r--r-- | lib/l10n.php | 269 | ||||
-rw-r--r-- | lib/log.php | 14 | ||||
-rw-r--r-- | lib/ocsclient.php | 128 | ||||
-rw-r--r-- | lib/preferences.php | 8 | ||||
-rw-r--r-- | lib/setup.php | 36 | ||||
-rw-r--r-- | lib/template.php | 49 | ||||
-rw-r--r-- | lib/testcase.php | 93 | ||||
-rw-r--r-- | lib/user.php | 121 | ||||
-rw-r--r-- | log/index.php | 38 | ||||
-rw-r--r-- | log/js/log.js | 6 | ||||
-rw-r--r-- | log/l10n/da.php | 14 | ||||
-rw-r--r-- | log/l10n/de.php | 14 | ||||
-rw-r--r-- | log/l10n/nl.php | 14 | ||||
-rw-r--r-- | log/l10n/pl.php | 14 | ||||
-rw-r--r-- | log/l10n/xgettextfiles | 1 | ||||
-rw-r--r-- | log/templates/index.php | 40 | ||||
-rw-r--r-- | search/index.php | 3 | ||||
-rw-r--r-- | settings/ajax/changepassword.php | 12 | ||||
-rw-r--r-- | settings/ajax/setlanguage.php | 26 | ||||
-rw-r--r-- | settings/index.php | 7 | ||||
-rw-r--r-- | settings/js/main.js | 14 | ||||
-rw-r--r-- | settings/l10n/da.php | 19 | ||||
-rw-r--r-- | settings/l10n/de.php | 19 | ||||
-rw-r--r-- | settings/l10n/nl.php | 19 | ||||
-rw-r--r-- | settings/l10n/pl.php | 19 | ||||
-rw-r--r-- | settings/l10n/xgettextfiles | 3 | ||||
-rw-r--r-- | settings/templates/index.php | 52 | ||||
-rw-r--r-- | templates/installation.php | 70 | ||||
-rw-r--r-- | templates/logout.php | 1 | ||||
-rw-r--r-- | tests/index.php | 79 | ||||
-rw-r--r-- | tests/lib/filesystem.php | 222 | ||||
-rw-r--r-- | tests/templates/index.php | 11 |
210 files changed, 11158 insertions, 797 deletions
diff --git a/.gitignore b/.gitignore index fd29bd8c1d3..fa2b7459e63 100644 --- a/.gitignore +++ b/.gitignore @@ -16,6 +16,15 @@ _darcs/* CVS/* .svn/* RCS/* + +# kdevelop .kdev *.kdev4 -.project
\ No newline at end of file +<<<<<<< HEAD +.project +======= + +# Lokalize +*lokalize* + +>>>>>>> master diff --git a/.htaccess b/.htaccess index 58230365bf5..c818c9ca2ea 100644 --- a/.htaccess +++ b/.htaccess @@ -1,4 +1,5 @@ -ErrorDocument 404 //owncloud/templates/404.php +ErrorDocument 404 //core/templates/404.php php_value upload_max_filesize 20M php_value post_max_size 20M SetEnv htaccessWorking true +Options -Indexes diff --git a/3dparty/MDB2.php b/3dparty/MDB2.php index 30e564f1457..fbc7107914e 100644 --- a/3dparty/MDB2.php +++ b/3dparty/MDB2.php @@ -639,7 +639,7 @@ class MDB2 */ static function isError($data, $code = null) { - if (is_a($data, 'MDB2_Error')) { + if ($data instanceof MDB2_Error) { if (is_null($code)) { return true; } elseif (is_string($code)) { @@ -666,7 +666,7 @@ class MDB2 */ static function isConnection($value) { - return is_a($value, 'MDB2_Driver_Common'); + return ($value instanceof MDB2_Driver_Common); } // }}} @@ -683,7 +683,7 @@ class MDB2 */ static function isResult($value) { - return is_a($value, 'MDB2_Result'); + return $value instanceof MDB2_Result; } // }}} @@ -700,7 +700,7 @@ class MDB2 */ static function isResultCommon($value) { - return is_a($value, 'MDB2_Result_Common'); + return ($value instanceof MDB2_Result_Common); } // }}} @@ -717,7 +717,7 @@ class MDB2 */ static function isStatement($value) { - return is_a($value, 'MDB2_Statement_Common'); + return $value instanceof MDB2_Statement_Common; } // }}} diff --git a/3dparty/MDB2/Schema/Parser.php b/3dparty/MDB2/Schema/Parser.php index bd7a9657932..b740ef55fa8 100644 --- a/3dparty/MDB2/Schema/Parser.php +++ b/3dparty/MDB2/Schema/Parser.php @@ -127,13 +127,6 @@ class MDB2_Schema_Parser extends XML_Parser $this->val =new MDB2_Schema_Validate($fail_on_invalid_names, $valid_types, $force_defaults); } - function MDB2_Schema_Parser($variables, $fail_on_invalid_names = true, - $structure = false, $valid_types = array(), - $force_defaults = true) - { - $this->__construct($variables, $fail_on_invalid_names, $structure, $valid_types, $force_defaults); - } - function startHandler($xp, $element, $attribs) { if (strtolower($element) == 'variable') { @@ -503,7 +496,7 @@ class MDB2_Schema_Parser extends XML_Parser $this->element = implode('-', $this->elements); } - function &raiseError($msg = null, $xmlecode = 0, $xp = null, $ecode = MDB2_SCHEMA_ERROR_PARSE,$a=null,$b=null,$c=null) + function raiseError($msg = null, $xmlecode = 0, $xp = null, $ecode = MDB2_SCHEMA_ERROR_PARSE,$a=null,$b=null,$c=null) { if (is_null($this->error)) { $error = ''; diff --git a/3dparty/MDB2/Schema/Validate.php b/3dparty/MDB2/Schema/Validate.php index 21be024ce9f..217cf51b959 100644 --- a/3dparty/MDB2/Schema/Validate.php +++ b/3dparty/MDB2/Schema/Validate.php @@ -91,11 +91,6 @@ class MDB2_Schema_Validate $this->force_defaults = $force_defaults; } - function MDB2_Schema_Validate($fail_on_invalid_names = true, $valid_types = array(), $force_defaults = true) - { - $this->__construct($fail_on_invalid_names, $valid_types, $force_defaults); - } - // }}} // {{{ raiseError() diff --git a/3dparty/PEAR.php b/3dparty/PEAR.php index 9760b9d265a..f832c0d4916 100644 --- a/3dparty/PEAR.php +++ b/3dparty/PEAR.php @@ -249,7 +249,7 @@ class PEAR */ static function isError($data, $code = null) { - if (is_a($data, 'PEAR_Error')) { + if ($data instanceof PEAR_Error) { if (is_null($code)) { return true; } elseif (is_string($code)) { @@ -305,7 +305,7 @@ class PEAR function setErrorHandling($mode = null, $options = null) { - if (isset($this) && is_a($this, 'PEAR')) { + if (isset($this) && $this instanceof PEAR) { $setmode = &$this->_default_error_mode; $setoptions = &$this->_default_error_options; } else { @@ -557,7 +557,7 @@ class PEAR $code = null, $userinfo = null) { - if (isset($this) && is_a($this, 'PEAR')) { + if (isset($this) && $this instanceof PEAR) { return $this->raiseError($message, $code, null, null, $userinfo); } else { return PEAR::raiseError($message, $code, null, null, $userinfo); @@ -653,7 +653,7 @@ class PEAR function pushErrorHandling($mode, $options = null) { $stack = &$GLOBALS['_PEAR_error_handler_stack']; - if (isset($this) && is_a($this, 'PEAR')) { + if (isset($this) && $this instanceof PEAR) { $def_mode = &$this->_default_error_mode; $def_options = &$this->_default_error_options; } else { @@ -662,7 +662,7 @@ class PEAR } $stack[] = array($def_mode, $def_options); - if (isset($this) && is_a($this, 'PEAR')) { + if (isset($this) && $this instanceof PEAR) { $this->setErrorHandling($mode, $options); } else { PEAR::setErrorHandling($mode, $options); @@ -687,7 +687,7 @@ class PEAR array_pop($stack); list($mode, $options) = $stack[sizeof($stack) - 1]; array_pop($stack); - if (isset($this) && is_a($this, 'PEAR')) { + if (isset($this) && $this instanceof PEAR) { $this->setErrorHandling($mode, $options); } else { PEAR::setErrorHandling($mode, $options); diff --git a/admin/ajax/changepassword.php b/admin/ajax/changepassword.php index a8f3af15175..51634908a76 100644 --- a/admin/ajax/changepassword.php +++ b/admin/ajax/changepassword.php @@ -7,7 +7,7 @@ require_once('../../lib/base.php'); header( "Content-Type: application/jsonrequest" ); // Check if we are a user -if( !OC_USER::isLoggedIn() || !OC_GROUP::inGroup( $_SESSION['user_id'], 'admin' )){ +if( !OC_USER::isLoggedIn() || !OC_GROUP::inGroup( OC_USER::getUser(), 'admin' )){ echo json_encode( array( "status" => "error", "data" => array( "message" => "Authentication error" ))); exit(); } diff --git a/admin/ajax/creategroup.php b/admin/ajax/creategroup.php index eec27587930..df9a36aaa2f 100644 --- a/admin/ajax/creategroup.php +++ b/admin/ajax/creategroup.php @@ -7,7 +7,7 @@ require_once('../../lib/base.php'); header( "Content-Type: application/jsonrequest" ); // Check if we are a user -if( !OC_USER::isLoggedIn() || !OC_GROUP::inGroup( $_SESSION['user_id'], 'admin' )){ +if( !OC_USER::isLoggedIn() || !OC_GROUP::inGroup( OC_USER::getUser(), 'admin' )){ echo json_encode( array( "status" => "error", "data" => array( "message" => "Authentication error" ))); exit(); } diff --git a/admin/ajax/createuser.php b/admin/ajax/createuser.php index a6e4ec0e93d..507ded9079f 100644 --- a/admin/ajax/createuser.php +++ b/admin/ajax/createuser.php @@ -7,7 +7,7 @@ require_once('../../lib/base.php'); header( "Content-Type: application/jsonrequest" ); // Check if we are a user -if( !OC_USER::isLoggedIn() || !OC_GROUP::inGroup( $_SESSION['user_id'], 'admin' )){ +if( !OC_USER::isLoggedIn() || !OC_GROUP::inGroup( OC_USER::getUser(), 'admin' )){ echo json_encode( array( "status" => "error", "data" => array( "message" => "Authentication error" ))); exit(); } diff --git a/admin/ajax/disableapp.php b/admin/ajax/disableapp.php new file mode 100644 index 00000000000..d23f8de7ef0 --- /dev/null +++ b/admin/ajax/disableapp.php @@ -0,0 +1,9 @@ +<?php + +// Init owncloud +require_once('../../lib/base.php'); +header( "Content-Type: application/jsonrequest" ); + +OC_APP::disable($_POST['appid']); + +?> diff --git a/admin/ajax/enableapp.php b/admin/ajax/enableapp.php new file mode 100644 index 00000000000..d988d7fd2df --- /dev/null +++ b/admin/ajax/enableapp.php @@ -0,0 +1,9 @@ +<?php + +// Init owncloud +require_once('../../lib/base.php'); +header( "Content-Type: application/jsonrequest" ); + +OC_APP::enable($_POST['appid']); + +?> diff --git a/admin/ajax/removegroup.php b/admin/ajax/removegroup.php index c7991ba5819..e3d62e5fac8 100644 --- a/admin/ajax/removegroup.php +++ b/admin/ajax/removegroup.php @@ -7,7 +7,7 @@ require_once('../../lib/base.php'); header( "Content-Type: application/jsonrequest" ); // Check if we are a user -if( !OC_USER::isLoggedIn() || !OC_GROUP::inGroup( $_SESSION['user_id'], 'admin' )){ +if( !OC_USER::isLoggedIn() || !OC_GROUP::inGroup( OC_USER::getUser(), 'admin' )){ echo json_encode( array( "status" => "error", "data" => array( "message" => "Authentication error" ))); exit(); } diff --git a/admin/ajax/removeuser.php b/admin/ajax/removeuser.php index 7e587f16058..6b48146ad45 100644 --- a/admin/ajax/removeuser.php +++ b/admin/ajax/removeuser.php @@ -7,7 +7,7 @@ require_once('../../lib/base.php'); header( "Content-Type: application/jsonrequest" ); // Check if we are a user -if( !OC_USER::isLoggedIn() || !OC_GROUP::inGroup( $_SESSION['user_id'], 'admin' )){ +if( !OC_USER::isLoggedIn() || !OC_GROUP::inGroup( OC_USER::getUser(), 'admin' )){ echo json_encode( array( "status" => "error", "data" => array( "message" => "Authentication error" ))); exit(); } diff --git a/admin/ajax/togglegroups.php b/admin/ajax/togglegroups.php index f821ae0bfaa..5c7bd393e92 100644 --- a/admin/ajax/togglegroups.php +++ b/admin/ajax/togglegroups.php @@ -7,7 +7,7 @@ require_once('../../lib/base.php'); header( "Content-Type: application/jsonrequest" ); // Check if we are a user -if( !OC_USER::isLoggedIn() || !OC_GROUP::inGroup( $_SESSION['user_id'], 'admin' )){ +if( !OC_USER::isLoggedIn() || !OC_GROUP::inGroup( OC_USER::getUser(), 'admin' )){ echo json_encode( array( "status" => "error", "data" => array( "message" => "Authentication error" ))); exit(); } diff --git a/admin/appinfo/app.php b/admin/appinfo/app.php index e87013bd993..d01b7d5d624 100644 --- a/admin/appinfo/app.php +++ b/admin/appinfo/app.php @@ -5,9 +5,8 @@ OC_APP::register( array( "order" => 1, "id" => "admin", "name" => "Administratio OC_APP::addAdminPage( array( "id" => "core_system", "order" => 1, "href" => OC_HELPER::linkTo( "admin", "system.php" ), "name" =>"System", "icon" => OC_HELPER::imagePath( "admin", "administration.png" ))); OC_APP::addAdminPage( array( "id" => "core_users", "order" => 2, "href" => OC_HELPER::linkTo( "admin", "users.php" ), "name" => "Users", "icon" => OC_HELPER::imagePath( "admin", "users.png" ))); OC_APP::addAdminPage( array( "id" => "core_apps", "order" => 3, "href" => OC_HELPER::linkTo( "admin", "apps.php" ), "name" => "Apps", "icon" => OC_HELPER::imagePath( "admin", "apps.png" ))); -OC_APP::addAdminPage( array( "id" => "core_plugins", "order" => 4, "href" => OC_HELPER::linkTo( "admin", "plugins.php" ), "name" => "Plugins", "icon" => OC_HELPER::imagePath( "admin", "plugins.png" ))); // Add subentries for App installer -OC_APP::addNavigationSubEntry( "core_apps", array( "id" => "core_apps_installed", "order" => 4, "href" => OC_HELPER::linkTo( "admin", "apps.php?add=some¶meters=here" ), "name" => "Installed apps", "icon" => OC_HELPER::imagePath( "admin", "navicon.png" ))); +OC_APP::addNavigationSubEntry( "core_apps", array( "id" => "core_apps_installed", "order" => 4, "href" => OC_HELPER::linkTo( "admin", "apps.php?installed" ), "name" => "Installed apps", "icon" => OC_HELPER::imagePath( "admin", "navicon.png" ))); ?> diff --git a/admin/apps.php b/admin/apps.php index 7ce3f4c419f..b47611f536d 100644 --- a/admin/apps.php +++ b/admin/apps.php @@ -22,70 +22,88 @@ */ require_once('../lib/base.php'); +include_once('../lib/installer.php'); require( 'template.php' ); -if( !OC_USER::isLoggedIn() || !OC_GROUP::inGroup( $_SESSION['user_id'], 'admin' )){ +if( !OC_USER::isLoggedIn() || !OC_GROUP::inGroup( OC_USER::getUser(), 'admin' )){ header( "Location: ".OC_HELPER::linkTo( "", "index.php" )); exit(); } // Load the files we need OC_UTIL::addStyle( "admin", "apps" ); +OC_UTIL::addScript( "admin", "apps" ); if(isset($_GET['id'])) $id=$_GET['id']; else $id=0; if(isset($_GET['cat'])) $cat=$_GET['cat']; else $cat=0; +if(isset($_GET['installed'])) $installed=true; else $installed=false; + +if($installed){ + global $SERVERROOT; + OC_INSTALLER::installShippedApps(false); + $apps = OC_APPCONFIG::getApps(); + $records = array(); + + OC_APP::setActiveNavigationEntry( "core_apps_installed" ); + foreach($apps as $app){ + $info=OC_APP::getAppInfo("$SERVERROOT/apps/$app/appinfo/info.xml"); + $record = array( 'id' => $app, + 'name' => $info['name'], + 'version' => $info['version'], + 'author' => $info['author'], + 'enabled' => OC_APP::isEnabled( $app )); + $records[]=$record; + } -$categories=OC_OCSCLIENT::getCategories(); - -/* - -All -Installed Apps - + $tmpl = new OC_TEMPLATE( "admin", "appsinst", "admin" ); + $tmpl->assign( "apps", $records ); + $tmpl->printPage(); + unset($tmpl); + exit(); +}else{ + $categories=OC_OCSCLIENT::getCategories(); + if($categories==NULL){ + OC_APP::setActiveNavigationEntry( "core_apps" ); -foreach($categories as $key=>$value) { -print_r($value); -} + $tmpl = new OC_TEMPLATE( "admin", "app_noconn", "admin" ); + $tmpl->printPage(); + unset($tmpl); + exit(); + } -*/ + if($id==0) { + OC_APP::setActiveNavigationEntry( "core_apps" ); -// OC_APP::setActiveNavigationEntry( "core_apps_installed" ); + if($cat==0){ + $numcats=array(); + foreach($categories as $key=>$value) $numcats[]=$key; + $apps=OC_OCSCLIENT::getApplications($numcats); + }else{ + $apps=OC_OCSCLIENT::getApplications($cat); + } + // return template + $tmpl = new OC_TEMPLATE( "admin", "apps", "admin" ); -if($id==0) { - OC_APP::setActiveNavigationEntry( "core_apps" ); + $tmpl->assign( "categories", $categories ); + $tmpl->assign( "apps", $apps ); + $tmpl->printPage(); + unset($tmpl); - if($cat==0){ - $numcats=array(); - foreach($categories as $key=>$value) $numcats[]=$key; - $apps=OC_OCSCLIENT::getApplications($numcats); }else{ - $apps=OC_OCSCLIENT::getApplications($cat); - } + OC_APP::setActiveNavigationEntry( "core_apps" ); - // return template - $tmpl = new OC_TEMPLATE( "admin", "apps", "admin" ); + $app=OC_OCSCLIENT::getApplication($id); - $tmpl->assign( "categories", $categories ); - $tmpl->assign( "apps", $apps ); - $tmpl->printPage(); - unset($tmpl); - -}else{ - OC_APP::setActiveNavigationEntry( "core_apps" ); - - $app=OC_OCSCLIENT::getApplication($id); - - $tmpl = new OC_TEMPLATE( "admin", "app", "admin" ); - $tmpl->assign( "categories", $categories ); - $tmpl->assign( "app", $app ); - $tmpl->printPage(); - unset($tmpl); + $tmpl = new OC_TEMPLATE( "admin", "app", "admin" ); + $tmpl->assign( "categories", $categories ); + $tmpl->assign( "app", $app ); + $tmpl->printPage(); + unset($tmpl); + } } - ?> - diff --git a/admin/css/apps.css b/admin/css/apps.css index 7063762204a..cd427a3c536 100644 --- a/admin/css/apps.css +++ b/admin/css/apps.css @@ -7,6 +7,22 @@ table td.date text-align: right; } +table td.version, table td.enabled, table td.disabled +{ + padding: 0.5em 1em; + text-align: center; +} + +input[type="button"].enabled +{ + color: #006600; +} + +input[type="button"].disabled +{ + color: #660000; +} + .preview { padding: 3px; @@ -47,3 +63,6 @@ table td.name a } +input[type="button"].appbutton { padding:0.1em 1em; border:1px solid #999; font-weight:bold; font-size:0.9em; cursor:pointer; } +input[type="button"]:hover.appbutton, form input[type="submit"]:focus { border:1px solid #999; background-color:#999; outline:0; } +input[type="button"]:active.appbutton { outline:0; }
\ No newline at end of file diff --git a/admin/js/apps.js b/admin/js/apps.js new file mode 100644 index 00000000000..ee9d814eb0b --- /dev/null +++ b/admin/js/apps.js @@ -0,0 +1,18 @@ +$("input[x-use='appenablebutton']").live( "click", function(){ + appid = $(this).parent().parent().attr("x-uid"); + + //alert("dsfsdfsdf"); + if($(this).val() == "enabled"){ + $(this).attr("value","disabled"); + $(this).removeClass( "enabled" ); + $(this).addClass( "disabled" ); + //$.post( "ajax/disableapp.php", $(appid).serialize(), function(data){} ); + $.post( "ajax/disableapp.php", { appid: appid }, function(data){ alert(data.status);}); + } + else if($(this).val() == "disabled"){ + $(this).attr("value","enabled"); + $(this).removeClass( "disabled" ); + $(this).addClass( "enabled" ); + $.post( "ajax/enableapp.php", { appid: appid }, function(data){ alert(data.status);} ); + } +});
\ No newline at end of file diff --git a/admin/l10n/da.php b/admin/l10n/da.php new file mode 100644 index 00000000000..477dd9db9e2 --- /dev/null +++ b/admin/l10n/da.php @@ -0,0 +1,20 @@ +<?php $TRANSLATIONS = array( +"read more" => "læs mere", +"INSTALL" => "INSTALLER", +"Apps Repository" => "Applikation arkiv", +"Cannot connect to apps repository" => "Kan ikke oprette forbindelse til applikations arkivet", +"Name" => "Navn", +"Modified" => "Ændret", +"Administration" => "Administration", +"System Settings" => "System indstillinger", +"Add user" => "Tilføj bruger", +"Password" => "Kodeord", +"Create user" => "Lav bruger", +"remove" => "slet", +"Groups" => "Grupper", +"Create group" => "Lav gruppe", +"Force new password:" => "Tving ny adgangskode", +"Set" => "Indstil", +"Do you really want to delete user" => "Vil du virkelig slette denne bruger?", +"Do you really want to delete group" => "Vil du virkelig slette denne gruppe?" +); diff --git a/admin/l10n/de.php b/admin/l10n/de.php new file mode 100644 index 00000000000..9d1b12b1a16 --- /dev/null +++ b/admin/l10n/de.php @@ -0,0 +1,20 @@ +<?php $TRANSLATIONS = array( +"read more" => "mehr …", +"INSTALL" => "Installieren", +"Apps Repository" => "Anwendungen", +"Cannot connect to apps repository" => "Verbindung fehlgeschlagen", +"Name" => "Name", +"Modified" => "Änderungsdatum", +"Administration" => "Verwaltung", +"System Settings" => "Systemeinstellungen", +"Groups" => "Gruppen", +"Add user" => "Nutzer hinzufügen", +"Password" => "Passwort", +"Create user" => "Nutzer erstellen", +"remove" => "entfernen", +"Create group" => "Gruppe erstellen", +"Force new password:" => "Neues Passwort:", +"Set" => "OK", +"Do you really want to delete user" => "Möchtest du den Nutzer wirklich entfernen?", +"Do you really want to delete group" => "Möchtest du die Gruppe wirklich entfernen?" +); diff --git a/admin/l10n/nl.php b/admin/l10n/nl.php new file mode 100644 index 00000000000..cfbc1b0f515 --- /dev/null +++ b/admin/l10n/nl.php @@ -0,0 +1,20 @@ +<?php $TRANSLATIONS = array( +"read more" => "Meer informatie", +"INSTALL" => "Installeer", +"Apps Repository" => "Applicatiedatabase", +"Cannot connect to apps repository" => "Kan geen verbinding maken met de applicatiedatabase", +"Name" => "Naam", +"Modified" => "Laatst aangepast", +"Administration" => "Administratie", +"System Settings" => "Systeeminstellingen", +"Groups" => "Groepen", +"Add user" => "Gebruiker toevoegen", +"Password" => "Wachtwoord", +"Create user" => "Gebruiker aanmaken", +"remove" => "verwijder", +"Create group" => "Groep aanmaken", +"Force new password:" => "Forceer nieuw wachtwoord:", +"Set" => "Ok", +"Do you really want to delete user" => "Wilt u deze gebruiker verwijderen", +"Do you really want to delete group" => "Wilt u deze groep verwijderen" +); diff --git a/admin/l10n/pl.php b/admin/l10n/pl.php new file mode 100644 index 00000000000..9995c5da56f --- /dev/null +++ b/admin/l10n/pl.php @@ -0,0 +1,21 @@ +<?php $TRANSLATIONS = array( +"read more" => "czytaj więcej", +"INSTALL" => "INSTALUJ", +"Apps Repository" => "Repozytorium aplikacji", +"Cannot connect to apps repository" => "Nie można połączyć się z repozytorium aplikacji", +"Name" => "Nazwa", +"Modified" => "Zmodyfikowano", +"Administration" => "Administracja", +"System Settings" => "Ustawienia systemowe", +"Add user" => "Dodaj użytkownika", +"Password" => "Hasło", +"Create user" => "Utwórz użytkownika", +"remove" => "usuń", +"Groups" => "Grupy", +"Create group" => "Utwórz grupę", +"Force new password:" => "Wymuś nowe hasło", +"Set" => "Ustaw", +"Do you really want to delete user" => "Czy naprawdę chcesz usunąć użytkownika", +"Do you really want to delete group" => "Czy naprawdę chcesz usunąć grupę", +"Users" => "Użytkownicy" +); diff --git a/admin/l10n/xgettextfiles b/admin/l10n/xgettextfiles new file mode 100644 index 00000000000..37acbc25deb --- /dev/null +++ b/admin/l10n/xgettextfiles @@ -0,0 +1,5 @@ +../templates/app.php +../templates/app_noconn.php +../templates/apps.php +../templates/system.php +../templates/users.php diff --git a/admin/plugins.php b/admin/plugins.php deleted file mode 100644 index fd1933a7fa1..00000000000 --- a/admin/plugins.php +++ /dev/null @@ -1,52 +0,0 @@ -<?php - -/** -* ownCloud -* -* @author Frank Karlitschek -* @copyright 2010 Frank Karlitschek karlitschek@kde.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/>. -* -*/ - -require_once('../lib/base.php'); -require( 'template.php' ); -if( !OC_USER::isLoggedIn() || !OC_GROUP::inGroup( $_SESSION['user_id'], 'admin' )){ - header( "Location: ".OC_HELPER::linkTo( "index.php" )); - exit(); -} - -OC_APP::setActiveNavigationEntry( "core_plugins" ); -$plugins=array(); -$blacklist=OC_PLUGIN::loadBlackList(); - -foreach( OC_PLUGIN::listPlugins() as $i ){ - // Gather data about plugin - $data = OC_PLUGIN::getPluginData($plugin); - - // Is it enabled? - $data["enabled"] = ( array_search( $plugin, $blacklist ) === false ); - - // Add the data - $plugins[] = $data; -} - - -$tmpl = new OC_TEMPLATE( "admin", "plugins", "admin" ); -$tmpl->assign( "plugins", $plugins ); -$tmpl->printPage(); - -?> - diff --git a/admin/system.php b/admin/system.php index 310979295f0..284509144ee 100644 --- a/admin/system.php +++ b/admin/system.php @@ -23,7 +23,7 @@ require_once('../lib/base.php'); require( 'template.php' ); -if( !OC_USER::isLoggedIn() || !OC_GROUP::inGroup( $_SESSION['user_id'], 'admin' )){ +if( !OC_USER::isLoggedIn() || !OC_GROUP::inGroup( OC_USER::getUser(), 'admin' )){ header( "Location: ".OC_HELPER::linkTo( "index.php" )); exit(); } diff --git a/admin/templates/app.php b/admin/templates/app.php index 1ea31bdecde..c8989e323ce 100644 --- a/admin/templates/app.php +++ b/admin/templates/app.php @@ -6,7 +6,7 @@ $app=$_['app']; ?> <h1><?php echo $app["name"]; ?></h1> <?php echo('<span class="type">'.$app['typename'].'</span>'); ?><br /> -<span class="date"><?php echo OC_UTIL::formatdate($app["changed"]); ?></span><br /> +<span class="date"><?php echo $l->l('datetime', $app["changed"]); ?></span><br /> <table cellspacing="6" border="0" width="100%"> @@ -19,9 +19,9 @@ $app=$_['app']; <td class="description" valign="top"> <?php echo $app["description"]; ?> <br /> - <?php echo('<a class="description" target="_blank" href="'.$app["detailpage"].'">read more</a><br />'); ?> + <?php echo('<a class="description" target="_blank" href="'.$app["detailpage"].'">'.$l->t( 'read more' ).'</a><br />'); ?> </td> - <td width="1" valign="top"><a class="prettybutton" href="">INSTALL</a></td> + <td width="1" valign="top"><a class="prettybutton" href=""><?php echo $l->t( 'INSTALL' ); ?></a></td> </tr> </table> diff --git a/admin/templates/app_noconn.php b/admin/templates/app_noconn.php new file mode 100644 index 00000000000..70b7d9b3119 --- /dev/null +++ b/admin/templates/app_noconn.php @@ -0,0 +1,7 @@ +<?php +/* + * Template for Apps when can't connect to app store + */ +?> +<h1><?php echo $l->t( 'Apps Repository' ); ?></h1> +<h2><?php echo $l->t( 'Cannot connect to apps repository' ); ?></h2> diff --git a/admin/templates/apps.php b/admin/templates/apps.php index 36a7cd53029..593aad63182 100644 --- a/admin/templates/apps.php +++ b/admin/templates/apps.php @@ -3,15 +3,15 @@ * Template for Apps */ ?> -<h1>Apps Repository</h1> +<h1><?php echo $l->t( 'Apps Repository' ); ?></h1> <table cellspacing="0"> <thead> <tr> <th></th> - <th>Name</th> - <th>Modified</th> + <th><?php echo $l->t( 'Name' ); ?></th> + <th><?php echo $l->t( 'Modified' ); ?></th> </tr> </thead> <tbody> @@ -19,7 +19,7 @@ <tr> <td width="1"><?php if($app["preview"] <> "") { echo('<a href="'.OC_HELPER::linkTo( "admin", "apps.php" ).'?id='.$app['id'].'"><img class="preview" border="0" src="'.$app["preview"].'" /></a>'); } ?> </a></td> <td class="name"><a href="<?php echo(OC_HELPER::linkTo( "admin", "apps.php" ).'?id='.$app['id']); ?>" title=""><?php echo $app["name"]; ?></a><br /><?php echo('<span class="type">'.$app['typename'].'</span>'); ?></td> - <td class="date"><?php echo OC_UTIL::formatdate($app["changed"]); ?></td> + <td class="date"><?php echo $l->l('datetime', $app["changed"]); ?></td> </tr> <?php endforeach; ?> </tbody> diff --git a/admin/templates/appsinst.php b/admin/templates/appsinst.php new file mode 100644 index 00000000000..0e97df6add8 --- /dev/null +++ b/admin/templates/appsinst.php @@ -0,0 +1,27 @@ +<?php +/* + * Template for Installed Apps + */ +?> +<h1><?php echo $l->t( 'Installed Applications' ); ?></h1> + +<table> + <thead> + <tr> + <th><?php echo $l->t( 'Name' ); ?></th> + <th><?php echo $l->t( 'Version' ); ?></th> + <th><?php echo $l->t( 'Author' ); ?></th> + <th><?php echo $l->t( 'Status' ); ?></th> + </tr> + </thead> + <tbody> + <?php foreach($_["apps"] as $app): ?> + <tr x-uid="<?php echo($app['id']); ?>"> + <td class="name" width="200"><?php echo($app['name']); ?></td> + <td class="version"><?php echo($app['version']); ?></td> + <td><?php echo($app['author']); ?></td> + <td><input x-use="appenablebutton" type='button' value='<?php echo $l->t( $app['enabled'] ? 'enabled' : 'disabled' ); ?>' class='appbutton prettybutton <?php echo( $app['enabled'] ? 'enabled' : 'disabled' ); ?>'/></td> + </tr> + <?php endforeach; ?> + </tbody> +</table>
\ No newline at end of file diff --git a/admin/templates/plugins.php b/admin/templates/plugins.php deleted file mode 100644 index 8f5e87d3e80..00000000000 --- a/admin/templates/plugins.php +++ /dev/null @@ -1,28 +0,0 @@ -<?php -/* - * Template for admin pages - */ -?> -<h1>Administration</h1> -<h2>Plugins</h2> - -<table> - <thead> - <tr> - <th>Name</th> - <th>Description</th> - <th>Version</th> - <th>Author</th> - <th></th> - </tr> - </thead> - <tbody> - <?php foreach($_["plugins"] as $plugin): ?> - <td><?php echo $plugin["info"]["id"]; ?></td> - <td><?php echo $plugin["info"]["version"]; ?></td> - <td><?php echo $plugin["info"]["name"]; ?></td> - <td><?php echo $plugin["info"]["author"]; ?></td> - <td>enable</td> - <?php endforeach; ?> - </tbody> -</table> diff --git a/admin/templates/system.php b/admin/templates/system.php index 4087b40a483..92ff9c836a8 100644 --- a/admin/templates/system.php +++ b/admin/templates/system.php @@ -3,6 +3,6 @@ * Template for admin pages */ ?> -<h1>Administration</h1> -<h2>System Settings</h2> +<h1><?php echo $l->t( 'Administration' ); ?></h1> +<h2><?php echo $l->t( 'System Settings' ); ?></h2> #TBD
\ No newline at end of file diff --git a/admin/templates/users.php b/admin/templates/users.php index 235df5bf829..133028c4e27 100644 --- a/admin/templates/users.php +++ b/admin/templates/users.php @@ -1,33 +1,33 @@ -<h2>Users</h2> +<h2><?php echo $l->t( 'Users' ); ?></h2> <table id="usertable"> <thead> <tr> - <th>Name</th> - <th>Groups</th> + <th><?php echo $l->t( 'Name' ); ?></th> + <th><?php echo $l->t( 'Groups' ); ?></th> <th></th> </tr> </thead> <tfoot> <tr id="createuseroption"> - <td><button id="createuseroptionbutton">Add user</button></td> + <td><button id="createuseroptionbutton"><?php echo $l->t( 'Add user' ); ?></button></td> <td> </td> <td> </td> </tr> <form id="createuserdata"> <tr id="createuserform" style="display:none;"> <td> - Name <input x-use="createuserfield" type="text" name="username" /><br> - Password <input x-use="createuserfield" type="password" name="password" /> + <?php echo $l->t( 'Name' ); ?> <input x-use="createuserfield" type="text" name="username" /><br> + <?php echo $l->t( 'Password' ); ?> <input x-use="createuserfield" type="password" name="password" /> </td> <td id="createusergroups"> <?php foreach($_["groups"] as $i): ?> - <input x-use="createusercheckbox" x-gid="<? echo $i["name"]; ?>" type="checkbox" name="groups[]" value="<? echo $i["name"]; ?>" /> - <span x-gid="<? echo $i["name"]; ?>"><? echo $i["name"]; ?><br></span> + <input x-use="createusercheckbox" x-gid="<?php echo $i["name"]; ?>" type="checkbox" name="groups[]" value="<?php echo $i["name"]; ?>" /> + <span x-gid="<?php echo $i["name"]; ?>"><?php echo $i["name"]; ?><br></span> <?php endforeach; ?> </td> <td> - <button id="createuserbutton">Create user</button> + <button id="createuserbutton"><?php echo $l->t( 'Create user' ); ?></button> </td> </tr> </form> @@ -37,17 +37,17 @@ <tr x-uid="<?php echo $user["name"] ?>"> <td x-use="username"><div x-use="usernamediv"><?php echo $user["name"]; ?></div></td> <td x-use="usergroups"><div x-use="usergroupsdiv"><?php if( $user["groups"] ){ echo $user["groups"]; }else{echo " ";} ?></div></td> - <td><a class="removeuserbutton" href="">remove</a></td> + <td><a class="removeuserbutton" href=""><?php echo $l->t( 'remove' ); ?></a></td> </tr> <?php endforeach; ?> </tbody> </table> -<h2>Groups</h2> +<h2><?php echo $l->t( 'Groups' ); ?></h2> <table id="grouptable"> <thead> <tr> - <th>Name</th> + <th><?php echo $l->t( 'Name' ); ?></th> <th></th> </tr> </thead> @@ -55,7 +55,7 @@ <form id="creategroupdata"> <tr> <td><input x-use="creategroupfield" type="text" name="groupname" /></td> - <td><button id="creategroupbutton">Create group</button></td> + <td><button id="creategroupbutton"><?php echo $l->t( 'Create group' ); ?></button></td> </tr> </form> </tfoot> @@ -65,7 +65,7 @@ <td><?php echo $group["name"] ?></td> <td> <?php if( $group["name"] != "admin" ): ?> - <a class="removegroupbutton" href="">remove</a> + <a class="removegroupbutton" href=""><?php echo $l->t( 'remove' ); ?></a> <?php else: ?> <?php endif; ?> @@ -82,8 +82,8 @@ <input id="changegroupuid" type="hidden" name="username" value="" /> <input id="changegroupgid" type="hidden" name="group" value="" /> <?php foreach($_["groups"] as $i): ?> - <input x-use="togglegroup" x-gid="<? echo $i["name"]; ?>" type="checkbox" name="groups[]" value="<? echo $i["name"]; ?>" /> - <span x-use="togglegroup" x-gid="<? echo $i["name"]; ?>"><? echo $i["name"]; ?><br></span> + <input x-use="togglegroup" x-gid="<?php echo $i["name"]; ?>" type="checkbox" name="groups[]" value="<?php echo $i["name"]; ?>" /> + <span x-use="togglegroup" x-gid="<?php echo $i["name"]; ?>"><?php echo $i["name"]; ?><br></span> <?php endforeach; ?> </form> </div> @@ -91,22 +91,22 @@ <div id="changepassword" style="display:none"> <form id="changepasswordform"> <input id="changepassworduid" type="hidden" name="username" value="" /> - Force new password: + <?php echo $l->t( 'Force new password:' ); ?> <input id="changepasswordpwd" type="password" name="password" value="" /> - <button id="changepasswordbutton">Set</button> + <button id="changepasswordbutton"><?php echo $l->t( 'Set' ); ?></button> </form> </div> <div id="removeuserform" title="Remove user"> <form id="removeuserdata"> - Do you really want to delete user <span id="deleteuserusername">$user</span>? + <?php echo $l->t( 'Do you really want to delete user' ); ?> <span id="deleteuserusername">$user</span>? <input id="deleteusernamefield" type="hidden" name="username" value=""> </form> </div> <div id="removegroupform" title="Remove Group"> <form id="removegroupdata"> - Do you really want to delete group <span id="removegroupgroupname">$group</span>? + <?php echo $l->t( 'Do you really want to delete group' ); ?> <span id="removegroupgroupname">$group</span>? <input id="removegroupnamefield" type="hidden" name="groupname" value=""> </form> </div> diff --git a/admin/users.php b/admin/users.php index e44feb40fe2..0848d57162a 100644 --- a/admin/users.php +++ b/admin/users.php @@ -23,7 +23,7 @@ require_once('../lib/base.php'); require( 'template.php' ); -if( !OC_USER::isLoggedIn() || !OC_GROUP::inGroup( $_SESSION['user_id'], 'admin' )){ +if( !OC_USER::isLoggedIn() || !OC_GROUP::inGroup( OC_USER::getUser(), 'admin' )){ header( "Location: ".OC_HELPER::linkTo( "index.php" )); exit(); } diff --git a/apps/files_publiclink/admin.php b/apps/files_publiclink/admin.php index a48076b4d42..afb726da312 100644 --- a/apps/files_publiclink/admin.php +++ b/apps/files_publiclink/admin.php @@ -29,7 +29,7 @@ require( 'template.php' ); // Check if we are a user -if( !OC_USER::isLoggedIn() || !OC_GROUP::inGroup( $_SESSION['user_id'], 'admin' )){ +if( !OC_USER::isLoggedIn()){ header( "Location: ".OC_HELPER::linkTo( "index.php" )); exit(); } diff --git a/apps/files_publiclink/appinfo/database.xml b/apps/files_publiclink/appinfo/database.xml index de63b03f445..4fe6be47d8d 100644 --- a/apps/files_publiclink/appinfo/database.xml +++ b/apps/files_publiclink/appinfo/database.xml @@ -35,7 +35,7 @@ <notnull>true</notnull> </field> <index> - <name>token</name> + <name>a_files_publiclink_token</name> <unique>true</unique> <field> <name>token</name> diff --git a/apps/files_publiclink/js/admin.js b/apps/files_publiclink/js/admin.js index 017c62cb42a..21857718149 100644 --- a/apps/files_publiclink/js/admin.js +++ b/apps/files_publiclink/js/admin.js @@ -8,7 +8,7 @@ $(document).ready(function() { source: "../../files/ajax/autocomplete.php", minLength: 1 }); - $("button.delete").live('click', function() { + $("button.delete").live('click', function( event ) { event.preventDefault(); var token=$(this).attr('data-token'); var data="token="+token; @@ -22,7 +22,7 @@ $(document).ready(function() { } }); }); - $('#newlink').submit(function(){ + $('#newlink').submit(function( event ){ event.preventDefault(); var path=$('#path').val(); var expire=$('#expire_time').val()||0; @@ -48,5 +48,5 @@ $(document).ready(function() { } } }); - }) + }); });
\ No newline at end of file diff --git a/apps/files_publiclink/lib_public.php b/apps/files_publiclink/lib_public.php index aeef9212377..93ccc52d0e9 100644 --- a/apps/files_publiclink/lib_public.php +++ b/apps/files_publiclink/lib_public.php @@ -7,7 +7,7 @@ class OC_PublicLink{ */ public function __construct($path,$expiretime=0){ if($path and OC_FILESYSTEM::file_exists($path) and OC_FILESYSTEM::is_readable($path)){ - $user=$_SESSION['user_id']; + $user=OC_USER::getUser(); $token=sha1("$user-$path-$expiretime"); $query=OC_DB::prepare("INSERT INTO *PREFIX*publiclink VALUES(?,?,?,?)"); $result=$query->execute(array($token,$path,$user,$expiretime)); @@ -60,7 +60,7 @@ class OC_PublicLink{ */ static public function getLinks(){ $query=OC_DB::prepare("SELECT * FROM *PREFIX*publiclink WHERE user=?"); - return $query->execute(array($_SESSION['user_id']))->fetchAll(); + return $query->execute(array(OC_USER::getUser()))->fetchAll(); } /** @@ -69,7 +69,7 @@ class OC_PublicLink{ static public function delete($token){ $query=OC_DB::prepare("SELECT user,path FROM *PREFIX*publiclink WHERE token=?"); $result=$query->execute(array($token))->fetchAll(); - if(count($result)>0 and $result[0]['user']==$_SESSION['user_id']){ + if(count($result)>0 and $result[0]['user']==OC_USER::getUser()){ $query=OC_DB::prepare("DELETE FROM *PREFIX*publiclink WHERE token=?"); $query->execute(array($token)); } diff --git a/apps/files_publiclink/templates/admin.php b/apps/files_publiclink/templates/admin.php index 2483eef321a..95b99109f23 100644 --- a/apps/files_publiclink/templates/admin.php +++ b/apps/files_publiclink/templates/admin.php @@ -2,18 +2,18 @@ <table id='linklist'> <thead> <tr> - <td class='path'>Path</td> - <td class='expire'>Expires</td> - <td class='link'>Link</td> + <td class='path'><?php echo $l->t( 'Path' ); ?></td> + <td class='expire'><?php echo $l->t( 'Expires' ); ?></td> + <td class='link'><?php echo $l->t( 'Link' ); ?></td> </tr> </thead> <tbody> <?php foreach($_['links'] as $link):?> <tr class='link' id='<?php echo $link['token'];?>'> <td class='path'><?php echo $link['path'];?></td> - <td class='expire'><?php echo ($link['expire_time']==0)?'Never':OC_UTIL::formatdate($link['expire_time'],true);?></td> + <td class='expire'><?php echo ($link['expire_time']==0)?'Never':$l->l('datetime', $link['expire_time']);?></td> <td class='link'><a href='get.php?token=<?php echo $link['token'];?>'><?php echo $_['baseUrl'];?>?token=<?php echo $link['token'];?></a></td> - <td><button class='delete fancybutton' data-token='<?php echo $link['token'];?>'>Delete</button></td> + <td><button class='delete fancybutton' data-token='<?php echo $link['token'];?>'><?php echo $l->t( 'Delete' ); ?></button></td> </tr> <?php endforeach;?> <tr id='newlink_row'> diff --git a/apps/files_publiclink/templates/index.php b/apps/files_publiclink/templates/index.php index 9e238452603..759f3ad8772 100644 --- a/apps/files_publiclink/templates/index.php +++ b/apps/files_publiclink/templates/index.php @@ -5,9 +5,9 @@ <thead> <tr> <th><input type="checkbox" id="select_all" /></th> - <th>Name</th> - <th>Size</th> - <th>Modified</th> + <th><?php echo $l->t( 'Name' ); ?></th> + <th><?php echo $l->t( 'Size' ); ?></th> + <th><?php echo $l->t( 'Modified' ); ?></th> <th></th> </tr> </thead> diff --git a/apps/user_ldap/appinfo/app.php b/apps/user_ldap/appinfo/app.php new file mode 100644 index 00000000000..67b61989f7f --- /dev/null +++ b/apps/user_ldap/appinfo/app.php @@ -0,0 +1,39 @@ +<?php + +/** +* ownCloud - user_ldap +* +* @author Dominik Schmidt +* @copyright 2011 Dominik Schmidt dev@dominik-schmidt.de +* +* 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/>. +* +*/ + +require_once('apps/user_ldap/user_ldap.php'); + +// define LDAP_DEFAULT_PORT +define("OC_USER_BACKEND_LDAP_DEFAULT_PORT", 389); + +// register user backend +OC_USER::useBackend( "LDAP" ); + +// add settings page to navigation +$entry = array( + 'id' => "user_ldap_settings", + 'order'=>1, + 'href' => OC_HELPER::linkTo( "user_ldap", "settings.php" ), + 'name' => 'LDAP' +); +OC_APP::addNavigationSubEntry( "core_users", $entry); diff --git a/apps/user_ldap/appinfo/info.xml b/apps/user_ldap/appinfo/info.xml new file mode 100644 index 00000000000..9a6ee1436fc --- /dev/null +++ b/apps/user_ldap/appinfo/info.xml @@ -0,0 +1,10 @@ +<?xml version="1.0"?> +<info> + <id>user_ldap</id> + <name>LDAP user backend</name> + <description>Authenticate Users by LDAP</description> + <version>0.1</version> + <licence>AGPL</licence> + <author>Dominik Schmidt</author> + <require>2</require> +</info> diff --git a/apps/user_ldap/settings.php b/apps/user_ldap/settings.php new file mode 100644 index 00000000000..f7aff1b4614 --- /dev/null +++ b/apps/user_ldap/settings.php @@ -0,0 +1,52 @@ +<?php + +/** + * ownCloud - user_ldap + * + * @author Dominik Schmidt + * @copyright 2011 Dominik Schmidt dev@dominik-schmidt.de + * + * 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/>. + * + */ + +require_once('../../lib/base.php'); +require( 'template.php' ); + +if( !OC_USER::isLoggedIn() || !OC_GROUP::inGroup( OC_USER::getUser(), 'admin' )){ + header( "Location: ".OC_HELPER::linkTo( "index.php" )); + exit(); +} + +$params = array('ldap_host', 'ldap_port', 'ldap_dn', 'ldap_password', 'ldap_base', 'ldap_filter'); + +foreach($params as $param){ + if(isset($_POST[$param])){ + OC_APPCONFIG::setValue('user_ldap', $param, $_POST[$param]); + } +} +OC_APP::setActiveNavigationEntry( "user_ldap_settings" ); + + +// fill template +$tmpl = new OC_TEMPLATE( 'user_ldap', 'settings', 'admin' ); +foreach($params as $param){ + $value = OC_APPCONFIG::getValue('user_ldap', $param,''); + $tmpl->assign($param, $value); +} + +// ldap_port has a default value +$tmpl->assign( 'ldap_port', OC_APPCONFIG::getValue('user_ldap', 'ldap_port', OC_USER_BACKEND_LDAP_DEFAULT_PORT)); + +$tmpl->printPage(); diff --git a/apps/user_ldap/templates/settings.php b/apps/user_ldap/templates/settings.php new file mode 100644 index 00000000000..5dddb71a022 --- /dev/null +++ b/apps/user_ldap/templates/settings.php @@ -0,0 +1,27 @@ +<form id="ldap" action='#' method='post'> + <fieldset> + <legend>LDAP</legend> + <div> + <div> + <span>Host: *</span><span><input type="text" name="ldap_host" width="200" value="<?php echo $_['ldap_host']; ?>"></span> + </div> + <div> + <span>Port: *</span><span><input type="text" name="ldap_port" width="200" value="<?php echo $_['ldap_port']; ?>"></span> + </div> + <div> + <span>DN:<input type="text" name="ldap_dn" width="200" value="<?php echo $_['ldap_dn']; ?>"></span> + </div> + <div> + <span>Password:<input type="password" name="ldap_password" width="200" value="<?php echo $_['ldap_password']; ?>"></span> + </div> + <div> + <span>Base: *<input type="text" name="ldap_base" width="200" value="<?php echo $_['ldap_base']; ?>"></span> + </div> + <div> + <span>Filter * (use %uid placeholder):<input type="text" name="ldap_filter" width="200" value="<?php echo $_['ldap_filter']; ?>"></span> + </div> + </div> + <input type='submit' value='Save'/> + <br/> * required + </fieldset> +</form>
\ No newline at end of file diff --git a/apps/user_ldap/user_ldap.php b/apps/user_ldap/user_ldap.php new file mode 100644 index 00000000000..d6ed8c741e7 --- /dev/null +++ b/apps/user_ldap/user_ldap.php @@ -0,0 +1,114 @@ +<?php + +/** + * ownCloud + * + * @author Dominik Schmidt + * @copyright 2011 Dominik Schmidt dev@dominik-schmidt.de + * + * 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/>. + * + */ + +require_once('User/backend.php'); + +class OC_USER_LDAP extends OC_USER_BACKEND { + + protected $ds; + protected $configured = false; + + // cached settings + protected $ldap_host; + protected $ldap_port; + protected $ldap_dn; + protected $ldap_password; + protected $ldap_base; + protected $ldap_filter; + + function __construct() { + $this->ldap_host = OC_APPCONFIG::getValue('user_ldap', 'ldap_host',''); + $this->ldap_port = OC_APPCONFIG::getValue('user_ldap', 'ldap_port', OC_USER_BACKEND_LDAP_DEFAULT_PORT ); + $this->ldap_dn = OC_APPCONFIG::getValue('user_ldap', 'ldap_dn',''); + $this->ldap_password = OC_APPCONFIG::getValue('user_ldap', 'ldap_password',''); + $this->ldap_base = OC_APPCONFIG::getValue('user_ldap', 'ldap_base',''); + $this->ldap_filter = OC_APPCONFIG::getValue('user_ldap', 'ldap_filter',''); + + if( !empty($this->ldap_host) + && !empty($this->ldap_port) + && !empty($this->ldap_dn) + && !empty($this->ldap_password) + && !empty($this->ldap_base) + && !empty($this->ldap_filter) + ) + { + $this->configured = true; + } + } + + function __destruct() { + // close the connection + if( $this->ds ) + ldap_unbind($this->ds); + } + + private function getDs() { + if(!$this->ds) { + $this->ds = ldap_connect( $this->ldap_host, $this->ldap_port ); + } + + // login + if(!empty($this->ldap_dn)) { + $ldap_login = @ldap_bind( $this->ds, $this->ldap_dn, $this->ldap_password ); + if(!$ldap_login) + return false; + } + + return $this->ds; + } + + private function getDn( $uid ) { + if(!$this->configured) + return false; + + // connect to server + $ds = $this->getDs(); + if( !$ds ) + return false; + + // get dn + $filter = str_replace("%uid", $uid, $this->ldap_filter); + $sr = ldap_search( $this->getDs(), $this->ldap_base, $filter ); + $entries = ldap_get_entries( $this->getDs(), $sr ); + + if( $entries["count"] == 0 ) + return false; + + return $entries[0]["dn"]; + } + public function checkPassword( $uid, $password ) { + $dn = $this->getDn( $uid ); + if( !$dn ) + return false; + + return @ldap_bind( $this->getDs(), $dn, $password ); + } + + public function userExists( $uid ) { + $dn = $this->getDn($uid); + return !empty($dn); + } + +} + +?> diff --git a/apps/user_openid/appinfo/app.php b/apps/user_openid/appinfo/app.php new file mode 100644 index 00000000000..d6eacfc0a3a --- /dev/null +++ b/apps/user_openid/appinfo/app.php @@ -0,0 +1,47 @@ +<?php + +//check if curl extension installed +if (!in_array ('curl', get_loaded_extensions())){ + return; +} + +$urlBase=((isset($_SERVER["HTTPS"]) && $_SERVER["HTTPS"] == 'on') ? 'https' : 'http').'://'.$_SERVER['HTTP_HOST']; +OC_UTIL::addHeader('link',array('rel'=>'openid.server', 'href'=>$urlBase.OC_HELPER::linkTo( "user_openid", "user.php" ).'/')); +OC_UTIL::addHeader('link',array('rel'=>'openid.delegate', 'href'=>$urlBase.OC_HELPER::linkTo( "user_openid", "user.php" ).'/')); + +require_once 'apps/user_openid/user_openid.php'; + +OC_APP::addSettingsPage( array( "id" => "user_openid_settings", 'order'=>1, "href" => OC_HELPER::linkTo( "user_openid", "settings.php" ), "name" => "OpenID")); + +//active the openid backend +OC_USER::useBackend('openid'); + +//check for results from openid requests +if(isset($_GET['openid_mode']) and $_GET['openid_mode'] == 'id_res'){ + error_log('openid retured'); + $openid = new SimpleOpenID; + $openid->SetIdentity($_GET['openid_identity']); + $openid_validation_result = $openid->ValidateWithServer(); + if ($openid_validation_result == true){ // OK HERE KEY IS VALID + error_log('auth sucessfull'); + global $WEBROOT; + $identity=$openid->GetIdentity(); + error_log("auth as $identity"); + $user=OC_USER_OPENID::findUserForIdentity($identity); + if($user){ + $_SESSION['user_id']=$user; + header("Location: $WEBROOT"); + } + }else if($openid->IsError() == true){ // ON THE WAY, WE GOT SOME ERROR + $error = $openid->GetError(); + error_log("ERROR CODE: " . $error['code']); + error_log("ERROR DESCRIPTION: " . $error['description']); + }else{ // Signature Verification Failed + error_log("INVALID AUTHORIZATION"); + } +}else if (isset($_GET['openid_mode']) and $_GET['openid_mode'] == 'cancel'){ // User Canceled your Request + error_log("USER CANCELED REQUEST"); + return false; +} + +?> diff --git a/apps/user_openid/appinfo/info.xml b/apps/user_openid/appinfo/info.xml new file mode 100644 index 00000000000..32525009d61 --- /dev/null +++ b/apps/user_openid/appinfo/info.xml @@ -0,0 +1,10 @@ +<?xml version="1.0"?> +<info> + <id>user_openid</id> + <name>OpenID user backend</name> + <description>Allow login through OpenID</description> + <version>0.1</version> + <licence>AGPL</licence> + <author>Robin Appelman</author> + <require>2</require> +</info>
\ No newline at end of file diff --git a/apps/user_openid/class.openid.v3.php b/apps/user_openid/class.openid.v3.php new file mode 100644 index 00000000000..8afb9e5b817 --- /dev/null +++ b/apps/user_openid/class.openid.v3.php @@ -0,0 +1,328 @@ +<?php +/* + FREE TO USE + Under License: GPLv3 + Simple OpenID PHP Class + + Some modifications by Eddie Roosenmaallen, eddie@roosenmaallen.com + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +This Class was written to make easy for you to integrate OpenID on your website. +This is just a client, which checks for user's identity. This Class Requires CURL Module. +It should be easy to use some other HTTP Request Method, but remember, often OpenID servers +are using SSL. +We need to be able to perform SSL Verification on the background to check for valid signature. + +HOW TO USE THIS CLASS: + STEP 1) + $openid = new SimpleOpenID; + :: SET IDENTITY :: + $openid->SetIdentity($_POST['openid_url']); + :: SET RETURN URL :: + $openid->SetApprovedURL('http://www.yoursite.com/return.php'); // Script which handles a response from OpenID Server + :: SET TRUST ROOT :: + $openid->SetTrustRoot('http://www.yoursite.com/'); + :: FETCH SERVER URL FROM IDENTITY PAGE :: [Note: It is recomended to cache this (Session, Cookie, Database)] + $openid->GetOpenIDServer(); // Returns false if server is not found + :: REDIRECT USER TO OPEN ID SERVER FOR APPROVAL :: + + :: (OPTIONAL) SET OPENID SERVER :: + $openid->SetOpenIDServer($server_url); // If you have cached previously this, you don't have to call GetOpenIDServer and set value this directly + + STEP 2) + Once user gets returned we must validate signature + :: VALIDATE REQUEST :: + true|false = $openid->ValidateWithServer(); + + ERRORS: + array = $openid->GetError(); // Get latest Error code + + FIELDS: + OpenID allowes you to retreive a profile. To set what fields you'd like to get use (accepts either string or array): + $openid->SetRequiredFields(array('email','fullname','dob','gender','postcode','country','language','timezone')); + or + $openid->SetOptionalFields('postcode'); + +IMPORTANT TIPS: +OPENID as is now, is not trust system. It is a great single-sign on method. If you want to +store information about OpenID in your database for later use, make sure you handle url identities +properly. + For example: + https://steve.myopenid.com/ + https://steve.myopenid.com + http://steve.myopenid.com/ + http://steve.myopenid.com + ... are representing one single user. Some OpenIDs can be in format openidserver.com/users/user/ - keep this in mind when storing identities + + To help you store an OpenID in your DB, you can use function: + $openid_db_safe = $openid->OpenID_Standarize($upenid); + This may not be comatible with current specs, but it works in current enviroment. Use this function to get openid + in one format like steve.myopenid.com (without trailing slashes and http/https). + Use output to insert Identity to database. Don't use this for validation - it may fail. + +*/ + +class SimpleOpenID{ + var $openid_url_identity; + var $URLs = array(); + var $error = array(); + var $fields = array( + 'required' => array(), + 'optional' => array(), + ); + + function SimpleOpenID(){ + if (!function_exists('curl_exec')) { + die('Error: Class SimpleOpenID requires curl extension to work'); + } + } + function SetOpenIDServer($a){ + $this->URLs['openid_server'] = $a; + } + function SetTrustRoot($a){ + $this->URLs['trust_root'] = $a; + } + function SetCancelURL($a){ + $this->URLs['cancel'] = $a; + } + function SetApprovedURL($a){ + $this->URLs['approved'] = $a; + } + function SetRequiredFields($a){ + if (is_array($a)){ + $this->fields['required'] = $a; + }else{ + $this->fields['required'][] = $a; + } + } + function SetOptionalFields($a){ + if (is_array($a)){ + $this->fields['optional'] = $a; + }else{ + $this->fields['optional'][] = $a; + } + } + function SetIdentity($a){ // Set Identity URL + if ((stripos($a, 'http://') === false) + && (stripos($a, 'https://') === false)){ + $a = 'http://'.$a; + } +/* + $u = parse_url(trim($a)); + if (!isset($u['path'])){ + $u['path'] = '/'; + }else if(substr($u['path'],-1,1) == '/'){ + $u['path'] = substr($u['path'], 0, strlen($u['path'])-1); + } + if (isset($u['query'])){ // If there is a query string, then use identity as is + $identity = $a; + }else{ + $identity = $u['scheme'] . '://' . $u['host'] . $u['path']; + } +//*/ + $this->openid_url_identity = $a; + } + function GetIdentity(){ // Get Identity + return $this->openid_url_identity; + } + function GetError(){ + $e = $this->error; + return array('code'=>$e[0],'description'=>$e[1]); + } + + function ErrorStore($code, $desc = null){ + $errs['OPENID_NOSERVERSFOUND'] = 'Cannot find OpenID Server TAG on Identity page.'; + if ($desc == null){ + $desc = $errs[$code]; + } + $this->error = array($code,$desc); + } + + function IsError(){ + if (count($this->error) > 0){ + return true; + }else{ + return false; + } + } + + function splitResponse($response) { + $r = array(); + $response = explode("\n", $response); + foreach($response as $line) { + $line = trim($line); + if ($line != "") { + list($key, $value) = explode(":", $line, 2); + $r[trim($key)] = trim($value); + } + } + return $r; + } + + function OpenID_Standarize($openid_identity = null){ + if ($openid_identity === null) + $openid_identity = $this->openid_url_identity; + + $u = parse_url(strtolower(trim($openid_identity))); + + if (!isset($u['path']) || ($u['path'] == '/')) { + $u['path'] = ''; + } + if(substr($u['path'],-1,1) == '/'){ + $u['path'] = substr($u['path'], 0, strlen($u['path'])-1); + } + if (isset($u['query'])){ // If there is a query string, then use identity as is + return $u['host'] . $u['path'] . '?' . $u['query']; + }else{ + return $u['host'] . $u['path']; + } + } + + function array2url($arr){ // converts associated array to URL Query String + if (!is_array($arr)){ + return false; + } + $query = ''; + foreach($arr as $key => $value){ + $query .= $key . "=" . $value . "&"; + } + return $query; + } + function FSOCK_Request($url, $method="GET", $params = ""){ + $fp = fsockopen("ssl://www.myopenid.com", 443, $errno, $errstr, 3); // Connection timeout is 3 seconds + if (!$fp) { + $this->ErrorStore('OPENID_SOCKETERROR', $errstr); + return false; + } else { + $request = $method . " /server HTTP/1.0\r\n"; + $request .= "User-Agent: Simple OpenID PHP Class (http://www.phpclasses.org/simple_openid)\r\n"; + $request .= "Connection: close\r\n\r\n"; + fwrite($fp, $request); + stream_set_timeout($fp, 4); // Connection response timeout is 4 seconds + $res = fread($fp, 2000); + $info = stream_get_meta_data($fp); + fclose($fp); + + if ($info['timed_out']) { + $this->ErrorStore('OPENID_SOCKETTIMEOUT'); + } else { + return $res; + } + } + } + function CURL_Request($url, $method="GET", $params = "") { // Remember, SSL MUST BE SUPPORTED + if (is_array($params)) $params = $this->array2url($params); + $curl = curl_init($url . ($method == "GET" && $params != "" ? "?" . $params : "")); + curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true); + curl_setopt($curl, CURLOPT_HEADER, false); + curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); + curl_setopt($curl, CURLOPT_HTTPGET, ($method == "GET")); + curl_setopt($curl, CURLOPT_POST, ($method == "POST")); + if ($method == "POST") curl_setopt($curl, CURLOPT_POSTFIELDS, $params); + curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); + $response = curl_exec($curl); + + if (curl_errno($curl) == 0){ + $response; + }else{ + $this->ErrorStore('OPENID_CURL', curl_error($curl)); + } + return $response; + } + + function HTML2OpenIDServer($content) { + $get = array(); + + // Get details of their OpenID server and (optional) delegate + preg_match_all('/<link[^>]*rel=[\'"](openid2.provider )?openid.server[\'"][^>]*href=[\'"]([^\'"]+)[\'"][^>]*\/?>/i', $content, $matches1); + preg_match_all('/<link[^>]*href=\'"([^\'"]+)[\'"][^>]*rel=[\'"](openid2.provider )?openid.server[\'"][^>]*\/?>/i', $content, $matches2); + $servers = array_merge($matches1[2], $matches2[1]); + + preg_match_all('/<link[^>]*rel=[\'"]openid.delegate[\'"][^>]*href=[\'"]([^\'"]+)[\'"][^>]*\/?>/i', $content, $matches1); + + preg_match_all('/<link[^>]*href=[\'"]([^\'"]+)[\'"][^>]*rel=[\'"]openid.delegate[\'"][^>]*\/?>/i', $content, $matches2); + + $delegates = array_merge($matches1[1], $matches2[1]); + + $ret = array($servers, $delegates); + return $ret; + } + + function GetOpenIDServer(){ + $response = $this->CURL_Request($this->openid_url_identity); + list($servers, $delegates) = $this->HTML2OpenIDServer($response); + if (count($servers) == 0){ + $this->ErrorStore('OPENID_NOSERVERSFOUND'); + return false; + } + if (isset($delegates[0]) + && ($delegates[0] != "")){ + $this->SetIdentity($delegates[0]); + } + $this->SetOpenIDServer($servers[0]); + return $servers[0]; + } + + function GetRedirectURL(){ + $params = array(); + $params['openid.return_to'] = urlencode($this->URLs['approved']); + $params['openid.mode'] = 'checkid_setup'; + $params['openid.identity'] = urlencode($this->openid_url_identity); + $params['openid.trust_root'] = urlencode($this->URLs['trust_root']); + + if (isset($this->fields['required']) + && (count($this->fields['required']) > 0)) { + $params['openid.sreg.required'] = implode(',',$this->fields['required']); + } + if (isset($this->fields['optional']) + && (count($this->fields['optional']) > 0)) { + $params['openid.sreg.optional'] = implode(',',$this->fields['optional']); + } + return $this->URLs['openid_server'] . "?". $this->array2url($params); + } + + function Redirect(){ + $redirect_to = $this->GetRedirectURL(); + if (headers_sent()){ // Use JavaScript to redirect if content has been previously sent (not recommended, but safe) + echo '<script language="JavaScript" type="text/javascript">window.location=\''; + echo $redirect_to; + echo '\';</script>'; + }else{ // Default Header Redirect + header('Location: ' . $redirect_to); + } + } + + function ValidateWithServer(){ + $params = array( + 'openid.assoc_handle' => urlencode($_GET['openid_assoc_handle']), + 'openid.signed' => urlencode($_GET['openid_signed']), + 'openid.sig' => urlencode($_GET['openid_sig']) + ); + // Send only required parameters to confirm validity + $arr_signed = explode(",",str_replace('sreg.','sreg_',$_GET['openid_signed'])); + for ($i=0; $i<count($arr_signed); $i++){ + $s = str_replace('sreg_','sreg.', $arr_signed[$i]); + $c = $_GET['openid_' . $arr_signed[$i]]; + // if ($c != ""){ + $params['openid.' . $s] = urlencode($c); + // } + } + $params['openid.mode'] = "check_authentication"; + + $openid_server = $this->GetOpenIDServer(); + if ($openid_server == false){ + return false; + } + $response = $this->CURL_Request($openid_server,'POST',$params); + $data = $this->splitResponse($response); + + if ($data['is_valid'] == "true") { + return true; + }else{ + return false; + } + } +} + +?>
\ No newline at end of file diff --git a/apps/user_openid/phpmyid.php b/apps/user_openid/phpmyid.php new file mode 100644 index 00000000000..7991b87c6d8 --- /dev/null +++ b/apps/user_openid/phpmyid.php @@ -0,0 +1,1740 @@ +<?php +// PLEASE DO NOT EDIT THIS FILE UNLESS YOU KNOW WHAT YOU ARE DOING! + +/** + * phpMyID - A standalone, single user, OpenID Identity Provider + * + * @package phpMyID + * @author CJ Niemira <siege (at) siege (dot) org> + * @copyright 2006-2008 + * @license http://www.gnu.org/licenses/gpl.html GNU Public License + * @url http://siege.org/projects/phpMyID + * @version 0.9 + */ + +require( 'template.php' ); + + +/** + * Set a constant to indicate that phpMyID is running + */ +define('PHPMYID_STARTED', true); + +/** + * List the known types and modes + * @name $known + * @global array $GLOBALS['known'] + */ +$GLOBALS['known'] = array( + 'assoc_types' => array('HMAC-SHA1'), + + 'openid_modes' => array('accept', + 'associate', + 'authorize', + 'cancel', + 'checkid_immediate', + 'checkid_setup', + 'check_authentication', + 'error', + 'id_res', + 'login', + 'logout', + 'test'), + + 'session_types' => array('', + 'DH-SHA1'), + + 'bigmath_types' => array('DH-SHA1'), +); + +/** + * Defined by OpenID spec + * @name $g + * @global integer $GLOBALS['g'] + */ +$GLOBALS['g'] = 2; + +/** + * Defined by OpenID spec + * @name $p + * @global integer $GLOBALS['p'] + */ +$GLOBALS['p'] = '155172898181473697471232257763715539915724801966915404479707' . +'7953140576293785419175806512274236981889937278161526466314385615958256881888' . +'8995127215884267541995034125870655654980358010487053768147672651325574704076' . +'5857479291291572334510643245094715007229621094194349783925984760375594985848' . +'253359305585439638443'; + + +// Runmode functions + +/** + * Allow the user to accept trust on a URL + * @global array $profile + */ +function accept_mode () { + global $profile; + + // this is a user session + user_session(); + + // the user needs refresh urls in their session to access this mode + if (! isset($_SESSION['post_accept_url']) || ! isset($_SESSION['cancel_accept_url']) || ! isset($_SESSION['unaccepted_url'])) + error_500('You may not access this mode directly.'); + + // has the user accepted the trust_root? + $accepted = @strlen($_REQUEST['accepted']) + ? $_REQUEST['accepted'] + : null; + + // if so, refresh back to post_accept_url + if ($accepted === 'yes') { + $_SESSION['accepted_url'] = $_SESSION['unaccepted_url']; + wrap_redirect($_SESSION['post_accept_url']); + + // if they rejected it, return to the client + } elseif ($accepted === 'no') { + wrap_redirect($_SESSION['cancel_accept_url']); + } + + // if neither, offer the trust request + $q = strpos($profile['req_url'], '?') ? '&' : '?'; + $yes = $profile['req_url'] . $q . 'accepted=yes'; + $no = $profile['req_url'] . $q . 'accepted=no'; + + wrap_html('The client site you are attempting to log into has requested that you trust the following URL:<br/><b>' . $_SESSION['unaccepted_url'] . '</b><br/><br/>Do you wish to continue?<br/><a href="' . $yes . '">Yes</a> | <a href="' . $no . '">No</a>'); +} + +/** * Perform an association with a consumer + * @global array $known + * @global array $profile + * @global integer $g + * @global integer $p + */ +function associate_mode () { + global $g, $known, $p, $profile; + + // Validate the request + if (! isset($_REQUEST['openid_mode']) || $_REQUEST['openid_mode'] != 'associate') + error_400(); + + // Get the request options, using defaults as necessary + $assoc_type = (@strlen($_REQUEST['openid_assoc_type']) + && in_array($_REQUEST['openid_assoc_type'], $known['assoc_types'])) + ? $_REQUEST['openid_assoc_type'] + : 'HMAC-SHA1'; + + $session_type = (@strlen($_REQUEST['openid_session_type']) + && in_array($_REQUEST['openid_session_type'], $known['session_types'])) + ? $_REQUEST['openid_session_type'] + : ''; + + $dh_modulus = (@strlen($_REQUEST['openid_dh_modulus'])) + ? long(base64_decode($_REQUEST['openid_dh_modulus'])) + : ($session_type == 'DH-SHA1' + ? $p + : null); + + $dh_gen = (@strlen($_REQUEST['openid_dh_gen'])) + ? long(base64_decode($_REQUEST['openid_dh_gen'])) + : ($session_type == 'DH-SHA1' + ? $g + : null); + + $dh_consumer_public = (@strlen($_REQUEST['openid_dh_consumer_public'])) + ? $_REQUEST['openid_dh_consumer_public'] + : ($session_type == 'DH-SHA1' + ? error_post('dh_consumer_public was not specified') + : null); + + $lifetime = time() + $profile['lifetime']; + + // Create standard keys + $keys = array( + 'assoc_type' => $assoc_type, + 'expires_in' => $profile['lifetime'] + ); + + // If I can't handle bigmath, default to plaintext sessions + if (in_array($session_type, $known['bigmath_types']) && $profile['use_bigmath'] === false) + $session_type = null; + + // Add response keys based on the session type + switch ($session_type) { + case 'DH-SHA1': + // Create the associate id and shared secret now + list ($assoc_handle, $shared_secret) = new_assoc($lifetime); + + // Compute the Diffie-Hellman stuff + $private_key = random($dh_modulus); + $public_key = bmpowmod($dh_gen, $private_key, $dh_modulus); + $remote_key = long(base64_decode($dh_consumer_public)); + $ss = bmpowmod($remote_key, $private_key, $dh_modulus); + + $keys['assoc_handle'] = $assoc_handle; + $keys['session_type'] = $session_type; + $keys['dh_server_public'] = base64_encode(bin($public_key)); + $keys['enc_mac_key'] = base64_encode(x_or(sha1_20(bin($ss)), $shared_secret)); + + break; + + default: + // Create the associate id and shared secret now + list ($assoc_handle, $shared_secret) = new_assoc($lifetime); + + $keys['assoc_handle'] = $assoc_handle; + $keys['mac_key'] = base64_encode($shared_secret); + } + + // Return the keys + wrap_kv($keys); +} + + +/** + * Perform a user authorization + * @global array $profile + */ +function authorize_mode () { + global $profile; + global $USERNAME; + global $IDENTITY; + + // this is a user session + + // the user needs refresh urls in their session to access this mode + if (! isset($_SESSION['post_auth_url']) || ! isset($_SESSION['cancel_auth_url'])) + error_500('You may not access this mode directly.'); + + $profile['idp_url']=$IDENTITY; + if (isset($_SERVER['PHP_AUTH_USER']) && $profile['authorized'] === false && $_SERVER['PHP_AUTH_USER']==$USERNAME) { + if (OC_USER::checkPassword($USERNAME, $_SERVER['PHP_AUTH_PW'])) {// successful login! + error_log('success'); + // return to the refresh url if they get in + $_SESSION['openid_auth']=true; + $_SESSION['openid_user']=$USERNAME; + wrap_redirect($_SESSION['post_auth_url']); + + // failed login + } else { + $_SESSION['failures']++; + debug('Login failed'); + debug('Fail count: ' . $_SESSION['failures']); + } + + } + + // if we get this far the user is not authorized, so send the headers + $uid = uniqid(mt_rand(1,9)); + $_SESSION['uniqid'] = $uid; + +// debug('Prompting user to log in. Stale? ' . $stale); + header('HTTP/1.0 401 Unauthorized'); +// header(sprintf('WWW-Authenticate: Digest qop="auth-int, auth", realm="%s", domain="%s", nonce="%s", opaque="%s", stale="%s", algorithm="MD5"', $profile['auth_realm'], $profile['auth_domain'], $uid, md5($profile['auth_realm']), $stale ? 'true' : 'false')); + header('WWW-Authenticate: Basic realm="ownCloud"'); + $q = strpos($_SESSION['cancel_auth_url'], '?') ? '&' : '?'; + wrap_refresh($_SESSION['cancel_auth_url'] . $q . 'openid.mode=cancel'); +// die('401 Unauthorized'); +} + + +/** + * Handle a consumer's request for cancellation. + */ +function cancel_mode () { + wrap_html('Request cancelled.'); +} + + +/** + * Handle a consumer's request to see if the user is authenticated + */ +function check_authentication_mode () { + // Validate the request + if (! isset($_REQUEST['openid_mode']) || $_REQUEST['openid_mode'] != 'check_authentication') + error_400(); + + $assoc_handle = @strlen($_REQUEST['openid_assoc_handle']) + ? $_REQUEST['openid_assoc_handle'] + : error_post('Missing assoc_handle'); + + $sig = @strlen($_REQUEST['openid_sig']) + ? $_REQUEST['openid_sig'] + : error_post('Missing sig'); + + $signed = @strlen($_REQUEST['openid_signed']) + ? $_REQUEST['openid_signed'] + : error_post('Missing signed'); + + // Prepare the return keys + $keys = array( + 'openid.mode' => 'id_res' + ); + + // Invalidate the assoc handle if we need to + if (@strlen($_REQUEST['openid_invalidate_handle'])) { + destroy_assoc_handle($_REQUEST['openid_invalidate_handle']); + + $keys['invalidate_handle'] = $_REQUEST['openid_invalidate_handle']; + } + + // Validate the sig by recreating the kv pair and signing + $_REQUEST['openid_mode'] = 'id_res'; + $tokens = ''; + foreach (explode(',', $signed) as $param) { + $post = preg_replace('/\./', '_', $param); + $tokens .= sprintf("%s:%s\n", $param, $_REQUEST['openid_' . $post]); + } + + // Add the sreg stuff, if we've got it + if (isset($sreg_required)) { + foreach (explode(',', $sreg_required) as $key) { + if (! isset($sreg[$key])) + continue; + $skey = 'sreg.' . $key; + + $tokens .= sprintf("%s:%s\n", $skey, $sreg[$key]); + $keys[$skey] = $sreg[$key]; + $fields[] = $skey; + } + } + + // Look up the consumer's shared_secret and timeout + list ($shared_secret, $expires) = secret($assoc_handle); + + // if I can't verify the assoc_handle, or if it's expired + if ($shared_secret == false || (is_numeric($expires) && $expires < time())) { + $keys['is_valid'] = 'false'; + + } else { + $ok = base64_encode(hmac($shared_secret, $tokens)); + $keys['is_valid'] = ($sig == $ok) ? 'true' : 'false'; + } + + // Return the keys + wrap_kv($keys); +} + + +/** + * Handle a consumer's request to see if the end user is logged in + * @global array $known + * @global array $profile + * @global array $sreg + */ +function checkid ( $wait ) { + global $known, $profile, $sreg; + global $USERNAME; + + // This is a user session + user_session(); + + // Get the options, use defaults as necessary + $return_to = @strlen($_REQUEST['openid_return_to']) + ? $_REQUEST['openid_return_to'] + : error_400('Missing return1_to'); + + $identity = @strlen($_REQUEST['openid_identity']) + ? $_REQUEST['openid_identity'] + : error_get($return_to, 'Missing identity'); + + $assoc_handle = @strlen($_REQUEST['openid_assoc_handle']) + ? $_REQUEST['openid_assoc.handle'] + : null; + + $trust_root = @strlen($_REQUEST['openid_trust_root']) + ? $_REQUEST['openid_trust_root'] + : $return_to; + + $sreg_required = @strlen($_REQUEST['openid_sreg_required']) + ? $_REQUEST['openid_sreg.required'] + : ''; + + $sreg_optional = @strlen($_REQUEST['openid_sreg_optional']) + ? $_REQUEST['openid_sreg.optional'] + : ''; + + // determine the cancel url + $q = strpos($return_to, '?') ? '&' : '?'; + $cancel_url = $return_to . $q . 'openid.mode=cancel'; + + // required and optional make no difference to us + $sreg_required .= ',' . $sreg_optional; + // do the trust_root analysis + if ($trust_root != $return_to) { + // the urls are not the same, be sure return decends from trust + if (! url_descends($return_to, $trust_root)) + error_500('Invalid trust_root: "' . $trust_root . '"'); + + } + + // transfer the user to the url accept mode if they're paranoid + if ($wait == 1 && isset($profile['paranoid']) && $profile['paranoid'] === true && (! isset($_SESSION['accepted_url']) || $_SESSION['accepted_url'] != $trust_root)) { + $_SESSION['cancel_accept_url'] = $cancel_url; + $_SESSION['post_accept_url'] = $profile['req_url']; + $_SESSION['unaccepted_url'] = $trust_root; + + debug('Transferring to acceptance mode.'); + debug('Cancel URL: ' . $_SESSION['cancel_accept_url']); + debug('Post URL: ' . $_SESSION['post_accept_url']); + + $q = strpos($profile['idp_url'], '?') ? '&' : '?'; + wrap_redirect($profile['idp_url'] . $q . 'openid.mode=accept'); + } + + // make sure i am this identifier +// if ($identity != $profile['idp_url']) { +// debug("Invalid identity: $identity"); +// debug("IdP URL: " . $profile['idp_url']); +// error_get($return_to, "Invalid identity: '$identity'"); +// } + + // begin setting up return keys + $keys = array( + 'mode' => 'id_res' + ); + + // if the user is not logged in, transfer to the authorization mode + if ($USERNAME=='' || $_SESSION['openid_auth'] === false || $USERNAME != $_SESSION['openid_user']) { + // users can only be logged in to one url at a time + $_SESSION['openid_user'] = null; + $_SESSION['auth_url'] = null; + + if ($wait) { + unset($_SESSION['uniqid']); + + $_SESSION['cancel_auth_url'] = $cancel_url; + $_SESSION['post_auth_url'] = $profile['req_url']; + + debug('Transferring to authorization mode.'); + debug('Cancel URL: ' . $_SESSION['cancel_auth_url']); + debug('Post URL: ' . $_SESSION['post_auth_url']); + + $q = strpos($profile['idp_url'], '?') ? '&' : '?'; + wrap_redirect($profile['idp_url'] . $q . 'openid.mode=authorize'); + } else { + $keys['user_setup_url'] = $profile['idp_url']; + } + + // the user is logged in + } else { + // remove the refresh URLs if set + unset($_SESSION['cancel_auth_url']); + unset($_SESSION['post_auth_url']); + + // check the assoc handle + list($shared_secret, $expires) = secret($assoc_handle); + + // if I can't verify the assoc_handle, or if it's expired + if ($shared_secret == false || (is_numeric($expires) && $expires < time())) { + debug("Session expired or missing key: $expires < " . time()); + if ($assoc_handle != null) { + $keys['invalidate_handle'] = $assoc_handle; + destroy_assoc_handle($assoc_handle); + } + + $lifetime = time() + $profile['lifetime']; + list ($assoc_handle, $shared_secret) = new_assoc($lifetime); + } + + $keys['identity'] = $profile['idp_url']; + $keys['assoc_handle'] = $assoc_handle; + $keys['return_to'] = $return_to; + + $fields = array_keys($keys); + $tokens = ''; + foreach ($fields as $key) + $tokens .= sprintf("%s:%s\n", $key, $keys[$key]); + + // add sreg keys + foreach (explode(',', $sreg_required) as $key) { + if (! isset($sreg[$key])) + continue; + $skey = 'sreg.' . $key; + + $tokens .= sprintf("%s:%s\n", $skey, $sreg[$key]); + $keys[$skey] = $sreg[$key]; + $fields[] = $skey; + } + + $keys['signed'] = implode(',', $fields); + $keys['sig'] = base64_encode(hmac($shared_secret, $tokens)); + } + + wrap_keyed_redirect($return_to, $keys); +} + + +/** + * Handle a consumer's request to see if the user is already logged in + */ +function checkid_immediate_mode () { + if (! isset($_REQUEST['openid_mode']) || $_REQUEST['openid_mode'] != 'checkid_immediate') + error_500(); + + checkid(false); +} + + +/** + * Handle a consumer's request to see if the user is logged in, but be willing + * to wait for them to perform a login if they're not + */ +function checkid_setup_mode () { + if (! isset($_REQUEST['openid_mode']) || $_REQUEST['openid_mode'] != 'checkid_setup') + error_500(); + + checkid(true); +} + + +/** + * Handle errors + */ +function error_mode () { + isset($_REQUEST['openid_error']) + ? wrap_html($_REQUEST['openid_error']) + : error_500(); +} + + +/** + * Show a user if they are logged in or not + * @global array $profile + */ +function id_res_mode () { + global $profile; + + user_session(); + + if ($profile['authorized']) + wrap_html('You are logged in as ' . $_SESSION['auth_username']); + + wrap_html('You are not logged in'); +} + + +/** + * Allow a user to perform a static login + * @global array $profile + */ +function login_mode () { + global $profile; + + user_session(); + + if ($profile['authorized']) + id_res_mode(); + + $keys = array( + 'mode' => 'checkid_setup', + 'identity' => $profile['idp_url'], + 'return_to' => $profile['idp_url'] + ); + + wrap_keyed_redirect($profile['idp_url'], $keys); +} + + +/** + * Allow a user to perform a static logout + * @global array $profile + */ +function logout_mode () { + global $profile; + + user_session(); + + if (! $profile['authorized']) + wrap_html('You were not logged in'); + + $_SESSION = array(); + session_destroy(); + debug('User session destroyed.'); + + header('HTTP/1.0 401 Unauthorized'); + wrap_redirect($profile['idp_url']); +} + + +/** + * The default information screen + * @global array $profile + */ +function no_mode () { + global $USERNAME, $profile; + $tmpl = new OC_TEMPLATE( 'user_openid', 'nomode', 'guest' ); + if(substr($profile['req_url'],-1,1)!=='/'){//the identity should always end with a / + $profile['req_url'].='/'; + } + $tmpl->addHeader('link',array('rel'=>'openid.server', 'href'=>$profile['req_url'])); + $tmpl->addHeader('link',array('rel'=>'openid.delegate', 'href'=>$profile['idp_url'])); + $tmpl->assign('user',$USERNAME); + $tmpl->printPage(); +} + + +/** + * Testing for setup + * @global array $profile + */ +function test_mode () { + global $profile, $p, $g; + + if ($profile['allow_test'] != true) + error_403(); + + @ini_set('max_execution_time', 180); + + $test_expire = time() + 120; + $test_ss_enc = 'W7hvmld2yEYdDb0fHfSkKhQX+PM='; + $test_ss = base64_decode($test_ss_enc); + $test_token = "alpha:bravo\ncharlie:delta\necho:foxtrot"; + $test_server_private = '11263846781670293092494395517924811173145217135753406847875706165886322533899689335716152496005807017390233667003995430954419468996805220211293016296351031812246187748601293733816011832462964410766956326501185504714561648498549481477143603650090931135412673422192550825523386522507656442905243832471167330268'; + $test_client_public = base64_decode('AL63zqI5a5p8HdXZF5hFu8p+P9GOb816HcHuvNOhqrgkKdA3fO4XEzmldlb37nv3+xqMBgWj6gxT7vfuFerEZLBvuWyVvR7IOGZmx0BAByoq3fxYd3Fpe2Coxngs015vK37otmH8e83YyyGo5Qua/NAf13yz1PVuJ5Ctk7E+YdVc'); + + $res = array(); + + // bcmath + $res['bcmath'] = extension_loaded('bcmath') + ? 'pass' : 'warn - not loaded'; + + // gmp + if ($profile['allow_gmp']) { + $res['gmp'] = extension_loaded('gmp') + ? 'pass' : 'warn - not loaded'; + } else { + $res['gmp'] = 'pass - n/a'; + } + + // sys_get_temp_dir + $res['logfile'] = is_writable($profile['logfile']) + ? 'pass' : "warn - log is not writable"; + + // session & new_assoc + user_session(); + list($test_assoc, $test_new_ss) = new_assoc($test_expire); + $res['session'] = ($test_assoc != session_id()) + ? 'pass' : 'fail'; + + // secret + @session_unregister('shared_secret'); + list($check, $check2) = secret($test_assoc); + $res['secret'] = ($check == $test_new_ss) + ? 'pass' : 'fail'; + + // expire + $res['expire'] = ($check2 <= $test_expire) + ? 'pass' : 'fail'; + + // base64 + $res['base64'] = (base64_encode($test_ss) == $test_ss_enc) + ? 'pass' : 'fail'; + + // hmac + $test_sig = base64_decode('/VXgHvZAOdoz/OTa5+XJXzSGhjs='); + $check = hmac($test_ss, $test_token); + $res['hmac'] = ($check == $test_sig) + ? 'pass' : sprintf("fail - '%s'", base64_encode($check)); + + if ($profile['use_bigmath']) { + // bigmath powmod + $test_server_public = '102773334773637418574009974502372885384288396853657336911033649141556441102566075470916498748591002884433213640712303846640842555822818660704173387461364443541327856226098159843042567251113889701110175072389560896826887426539315893475252988846151505416694218615764823146765717947374855806613410142231092856731'; + $check = bmpowmod($g, $test_server_private, $p); + $res['bmpowmod-1'] = ($check == $test_server_public) + ? 'pass' : sprintf("fail - '%s'", $check); + + // long + $test_client_long = '133926731803116519408547886573524294471756220428015419404483437186057383311250738749035616354107518232016420809434801736658109316293127101479053449990587221774635063166689561125137927607200322073086097478667514042144489248048756916881344442393090205172004842481037581607299263456852036730858519133859409417564'; + $res['long'] = (long($test_client_public) == $test_client_long) + ? 'pass' : 'fail'; + + // bigmath powmod 2 + $test_client_share = '19333275433742428703546496981182797556056709274486796259858099992516081822015362253491867310832140733686713353304595602619444380387600756677924791671971324290032515367930532292542300647858206600215875069588627551090223949962823532134061941805446571307168890255137575975911397744471376862555181588554632928402'; + $check = bmpowmod($test_client_long, $test_server_private, $p); + $res['bmpowmod-2'] = ($check == $test_client_share) + ? 'pass' : sprintf("fail - '%s'", $check); + + // bin + $test_client_mac_s1 = base64_decode('G4gQQkYM6QmAzhKbVKSBahFesPL0nL3F2MREVwEtnVRRYI0ifl9zmPklwTcvURt3QTiGBd+9Dn3ESLk5qka6IO5xnILcIoBT8nnGVPiOZvTygfuzKp4tQ2mXuIATJoa7oXRGmBWtlSdFapH5Zt6NJj4B83XF/jzZiRwdYuK4HJI='); + $check = bin($test_client_share); + $res['bin'] = ($check == $test_client_mac_s1) + ? 'pass' : sprintf("fail - '%s'", base64_encode($check)); + + } else { + $res['bigmath'] = 'fail - big math functions are not available.'; + } + + // sha1_20 + $test_client_mac_s1 = base64_decode('G4gQQkYM6QmAzhKbVKSBahFesPL0nL3F2MREVwEtnVRRYI0ifl9zmPklwTcvURt3QTiGBd+9Dn3ESLk5qka6IO5xnILcIoBT8nnGVPiOZvTygfuzKp4tQ2mXuIATJoa7oXRGmBWtlSdFapH5Zt6NJj4B83XF/jzZiRwdYuK4HJI='); + $test_client_mac_s2 = base64_decode('0Mb2t9d/HvAZyuhbARJPYdx3+v4='); + $check = sha1_20($test_client_mac_s1); + $res['sha1_20'] = ($check == $test_client_mac_s2) + ? 'pass' : sprintf("fail - '%s'", base64_encode($check)); + + // x_or + $test_client_mac_s3 = base64_decode('i36ZLYAJ1rYEx1VEHObrS8hgAg0='); + $check = x_or($test_client_mac_s2, $test_ss); + $res['x_or'] = ($check == $test_client_mac_s3) + ? 'pass' : sprintf("fail - '%s'", base64_encode($check)); + + $out = "<table border=1 cellpadding=4>\n"; + foreach ($res as $test => $stat) { + $code = substr($stat, 0, 4); + $color = ($code == 'pass') ? '#9f9' + : (($code == 'warn') ? '#ff9' : '#f99'); + $out .= sprintf("<tr><th>%s</th><td style='background:%s'>%s</td></tr>\n", $test, $color, $stat); + } + $out .= "</table>"; + + wrap_html( $out ); +} + + +// Support functions + +/** + * Prefix the keys of an array with 'openid.' + * @param array $array + * @return array + */ +function append_openid ($array) { + $keys = array_keys($array); + $vals = array_values($array); + + $r = array(); + for ($i=0; $i<sizeof($keys); $i++) + $r['openid.' . $keys[$i]] = $vals[$i]; + return $r; +} + +/** + * Create a big math addition function + * @param string $l + * @param string $r + * @return string + * @url http://www.icosaedro.it/bigint Inspired by + */ +function bmadd($l, $r) { + if (function_exists('bcadd')) + return bcadd($l, $r); + + global $profile; + if ($profile['use_gmp']) + return gmp_strval(gmp_add($l, $r)); + + $l = strval($l); $r = strval($r); + $ll = strlen($l); $rl = strlen($r); + if ($ll < $rl) { + $l = str_repeat("0", $rl-$ll) . $l; + $o = $rl; + + } elseif ( $ll > $rl ) { + $r = str_repeat("0", $ll-$rl) . $r; + $o = $ll; + + } else { + $o = $ll; + } + + $v = ''; + $carry = 0; + + for ($i = $o-1; $i >= 0; $i--) { + $d = (int)$l[$i] + (int)$r[$i] + $carry; + if ($d <= 9) { + $carry = 0; + + } else { + $carry = 1; + $d -= 10; + } + $v = (string) $d . $v; + } + + if ($carry > 0) + $v = "1" . $v; + + return $v; +} + +/** + * Create a big math comparison function + * @param string $l + * @param string $r + * @return string + */ +function bmcomp($l, $r) { + if (function_exists('bccomp')) + return bccomp($l, $r); + + global $profile; + if ($profile['use_gmp']) + return gmp_strval(gmp_cmp($l, $r)); + + $l = strval($l); $r = strval($r); + $ll = strlen($l); $lr = strlen($r); + if ($ll != $lr) + return ($ll > $lr) ? 1 : -1; + + return strcmp($l, $r); +} + +/** + * Create a big math division function + * @param string $l + * @param string $r + * @param int $z + * @return string + * @url http://www.icosaedro.it/bigint Inspired by + */ +function bmdiv($l, $r, $z = 0) { + if (function_exists('bcdiv')) + return ($z == 0) ? bcdiv($l, $r) : bcmod($l, $r); + + global $profile; + if ($profile['use_gmp']) + return gmp_strval(($z == 0) ? gmp_div_q($l, $r) : gmp_mod($l, $r)); + + $l = strval($l); $r = strval($r); + $v = '0'; + + while (true) { + if( bmcomp($l, $r) < 0 ) + break; + + $delta = strlen($l) - strlen($r); + if ($delta >= 1) { + $zeroes = str_repeat("0", $delta); + $r2 = $r . $zeroes; + + if (strcmp($l, $r2) >= 0) { + $v = bmadd($v, "1" . $zeroes); + $l = bmsub($l, $r2); + + } else { + $zeroes = str_repeat("0", $delta - 1); + $v = bmadd($v, "1" . $zeroes); + $l = bmsub($l, $r . $zeroes); + } + + } else { + $l = bmsub($l, $r); + $v = bmadd($v, "1"); + } + } + + return ($z == 0) ? $v : $l; +} + +/** + * Create a big math multiplication function + * @param string $l + * @param string $r + * @return string + * @url http://www.icosaedro.it/bigint Inspired by + */ +function bmmul($l, $r) { + if (function_exists('bcmul')) + return bcmul($l, $r); + + global $profile; + if ($profile['use_gmp']) + return gmp_strval(gmp_mul($l, $r)); + + $l = strval($l); $r = strval($r); + + $v = '0'; + $z = ''; + + for( $i = strlen($r)-1; $i >= 0; $i-- ){ + $bd = (int) $r[$i]; + $carry = 0; + $p = ""; + for( $j = strlen($l)-1; $j >= 0; $j-- ){ + $ad = (int) $l[$j]; + $pd = $ad * $bd + $carry; + if( $pd <= 9 ){ + $carry = 0; + } else { + $carry = (int) ($pd / 10); + $pd = $pd % 10; + } + $p = (string) $pd . $p; + } + if( $carry > 0 ) + $p = (string) $carry . $p; + $p = $p . $z; + $z .= "0"; + $v = bmadd($v, $p); + } + + return $v; +} + +/** + * Create a big math modulus function + * @param string $value + * @param string $mod + * @return string + */ +function bmmod( $value, $mod ) { + if (function_exists('bcmod')) + return bcmod($value, $mod); + + global $profile; + if ($profile['use_gmp']) + return gmp_strval(gmp_mod($value, $mod)); + + $r = bmdiv($value, $mod, 1); + return $r; +} + +/** + * Create a big math power function + * @param string $value + * @param string $exponent + * @return string + */ +function bmpow ($value, $exponent) { + if (function_exists('bcpow')) + return bcpow($value, $exponent); + + global $profile; + if ($profile['use_gmp']) + return gmp_strval(gmp_pow($value, $exponent)); + + $r = '1'; + while ($exponent) { + $r = bmmul($r, $value, 100); + $exponent--; + } + return (string)rtrim($r, '0.'); +} + +/** + * Create a big math 'powmod' function + * @param string $value + * @param string $exponent + * @param string $mod + * @return string + * @url http://php.net/manual/en/function.bcpowmod.php#72704 Borrowed from + */ +function bmpowmod ($value, $exponent, $mod) { + if (function_exists('bcpowmod')) + return bcpowmod($value, $exponent, $mod); + + global $profile; + if ($profile['use_gmp']) + return gmp_strval(gmp_powm($value, $exponent, $mod)); + + $r = ''; + while ($exponent != '0') { + $t = bmmod($exponent, '4096'); + $r = substr("000000000000" . decbin(intval($t)), -12) . $r; + $exponent = bmdiv($exponent, '4096'); + } + + $r = preg_replace("!^0+!","",$r); + + if ($r == '') + $r = '0'; + $value = bmmod($value, $mod); + $erb = strrev($r); + $q = '1'; + $a[0] = $value; + + for ($i = 1; $i < strlen($erb); $i++) { + $a[$i] = bmmod( bmmul($a[$i-1], $a[$i-1]), $mod ); + } + + for ($i = 0; $i < strlen($erb); $i++) { + if ($erb[$i] == "1") { + $q = bmmod( bmmul($q, $a[$i]), $mod ); + } + } + + return($q); +} + +/** + * Create a big math subtraction function + * @param string $l + * @param string $r + * @return string + * @url http://www.icosaedro.it/bigint Inspired by + */ +function bmsub($l, $r) { + if (function_exists('bcsub')) + return bcsub($l, $r); + + global $profile; + if ($profile['use_gmp']) + return gmp_strval(gmp_sub($l, $r)); + + + $l = strval($l); $r = strval($r); + $ll = strlen($l); $rl = strlen($r); + + if ($ll < $rl) { + $l = str_repeat("0", $rl-$ll) . $l; + $o = $rl; + } elseif ( $ll > $rl ) { + $r = str_repeat("0", $ll-$rl) . (string)$r; + $o = $ll; + } else { + $o = $ll; + } + + if (strcmp($l, $r) >= 0) { + $sign = ''; + } else { + $x = $l; $l = $r; $r = $x; + $sign = '-'; + } + + $v = ''; + $carry = 0; + + for ($i = $o-1; $i >= 0; $i--) { + $d = ($l[$i] - $r[$i]) - $carry; + if ($d < 0) { + $carry = 1; + $d += 10; + } else { + $carry = 0; + } + $v = (string) $d . $v; + } + + return $sign . ltrim($v, '0'); +} + + +/** + * Get a binary value + * @param integer $n + * @return string + * @url http://openidenabled.com Borrowed from PHP-OpenID + */ +function bin ($n) { + $bytes = array(); + while (bmcomp($n, 0) > 0) { + array_unshift($bytes, bmmod($n, 256)); + $n = bmdiv($n, bmpow(2,8)); + } + + if ($bytes && ($bytes[0] > 127)) + array_unshift($bytes, 0); + + $b = ''; + foreach ($bytes as $byte) + $b .= pack('C', $byte); + + return $b; +} + + +/** + * Debug logging + * @param mixed $x + * @param string $m + */ +function debug ($x, $m = null) { + global $profile; + + if (! isset($profile['debug']) || $profile['debug'] === false) + return true; + + if (! is_writable(dirname($profile['logfile'])) &! is_writable($profile['logfile'])) + error_500('Cannot write to debug log: ' . $profile['logfile']); + + if (is_array($x)) { + ob_start(); + print_r($x); + $x = $m . ($m != null ? "\n" : '') . ob_get_clean(); + + } else { + $x .= "\n"; + } + + error_log($x . "\n", 3, $profile['logfile']); +} + + +/** + * Destroy a consumer's assoc handle + * @param string $id + */ +function destroy_assoc_handle ( $id ) { + debug("Destroying session: $id"); + + $sid = session_id(); + session_write_close(); + + session_id($id); + session_start(); + session_destroy(); + + session_id($sid); + session_start(); +} + + +/** + * Return an error message to the user + * @param string $message + */ +function error_400 ( $message = 'Bad Request' ) { + header("HTTP/1.1 400 Bad Request"); + wrap_html($message); +} + + +/** + * Return an error message to the user + * @param string $message + */ +function error_403 ( $message = 'Forbidden' ) { + header("HTTP/1.1 403 Forbidden"); + wrap_html($message); +} + + +/** + * Return an error message to the user + * @param string $message + */ +function error_500 ( $message = 'Internal Server Error' ) { + header("HTTP/1.1 500 Internal Server Error"); + wrap_html($message); +} + + +/** + * Return an error message to the consumer + * @param string $message + */ +function error_get ( $url, $message = 'Bad Request') { + wrap_keyed_redirect($url, array('mode' => 'error', 'error' => $message)); +} + + +/** + * Return an error message to the consumer + * @param string $message + */ +function error_post ( $message = 'Bad Request' ) { + header("HTTP/1.1 400 Bad Request"); + echo ('error:' . $message); + exit(0); +} + + +/** + * Do an HMAC + * @param string $key + * @param string $data + * @param string $hash + * @return string + * @url http://php.net/manual/en/function.sha1.php#39492 Borrowed from + */ +function hmac($key, $data, $hash = 'sha1_20') { + $blocksize=64; + + if (strlen($key) > $blocksize) + $key = $hash($key); + + $key = str_pad($key, $blocksize,chr(0x00)); + $ipad = str_repeat(chr(0x36),$blocksize); + $opad = str_repeat(chr(0x5c),$blocksize); + + $h1 = $hash(($key ^ $ipad) . $data); + $hmac = $hash(($key ^ $opad) . $h1); + return $hmac; +} + + +if (! function_exists('http_build_query')) { +/** + * Create function if missing + * @param array $array + * @return string + */ +function http_build_query ($array) { + $r = array(); + foreach ($array as $key => $val) + $r[] = sprintf('%s=%s', urlencode($key), urlencode($val)); + return implode('&', $r); +}} + + +/** + * Turn a binary back into a long + * @param string $b + * @return integer + * @url http://openidenabled.com Borrowed from PHP-OpenID + */ +function long($b) { + $bytes = array_merge(unpack('C*', $b)); + $n = 0; + foreach ($bytes as $byte) { + $n = bmmul($n, bmpow(2,8)); + $n = bmadd($n, $byte); + } + return $n; +} + + +/** + * Create a new consumer association + * @param integer $expiration + * @return array + */ +function new_assoc ( $expiration ) { + if (isset($_SESSION) && is_array($_SESSION)) { + $sid = session_id(); + $dat = session_encode(); + session_write_close(); + } + + session_start(); + session_regenerate_id('false'); + + $id = session_id(); + $shared_secret = new_secret(); + debug('Started new assoc session: ' . $id); + + $_SESSION = array(); + $_SESSION['expiration'] = $expiration; + $_SESSION['shared_secret'] = base64_encode($shared_secret); + + session_write_close(); + + if (isset($sid)) { + session_id($sid); + session_start(); + $_SESSION = array(); + session_decode($dat); + } + + return array($id, $shared_secret); +} + + +/** + * Create a new shared secret + * @return string + */ +function new_secret () { + $r = ''; + for($i=0; $i<20; $i++) + $r .= chr(mt_rand(0, 255)); + + debug("Generated new key: hash = '" . md5($r) . "', length = '" . strlen($r) . "'"); + return $r; +} + + +/** + * Random number generation + * @param integer max + * @return integer + */ +function random ( $max ) { + if (strlen($max) < 4) + return mt_rand(1, $max - 1); + + $r = ''; + for($i=1; $i<strlen($max) - 1; $i++) + $r .= mt_rand(0,9); + $r .= mt_rand(1,9); + + return $r; +} + +/** + * Get the shared secret and expiration time for the specified assoc_handle + * @param string $handle assoc_handle to look up + * @return array (shared_secret, expiration_time) + */ +function secret ( $handle ) { + if (! preg_match('/^\w+$/', $handle)) + return array(false, 0); + + if (isset($_SESSION) && is_array($_SESSION)) { + $sid = session_id(); + $dat = session_encode(); + session_write_close(); + } + + session_id($handle); + session_start(); + debug('Started session to acquire key: ' . session_id()); + + $secret = isset($_SESSION['shared_secret']) + ? base64_decode($_SESSION['shared_secret']) + : false; + + $expiration = isset($_SESSION['expiration']) + ? $_SESSION['expiration'] + : null; + + session_write_close(); + + if (isset($sid)) { + session_id($sid); + session_start(); + $_SESSION = array(); + session_decode($dat); + } + + debug("Found key: hash = '" . md5($secret) . "', length = '" . strlen($secret) . "', expiration = '$expiration'"); + return array($secret, $expiration); +} + + +/** + * Do an internal self check + * @global array $profile + * @global array $sreg + */ +function self_check () { + global $profile, $sreg; + +// if (! isset($profile) || ! is_array($profile)) +// error_500('No configuration found, you shouldn\'t access this file directly.'); + + if (version_compare(phpversion(), '4.2.0', 'lt')) + error_500('The required minimum version of PHP is 4.2.0, you are running ' . phpversion()); + + $extension_r = array('session', 'pcre'); + foreach ($extension_r as $x) { + if (! extension_loaded($x)) + @dl($x); + if (! extension_loaded($x)) + error_500("Required extension '$x' is missing."); + } + +// $extension_b = array('suhosin'); +// foreach ($extension_b as $x) { +// if (extension_loaded($x) &! $profile["allow_$x"]) +// error_500("phpMyID is not compatible with '$x'"); +// } +// +// $keys = array('auth_username', 'auth_password'); +// foreach ($keys as $key) { +// if (! array_key_exists($key, $profile)) +// error_500("'$key' is missing from your profile."); +// } + + if (! isset($sreg) || ! is_array($sreg)) + $sreg = array(); +} + + +/** + * Do SHA1 20 byte encryption + * @param string $v + * @return string + * @url http://openidenabled.com Borrowed from PHP-OpenID + */ +function sha1_20 ($v) { + if (version_compare(phpversion(), '5.0.0', 'ge')) + return sha1($v, true); + + $hex = sha1($v); + $r = ''; + for ($i = 0; $i < 40; $i += 2) { + $hexcode = substr($hex, $i, 2); + $charcode = base_convert($hexcode, 16, 10); + $r .= chr($charcode); + } + return $r; +} + + +/** + * Look for the point of differentiation in two strings + * @param string $a + * @param string $b + * @return int + */ +function str_diff_at ($a, $b) { + if ($a == $b) + return -1; + $n = min(strlen($a), strlen($b)); + for ($i = 0; $i < $n; $i++) + if ($a[$i] != $b[$i]) + return $i; + return $n; +} + + +if (! function_exists('sys_get_temp_dir') && ini_get('open_basedir') == false) { +/** + * Create function if missing + * @return string + */ +function sys_get_temp_dir () { + $keys = array('TMP', 'TMPDIR', 'TEMP'); + foreach ($keys as $key) { + if (isset($_ENV[$key]) && is_dir($_ENV[$key]) && is_writable($_ENV[$key])) + return realpath($_ENV[$key]); + } + + $tmp = tempnam(false, null); + if (file_exists($tmp)) { + $dir = realpath(dirname($tmp)); + unlink($tmp); + return realpath($dir); + } + + return realpath(dirname(__FILE__)); +}} elseif (! function_exists('sys_get_temp_dir')) { +function sys_get_temp_dir () { + return realpath(dirname(__FILE__)); +}} + + +/** + * Determine if a child URL actually decends from the parent, and that the + * parent is a good URL. + * THIS IS EXPERIMENTAL + * @param string $parent + * @param string $child + * @return bool + */ +function url_descends ( $child, $parent ) { + if ($child == $parent) + return true; + + $keys = array(); + $parts = array(); + + $req = array('scheme', 'host'); + $bad = array('fragment', 'pass', 'user'); + + foreach (array('parent', 'child') as $name) { + $parts[$name] = @parse_url($$name); + if ($parts[$name] === false) + return false; + + $keys[$name] = array_keys($parts[$name]); + + if (array_intersect($keys[$name], $req) != $req) + return false; + + if (array_intersect($keys[$name], $bad) != array()) + return false; + + if (! preg_match('/^https?$/i', strtolower($parts[$name]['scheme']))) + return false; + + if (! array_key_exists('port', $parts[$name])) + $parts[$name]['port'] = (strtolower($parts[$name]['scheme']) == 'https') ? 443 : 80; + + if (! array_key_exists('path', $parts[$name])) + $parts[$name]['path'] = '/'; + } + + // port and scheme must match + if ($parts['parent']['scheme'] != $parts['child']['scheme'] || + $parts['parent']['port'] != $parts['child']['port']) + return false; + + // compare the hosts by reversing the strings + $cr_host = strtolower(strrev($parts['child']['host'])); + $pr_host = strtolower(strrev($parts['parent']['host'])); + + $break = str_diff_at($cr_host, $pr_host); + if ($break >= 0 && ($pr_host[$break] != '*' || substr_count(substr($pr_host, 0, $break), '.') < 2)) + return false; + + // now compare the paths + $break = str_diff_at($parts['child']['path'], $parts['parent']['path']); + if ($break >= 0 + && ($break < strlen($parts['parent']['path']) && $parts['parent']['path'][$break] != '*') + || ($break > strlen($parts['child']['path']))) + return false; + + return true; +} + + +/** + * Create a user session + * @global array $profile + * @global array $proto + */ +function user_session () { + global $proto, $profile; + + session_name('phpMyID_Server'); + @session_start(); + + $profile['authorized'] = (isset($_SESSION['auth_username']) + && $_SESSION['auth_username'] == $profile['auth_username']) + ? true + : false; + + debug('Started user session: ' . session_id() . ' Auth? ' . $profile['authorized']); +} + + +/** + * Return HTML + * @global string $charset + * @param string $message + */ +function wrap_html ( $message ) { + global $charset, $profile; + header('Content-Type: text/html; charset=' . $charset); + $html= '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html> +<head> +<title>phpMyID</title> +<link rel="openid.server" href="' . $profile['req_url'] . '" /> +<link rel="openid.delegate" href="' . $profile['idp_url'] . '" /> +' . implode("\n", $profile['opt_headers']) . ' +<meta name="charset" content="' . $charset . '" /> +<meta name="robots" content="noindex,nofollow" /> +</head> +<body> +<p>' . $message . '</p> +</body> +</html> +'; + error_log($html); + echo $html; + exit(0); +} + + +/** + * Return a key-value pair in plain text + * @global string $charset + * @param array $keys + */ +function wrap_kv ( $keys ) { + global $charset; + + debug($keys, 'Wrapped key/vals'); + header('Content-Type: text/plain; charset=' . $charset); + foreach ($keys as $key => $value) + printf("%s:%s\n", $key, $value); + + exit(0); +} + + +/** + * Redirect, with OpenID keys + * @param string $url + * @param array @keys + */ +function wrap_keyed_redirect ($url, $keys) { + $keys = append_openid($keys); + debug($keys, 'Location keys'); + + $q = strpos($url, '?') ? '&' : '?'; + wrap_redirect($url . $q . http_build_query($keys)); +} + + +/** + * Redirect the browser + * @global string $charset + * @param string $url + */ +function wrap_redirect ($url) { + header('HTTP/1.1 302 Found'); + header('Location: ' . $url); + debug('Location: ' . $url); + exit(0); +} + +/** + * Return an HTML refresh + * @global string $charset + * @param string $url + */ +function wrap_refresh ($url) { + global $charset; + + header('Content-Type: text/html; charset=' . $charset); + echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html> +<head> +<title>phpMyID</title> +<meta http-equiv="refresh" content="0;url=' . $url . '"> +</head> +<body> +<p>Redirecting to <a href="' . $url . '">' . $url . '</a></p> +</body> +</html> +'; + + debug('Refresh: ' . $url); + exit(0); +} + + +/** + * Implement binary x_or + * @param string $a + * @param string $b + * @return string + */ +function x_or ($a, $b) { + $r = ""; + + for ($i = 0; $i < strlen($b); $i++) + $r .= $a[$i] ^ $b[$i]; + debug("Xor size: " . strlen($r)); + return $r; +} + + + +/* + * App Initialization + */ +// Determine the charset to use +$GLOBALS['charset'] = 'iso-8859-1'; + +// Set the internal encoding +if (function_exists('mb_internal_encoding')) + mb_internal_encoding($charset); + +// Avoid problems with non-default arg_separator.output settings +// Credit for this goes to user 'prelog' on the forums +ini_set('arg_separator.output', '&'); + +// Do a check to be sure everything is set up correctly +self_check(); + + +/** + * Determine the HTTP request port + * @name $port + * @global integer $GLOBALS['port'] + */ +$GLOBALS['port'] = ((isset($_SERVER["HTTPS"]) && $_SERVER["HTTPS"] == 'on' && $_SERVER['SERVER_PORT'] == 443) + || $_SERVER['SERVER_PORT'] == 80) + ? '' + : ':' . $_SERVER['SERVER_PORT']; + + +error_log($_SERVER['HTTP_HOST']); +/** + * Determine the HTTP request protocol + * @name $proto + * @global string $GLOBALS['proto'] + */ +$GLOBALS['proto'] = (isset($_SERVER["HTTPS"]) && $_SERVER["HTTPS"] == 'on') ? 'https' : 'http'; + +// Set the authorization state - DO NOT OVERRIDE +$profile['authorized'] = false; + +global $IDENTITY; +global $USERNAME; + +// Set a default IDP URL +if (! array_key_exists('idp_url', $profile)) + $profile['idp_url'] = $IDENTITY; + +//Determine the requested URL - DO NOT OVERRIDE +$profile['req_url'] = sprintf("%s://%s%s", + $proto, + $_SERVER['HTTP_HOST'], +// $port,//host already includes the path + $_SERVER["REQUEST_URI"]); + +$fullId=urlencode('.php/'.$USERNAME); +$incompleteId=urlencode('.php/'); + +if(!strpos($profile['req_url'],$fullId)){ + $profile['req_url']=str_replace($incompleteId,$fullId,$profile['req_url']); +} + +error_log('inc id: '.$fullId); +error_log('req url: '.$profile['req_url']); + +// Set the default allowance for testing +if (! array_key_exists('allow_test', $profile)) + $profile['allow_test'] = false; + +// Set the default allowance for gmp +if (! array_key_exists('allow_gmp', $profile)) + $profile['allow_gmp'] = false; + +// Set the default force bigmath - BAD IDEA to override this +if (! array_key_exists('force_bigmath', $profile)) + $profile['force_bigmath'] = false; + +// Determine if GMP is usable +$profile['use_gmp'] = (extension_loaded('gmp') && $profile['allow_gmp']) ? true : false; + +// Determine if I can perform big math functions +$profile['use_bigmath'] = (extension_loaded('bcmath') || $profile['use_gmp'] || $profile['force_bigmath']) ? true : false; + +// Set a default authentication domain +if (! array_key_exists('auth_domain', $profile)) + $profile['auth_domain'] = $profile['req_url'] . ' ' . $profile['idp_url']; + +// Set a default authentication realm +if (! array_key_exists('auth_realm', $profile)) + $profile['auth_realm'] = 'ownCloud'; + +// Determine the realm for digest authentication - DO NOT OVERRIDE +$profile['php_realm'] = $profile['auth_realm'] . (ini_get('safe_mode') ? '-' . getmyuid() : ''); + +// Set a default lifetime - the lesser of GC and cache time +if (! array_key_exists('lifetime', $profile)) { + $sce = session_cache_expire() * 60; + $gcm = ini_get('session.gc_maxlifetime'); + $profile['lifetime'] = $sce < $gcm ? $sce : $gcm; +} + +// Set a default log file +if (! array_key_exists('logfile', $profile)) + $profile['logfile'] = sys_get_temp_dir() . DIRECTORY_SEPARATOR . $profile['auth_realm'] . '.debug.log'; + + +/* + * Optional Initialization + */ +// Setup optional headers +$profile['opt_headers'] = array(); + +// Determine if I should add microid stuff +if (array_key_exists('microid', $profile)) { + $hash = sha1($profile['idp_url']); + $values = is_array($profile['microid']) ? $profile['microid'] : array($profile['microid']); + + foreach ($values as $microid) { + preg_match('/^([a-z]+)/i', $microid, $mtx); + $profile['opt_headers'][] = sprintf('<meta name="microid" content="%s+%s:sha1:%s" />', $mtx[1], $proto, sha1(sha1($microid) . $hash)); + } +} + +// Determine if I should add pavatar stuff +if (array_key_exists('pavatar', $profile)) + $profile['opt_headers'][] = sprintf('<link rel="pavatar" href="%s" />', $profile['pavatar']); + + +/* + * Do it + */ +// Decide which runmode, based on user request or default +$run_mode = (isset($_REQUEST['openid_mode']) + && in_array($_REQUEST['openid_mode'], $known['openid_modes'])) + ? $_REQUEST['openid_mode'] + : 'no'; + +// Run in the determined runmode +debug("Run mode: $run_mode at: " . time()); +debug($_REQUEST, 'Request params'); +call_user_func($run_mode . '_mode'); +?> diff --git a/apps/user_openid/settings.php b/apps/user_openid/settings.php new file mode 100644 index 00000000000..76316de100c --- /dev/null +++ b/apps/user_openid/settings.php @@ -0,0 +1,24 @@ +<?php + +require_once('../../lib/base.php'); +require( 'template.php' ); +if( !OC_USER::isLoggedIn()){ + header( "Location: ".OC_HELPER::linkTo( "index.php" )); + exit(); +} + +if(isset($_POST['input_identity'])){ + OC_PREFERENCES::setValue(OC_USER::getUser(),'user_openid','identity',$_POST['input_identity']); +} + +OC_APP::setActiveNavigationEntry( "user_openid_settings" ); + +$identity=OC_PREFERENCES::getValue(OC_USER::getUser(),'user_openid','identity',''); + +$tmpl = new OC_TEMPLATE( "user_openid", "settings", "admin"); +$tmpl->assign('identity',$identity); +$tmpl->assign('user',OC_USER::getUser()); + +$tmpl->printPage(); + +?> diff --git a/apps/user_openid/templates/nomode.php b/apps/user_openid/templates/nomode.php new file mode 100644 index 00000000000..f85d28cdc9b --- /dev/null +++ b/apps/user_openid/templates/nomode.php @@ -0,0 +1,28 @@ +<?php + +global $profile; + +?> + +<div id="login"> + <img src="<?php echo image_path("", "owncloud-logo-medium-white.png"); ?>" alt="ownCloud" /> + <ul> + <li class='error'> + <div id="setup_form"> + <p><?php echo($l->t('This is an OpenID server endpoint. For more information, see '));?><a href='http://openid.net/' title='openid.net'>http://openid.net/</a></p> + <?php if($_['user']):?> + <p><?php echo($l->t('Identity: <b>').$profile['idp_url']); ?></b></p> + <p><?php echo($l->t('Realm: <b>').$profile['php_realm']); ?></b></p> + <p><?php echo($l->t('User: <b>').$_['user']); ?></b> + <p><a href="<?php echo($profile['idp_url']); ?>?openid.mode=login"><?php echo($l->t('Login')); ?></a> + <?php if($profile['allow_test'] === true): ?> + <a href="<?php echo($profile['idp_url']); ?>?openid.mode=test">Test</a> + <?php endif; ?> + <?php else: ?> + <p><?php echo($l->t('Error: <b>No user Selected')); ?></p> + <?php endif; ?> + </div> + </li> + </ul> +</div> + diff --git a/apps/user_openid/templates/settings.php b/apps/user_openid/templates/settings.php new file mode 100644 index 00000000000..7a1b530fbca --- /dev/null +++ b/apps/user_openid/templates/settings.php @@ -0,0 +1,7 @@ +<form id="identity" action='#' method='post'> + <fieldset> + <legend><?php echo $l->t( 'OpenID identity' );?></legend> + <label for='input_identity'>OpenID identity for <b><?php echo $_['user'];?></b></label><br/> + <input name='input_identity' id='input_identity' value="<?php echo $_['identity'];?>"/><input type='submit' value='Save'/> + </fieldset> +</form> diff --git a/apps/user_openid/user.php b/apps/user_openid/user.php new file mode 100644 index 00000000000..52af9ba3a56 --- /dev/null +++ b/apps/user_openid/user.php @@ -0,0 +1,47 @@ +<?php + +/** +* ownCloud +* +* @author Robin Appelman +* @copyright 2011 Robin Appelman icewind1991@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/>. +* +*/ + +$USERNAME=substr($_SERVER["REQUEST_URI"],strpos($_SERVER["REQUEST_URI"],'.php/')+5); +if(strpos($USERNAME,'?')!==false){ + $USERNAME=substr($USERNAME,0,strpos($USERNAME,'?')); +} + + +if($USERNAME=='' and isset($_SERVER['PHP_AUTH_USER'])){ + $USERNAME=$_SERVER['PHP_AUTH_USER']; +} + +$RUNTIME_NOAPPS=true; +$RUNTIME_NOAPPS=false; +require_once '../../lib/base.php'; + +if(!OC_USER::userExists($USERNAME)){ + $USERNAME=''; +} +global $WEBROOT; +$IDENTITY=((isset($_SERVER["HTTPS"]) && $_SERVER["HTTPS"] == 'on') ? 'https' : 'http').'://'.$_SERVER['HTTP_HOST'].$WEBROOT.'/apps/user_openid/user.php/'.$USERNAME; + +require_once 'phpmyid.php'; + + +?>
\ No newline at end of file diff --git a/apps/user_openid/user_openid.php b/apps/user_openid/user_openid.php new file mode 100644 index 00000000000..ddf5cc9bc23 --- /dev/null +++ b/apps/user_openid/user_openid.php @@ -0,0 +1,71 @@ +<?php + +/** + * ownCloud + * + * @author Robin Appelman + * @copyright 2011 Robin Appelman icewind1991gmailc.om + * + * 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/>. + * + */ + +require_once('User/backend.php'); +require_once('class.openid.v3.php'); + +/** + * Class for user management in a SQL Database (e.g. MySQL, SQLite) + */ +class OC_USER_OPENID extends OC_USER_BACKEND { + /** + * @brief Check if the password is correct + * @param $uid The username + * @param $password The password + * @returns true/false + * + * Check if the password is correct without logging in the user + */ + public function checkPassword( $uid, $password ){ + global $WEBROOT; + // Get identity from user and redirect browser to OpenID Server + $openid = new SimpleOpenID; + $openid->SetIdentity($uid); + $openid->SetTrustRoot('http://' . $_SERVER["HTTP_HOST"]); + if ($openid->GetOpenIDServer()){ + $openid->SetApprovedURL('http://' . $_SERVER["HTTP_HOST"] . $WEBROOT); // Send Response from OpenID server to this script + $openid->Redirect(); // This will redirect user to OpenID Server + exit; + }else{ + return false; + } + exit; + } + + /** + * find the user that can be authenticated with an openid identity + */ + public static function findUserForIdentity($identity){ + $query=OC_DB::prepare('SELECT userid FROM *PREFIX*preferences WHERE appid=? AND configkey=? AND configvalue=?'); + $result=$query->execute(array('user_openid','identity',$identity))->fetchAll(); + if(count($result)>0){ + return $result[0]['userid']; + }else{ + return false; + } + } +} + + + +?>
\ No newline at end of file diff --git a/config/.gitignore b/config/.gitignore index d09f42a2389..d09f42a2389 100644..100755 --- a/config/.gitignore +++ b/config/.gitignore diff --git a/core/ajax/translations.php b/core/ajax/translations.php new file mode 100644 index 00000000000..adaf7dcb758 --- /dev/null +++ b/core/ajax/translations.php @@ -0,0 +1,34 @@ +<?php + +/** +* ownCloud - ajax frontend +* +* @author Jakob Sack +* @copyright 2011 Jakob Sack kde@jakobsack.de +* +* 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/>. +* +*/ + +// Init owncloud +require_once('../../lib/base.php'); + +$app = $_POST["app"]; + +// We send json data +header( "Content-Type: application/jsonrequest" ); +$l = new OC_L10N( $app ); + +echo json_encode( array( 'status' => 'success', 'data' => $l->getTranslations())); +?> diff --git a/css/images/no.png b/core/css/images/no.png Binary files differindex fdc0f421255..fdc0f421255 100644 --- a/css/images/no.png +++ b/core/css/images/no.png diff --git a/css/images/ui-bg_diagonals-thick_90_eeeeee_40x40.png b/core/css/images/ui-bg_diagonals-thick_90_eeeeee_40x40.png Binary files differindex 6348115e6be..6348115e6be 100644 --- a/css/images/ui-bg_diagonals-thick_90_eeeeee_40x40.png +++ b/core/css/images/ui-bg_diagonals-thick_90_eeeeee_40x40.png diff --git a/css/images/ui-bg_flat_15_cd0a0a_40x100.png b/core/css/images/ui-bg_flat_15_cd0a0a_40x100.png Binary files differindex 7680b5437cf..7680b5437cf 100644 --- a/css/images/ui-bg_flat_15_cd0a0a_40x100.png +++ b/core/css/images/ui-bg_flat_15_cd0a0a_40x100.png diff --git a/css/images/ui-bg_glass_100_e4f1fb_1x400.png b/core/css/images/ui-bg_glass_100_e4f1fb_1x400.png Binary files differindex 705a32ea35d..705a32ea35d 100644 --- a/css/images/ui-bg_glass_100_e4f1fb_1x400.png +++ b/core/css/images/ui-bg_glass_100_e4f1fb_1x400.png diff --git a/css/images/ui-bg_glass_50_3baae3_1x400.png b/core/css/images/ui-bg_glass_50_3baae3_1x400.png Binary files differindex baabca6baaf..baabca6baaf 100644 --- a/css/images/ui-bg_glass_50_3baae3_1x400.png +++ b/core/css/images/ui-bg_glass_50_3baae3_1x400.png diff --git a/css/images/ui-bg_glass_80_d7ebf9_1x400.png b/core/css/images/ui-bg_glass_80_d7ebf9_1x400.png Binary files differindex d9387e9507e..d9387e9507e 100644 --- a/css/images/ui-bg_glass_80_d7ebf9_1x400.png +++ b/core/css/images/ui-bg_glass_80_d7ebf9_1x400.png diff --git a/css/images/ui-bg_highlight-hard_100_f2f5f7_1x100.png b/core/css/images/ui-bg_highlight-hard_100_f2f5f7_1x100.png Binary files differindex 28b566c2c29..28b566c2c29 100644 --- a/css/images/ui-bg_highlight-hard_100_f2f5f7_1x100.png +++ b/core/css/images/ui-bg_highlight-hard_100_f2f5f7_1x100.png diff --git a/css/images/ui-bg_highlight-hard_70_000000_1x100.png b/core/css/images/ui-bg_highlight-hard_70_000000_1x100.png Binary files differindex d5882978043..d5882978043 100644 --- a/css/images/ui-bg_highlight-hard_70_000000_1x100.png +++ b/core/css/images/ui-bg_highlight-hard_70_000000_1x100.png diff --git a/css/images/ui-bg_highlight-soft_100_deedf7_1x100.png b/core/css/images/ui-bg_highlight-soft_100_deedf7_1x100.png Binary files differindex 2289d3c7d7b..2289d3c7d7b 100644 --- a/css/images/ui-bg_highlight-soft_100_deedf7_1x100.png +++ b/core/css/images/ui-bg_highlight-soft_100_deedf7_1x100.png diff --git a/css/images/ui-bg_highlight-soft_25_ffef8f_1x100.png b/core/css/images/ui-bg_highlight-soft_25_ffef8f_1x100.png Binary files differindex 54aff0cb974..54aff0cb974 100644 --- a/css/images/ui-bg_highlight-soft_25_ffef8f_1x100.png +++ b/core/css/images/ui-bg_highlight-soft_25_ffef8f_1x100.png diff --git a/css/images/ui-icons_2694e8_256x240.png b/core/css/images/ui-icons_2694e8_256x240.png Binary files differindex 9d192c2f659..9d192c2f659 100644 --- a/css/images/ui-icons_2694e8_256x240.png +++ b/core/css/images/ui-icons_2694e8_256x240.png diff --git a/css/images/ui-icons_2e83ff_256x240.png b/core/css/images/ui-icons_2e83ff_256x240.png Binary files differindex 09d1cdc856c..09d1cdc856c 100644 --- a/css/images/ui-icons_2e83ff_256x240.png +++ b/core/css/images/ui-icons_2e83ff_256x240.png diff --git a/css/images/ui-icons_3d80b3_256x240.png b/core/css/images/ui-icons_3d80b3_256x240.png Binary files differindex f13b206645b..f13b206645b 100644 --- a/css/images/ui-icons_3d80b3_256x240.png +++ b/core/css/images/ui-icons_3d80b3_256x240.png diff --git a/css/images/ui-icons_72a7cf_256x240.png b/core/css/images/ui-icons_72a7cf_256x240.png Binary files differindex 0d20b730833..0d20b730833 100644 --- a/css/images/ui-icons_72a7cf_256x240.png +++ b/core/css/images/ui-icons_72a7cf_256x240.png diff --git a/css/images/ui-icons_ffffff_256x240.png b/core/css/images/ui-icons_ffffff_256x240.png Binary files differindex 42f8f992c72..42f8f992c72 100644 --- a/css/images/ui-icons_ffffff_256x240.png +++ b/core/css/images/ui-icons_ffffff_256x240.png diff --git a/css/jquery-ui-1.8.10.custom.css b/core/css/jquery-ui-1.8.10.custom.css index 1f376ca99d3..1f376ca99d3 100644 --- a/css/jquery-ui-1.8.10.custom.css +++ b/core/css/jquery-ui-1.8.10.custom.css diff --git a/css/styles.css b/core/css/styles.css index 2790c5c0492..5027a6b6fe9 100644 --- a/css/styles.css +++ b/core/css/styles.css @@ -269,6 +269,7 @@ p.actions a.delete, div.actions a.delete { background-image:url('../img/delete.p #logs_options span { margin:0 2em 0 0.5em; font-weight:bold; } #logs_options label { margin:0 1em 0 0; } #logs_options input[type="submit"] { float:right; margin:0 2em 0 0; } +#logs_options input[type="submit"].nofloat { float:none; margin:0 2em 0 0; } #logs_options input[type="text"] { margin:0; padding:0; border:1px solid #ccc; text-align:right; } li.error{ list-style:none; width:640px; margin:4em auto; padding:1em 1em 1em 4em; background-color:#fee; background-image:url('../img/task-attention.png'); background-position:0.8em 0.8em; background-repeat:no-repeat; border:1px solid #ccc; -moz-border-radius:10px; -webkit-border-radius:10px; border-radius:10px; } diff --git a/img/actions/arrow-down.png b/core/img/actions/arrow-down.png Binary files differindex 03f201428ad..03f201428ad 100644 --- a/img/actions/arrow-down.png +++ b/core/img/actions/arrow-down.png diff --git a/img/actions/arrow-left.png b/core/img/actions/arrow-left.png Binary files differindex b56cfee03df..b56cfee03df 100644 --- a/img/actions/arrow-left.png +++ b/core/img/actions/arrow-left.png diff --git a/img/actions/arrow-right.png b/core/img/actions/arrow-right.png Binary files differindex 0acee70bcdd..0acee70bcdd 100644 --- a/img/actions/arrow-right.png +++ b/core/img/actions/arrow-right.png diff --git a/img/actions/arrow-up.png b/core/img/actions/arrow-up.png Binary files differindex 5e423213fbd..5e423213fbd 100644 --- a/img/actions/arrow-up.png +++ b/core/img/actions/arrow-up.png diff --git a/img/actions/go-home.png b/core/img/actions/go-home.png Binary files differindex 3802c98fc46..3802c98fc46 100644 --- a/img/actions/go-home.png +++ b/core/img/actions/go-home.png diff --git a/img/body_background.jpg b/core/img/body_background.jpg Binary files differindex c3d0102f711..c3d0102f711 100644 --- a/img/body_background.jpg +++ b/core/img/body_background.jpg diff --git a/img/drop-arrow.png b/core/img/drop-arrow.png Binary files differindex 315395d5d42..315395d5d42 100644 --- a/img/drop-arrow.png +++ b/core/img/drop-arrow.png diff --git a/img/favicon-touch.png b/core/img/favicon-touch.png Binary files differindex 20af826523c..20af826523c 100644 --- a/img/favicon-touch.png +++ b/core/img/favicon-touch.png diff --git a/img/favicon.png b/core/img/favicon.png Binary files differindex a7ee766dfa8..a7ee766dfa8 100644 --- a/img/favicon.png +++ b/core/img/favicon.png diff --git a/img/header-a.png b/core/img/header-a.png Binary files differindex 46fb0977ee2..46fb0977ee2 100644 --- a/img/header-a.png +++ b/core/img/header-a.png diff --git a/img/header-login.png b/core/img/header-login.png Binary files differindex b0160e02d1f..b0160e02d1f 100644 --- a/img/header-login.png +++ b/core/img/header-login.png diff --git a/img/header-settings-a.png b/core/img/header-settings-a.png Binary files differindex a72271be6a4..a72271be6a4 100644 --- a/img/header-settings-a.png +++ b/core/img/header-settings-a.png diff --git a/img/header-settings.png b/core/img/header-settings.png Binary files differindex 7e6b70b5903..7e6b70b5903 100644 --- a/img/header-settings.png +++ b/core/img/header-settings.png diff --git a/img/header.png b/core/img/header.png Binary files differindex d377f65186d..d377f65186d 100644 --- a/img/header.png +++ b/core/img/header.png diff --git a/img/layout/back.png b/core/img/layout/back.png Binary files differindex 86abbe0cabe..86abbe0cabe 100644 --- a/img/layout/back.png +++ b/core/img/layout/back.png diff --git a/img/layout/logout.png b/core/img/layout/logout.png Binary files differindex 74dcd33bee7..74dcd33bee7 100644 --- a/img/layout/logout.png +++ b/core/img/layout/logout.png diff --git a/img/layout/settings.png b/core/img/layout/settings.png Binary files differindex ff650ecb0b0..ff650ecb0b0 100644 --- a/img/layout/settings.png +++ b/core/img/layout/settings.png diff --git a/img/mimetypes/file.png b/core/img/mimetypes/file.png Binary files differindex 49790448897..49790448897 100644 --- a/img/mimetypes/file.png +++ b/core/img/mimetypes/file.png diff --git a/img/owncloud-logo-medium-white.png b/core/img/owncloud-logo-medium-white.png Binary files differindex d4d06fdd62d..d4d06fdd62d 100644 --- a/img/owncloud-logo-medium-white.png +++ b/core/img/owncloud-logo-medium-white.png diff --git a/img/owncloud-logo-small-white.png b/core/img/owncloud-logo-small-white.png Binary files differindex 397ddf91341..397ddf91341 100644 --- a/img/owncloud-logo-small-white.png +++ b/core/img/owncloud-logo-small-white.png diff --git a/img/places/folder.png b/core/img/places/folder.png Binary files differindex 3edbe257a34..3edbe257a34 100644 --- a/img/places/folder.png +++ b/core/img/places/folder.png diff --git a/img/weather-clear.png b/core/img/weather-clear.png Binary files differindex 0acf7a9b2af..0acf7a9b2af 100644 --- a/img/weather-clear.png +++ b/core/img/weather-clear.png diff --git a/js/jquery-1.5.min.js b/core/js/jquery-1.5.min.js index 9144b8ae98c..9144b8ae98c 100644 --- a/js/jquery-1.5.min.js +++ b/core/js/jquery-1.5.min.js diff --git a/js/jquery-ui-1.8.10.custom.min.js b/core/js/jquery-ui-1.8.10.custom.min.js index 7d4ff1cec10..7d4ff1cec10 100644 --- a/js/jquery-ui-1.8.10.custom.min.js +++ b/core/js/jquery-ui-1.8.10.custom.min.js diff --git a/core/js/js.js b/core/js/js.js new file mode 100644 index 00000000000..9a14cb8ed4f --- /dev/null +++ b/core/js/js.js @@ -0,0 +1,23 @@ +var _l10ncache = {}; +function t(app,text){ + if( !( app in _l10ncache )){ + $.post( oc_webroot+'/core/ajax/translations.php', {'app': app}, function(jsondata){ + _l10ncache[app] = jsondata.data; + }); + + // Bad answer ... + if( !( app in _l10ncache )){ + _l10ncache[app] = []; + } + } + if( typeof( _l10ncache[app][text] ) !== 'undefined' ){ + return _l10ncache[app][text]; + } + else{ + return text; + } +} + +$(document).ready(function(){ + // Put fancy stuff in here +}); diff --git a/js/js.js b/core/js/setup.js index a6765ec62db..b4616b8b14c 100644 --- a/js/js.js +++ b/core/js/setup.js @@ -1,22 +1,22 @@ -$(document).ready(function() { +$(document).ready(function() { // Hide the MySQL config div if needed : if(!$('#mysql').is(':checked') && $('#hasSQLite').val()=='true') { $('#use_mysql').hide(); } - + $('#datadirField').hide(250); if($('#hasSQLite').val()=='true'){ $('#databaseField').hide(250); } - + $('#sqlite').click(function() { $('#use_mysql').slideUp(250); }); - + $('#mysql').click(function() { $('#use_mysql').slideDown(250); }); - + $('#showAdvanced').click(function() { $('#datadirField').slideToggle(250); if($('#hasSQLite').val()=='true'){ diff --git a/core/l10n/da.php b/core/l10n/da.php new file mode 100644 index 00000000000..631201bab60 --- /dev/null +++ b/core/l10n/da.php @@ -0,0 +1,27 @@ +<?php $TRANSLATIONS = array( +"Error 404, Cloud not found" => "Fejl 404, Skyen kan ikke findes", +"Welcome to <strong>ownCloud</strong>, your personnal cloud." => "Velkommen til <strong>ownCloud</strong>, din personlige Sky.", +"To finish the installation, please follow the steps below." => "For at fuldføre installationen, følg venligst nedenstående trin", +"Create an <strong>admin account.</strong>" => "Lav en <strong>administrator konto.</strong>", +"Login:" => "Login:", +"Password:" => "Kodeord:", +"Advanced" => "Avanceret", +"Set where to store the data." => "Indstil data mappe.", +"Data directory:" => "Data mappe:", +"Configure your database." => "Konfigurer din database.", +"I will use a SQLite database. You have nothing to do!" => "Jeg vil benytte en SQLite database. Du skal ikke gøre noget!", +"SQLite" => "SQLite", +"I will use a MySQL database." => "Jeg vil benytte en MySQL database.", +"Host:" => "Host:", +"Database name:" => "Database navn:", +"Table prefix:" => "Tabel prefix:", +"MySQL user login:" => "MySQL bruger login:", +"MySQL user password:" => "MySQL bruger password:", +"Finish setup" => "Afslut installation", +"<a href=\"http://owncloud.org/\">ownCloud</a> is a personal cloud which runs on your own server.</p>" => "<a href=\"http://owncloud.org/\">ownCloud</a> er din personly sky der køre på din egen server.</p>", +"Login failed!" => "Login mislykkedes", +"You are logged out." => "Du er nu logget ud", +"prev" => "forrige", +"next" => "næste", +"Search" => "Søg" +); diff --git a/core/l10n/de.php b/core/l10n/de.php new file mode 100644 index 00000000000..b1309beed06 --- /dev/null +++ b/core/l10n/de.php @@ -0,0 +1,27 @@ +<?php $TRANSLATIONS = array( +"Error 404, Cloud not found" => "Cloud konnte nicht gefunden werden.", +"Welcome to <strong>ownCloud</strong>, your personnal cloud." => "Willkommen bei <strong>ownCloud</strong>, deinem persönlichen Online-Speicher.", +"To finish the installation, please follow the steps below." => "Die Installation ist fast abgeschlossen.", +"Create an <strong>admin account.</strong>" => "<strong>Verwaltungskonto</strong> erstellen.", +"Login:" => "Benutzername:", +"Password:" => "Passwort:", +"Advanced" => "Erweitert", +"Set where to store the data." => "Speicherort der Daten", +"Data directory:" => "Datenverzeichnis:", +"Configure your database." => "Datenbank einstellen.", +"I will use a SQLite database. You have nothing to do!" => "Es wird eine SQLite-Datenbank genutzt.", +"SQLite" => "SQLite", +"I will use a MySQL database." => "Es wird eine MySQL-Datenbank genutzt.", +"Host:" => "Host:", +"Database name:" => "Datenbankname:", +"Table prefix:" => "Tabellenpräfix:", +"MySQL user login:" => "MySQL-Nutzername:", +"MySQL user password:" => "MySQL-Passwort:", +"<a href=\"http://owncloud.org/\">ownCloud</a> is a personal cloud which runs on your own server.</p>" => "<a href=\"http://owncloud.org/\">ownCloud</a> ist ein privater Online-Speicher für deinen eigenen Server.</p>", +"Login failed!" => "Anmeldung Fehlgeschlagen!", +"You are logged out." => "Sie wurden abgemeldet.", +"prev" => "zurück", +"next" => "weiter", +"Search" => "Suchen", +"Finish setup" => "Installation abschließen" +); diff --git a/core/l10n/l10n-de.php b/core/l10n/l10n-de.php new file mode 100644 index 00000000000..f3084b05df8 --- /dev/null +++ b/core/l10n/l10n-de.php @@ -0,0 +1,5 @@ +<?php +$LOCALIZATIONS = array( + 'date' => 'd.m.Y', + 'datetime' => 'd.m.Y H:i:s', + 'time' => 'H:i:s' ); diff --git a/core/l10n/nl.php b/core/l10n/nl.php new file mode 100644 index 00000000000..66d96505971 --- /dev/null +++ b/core/l10n/nl.php @@ -0,0 +1,27 @@ +<?php $TRANSLATIONS = array( +"Error 404, Cloud not found" => "Fout 404, Cloud niet gevonden.", +"Welcome to <strong>ownCloud</strong>, your personnal cloud." => "Welkom by <strong>ownCloud</strong>, uw persoonlijke cloud", +"To finish the installation, please follow the steps below." => "Volg de volgende stappen om de installatie te voltooien.", +"Create an <strong>admin account.</strong>" => "Maak een <strong>beheerdersaccount</strong> aan", +"Login:" => "Gebruikersnaam:", +"Password:" => "Wachtwoord:", +"Advanced" => "Geavanceerd", +"Set where to store the data." => "Bepaal de opslaglocatie.", +"Data directory:" => "Gegevensmap:", +"Configure your database." => "Configureer uw database.", +"I will use a SQLite database. You have nothing to do!" => "Er zal een SQLite database gebruikt worden. U hoeft geen verdere instellingen te maken.", +"SQLite" => "SQLite", +"I will use a MySQL database." => "Er zal een MySQL database gebruikt worden.", +"Host:" => "Host:", +"Database name:" => "Databasenaam:", +"Table prefix:" => "Voorvoegsel voor tabelnamen:", +"MySQL user login:" => "MySQL gebruikersnaam.", +"MySQL user password:" => "MySQL wachtwoord", +"Finish setup" => "Installatie afronden", +"<a href=\"http://owncloud.org/\">ownCloud</a> is a personal cloud which runs on your own server.</p>" => "<a href=\"http://owncloud.org/\">ownCloud</a> is een persoonlijke cloud die op uw eigen server draait.</p>", +"Login failed!" => "Aanmelden mislukt.", +"You are logged out." => "U bent afgemeld.", +"prev" => "vorige", +"next" => "volgende", +"Search" => "Zoeken" +); diff --git a/core/l10n/pl.php b/core/l10n/pl.php new file mode 100644 index 00000000000..6914e11557a --- /dev/null +++ b/core/l10n/pl.php @@ -0,0 +1,27 @@ +<?php $TRANSLATIONS = array( +"Error 404, Cloud not found" => "Błąd 404, Chmura nie znaleziona", +"Welcome to <strong>ownCloud</strong>, your personnal cloud." => "Witaj w <strong>ownCloud</strong>, Twojej osobistej chmurze.", +"To finish the installation, please follow the steps below." => "By zakończyć instalację, podążaj poniższymi krokami.", +"Create an <strong>admin account.</strong>" => "Utwórz <strong>konto administratora</strong>.", +"Login:" => "Login:", +"Password:" => "Hasło:", +"Advanced" => "Zaawansowane", +"Set where to store the data." => "Ustaw, gdzie przechowywać dane.", +"Data directory:" => "Katalog danych:", +"Configure your database." => "Skonfiguruj Twoją bazę danych.", +"I will use a SQLite database. You have nothing to do!" => "Użyję bazy SQLite. Nie masz tu nic do roboty!", +"SQLite" => "SQLite", +"I will use a MySQL database." => "Użyję bazy danych MySQL.", +"Host:" => "Host:", +"Database name:" => "Nazwa bazy:", +"Table prefix:" => "Przedrostek tabeli:", +"MySQL user login:" => "Login użytkownika MySQL:", +"MySQL user password:" => "Hasło użytkownika MySQL:", +"Finish setup" => "Zakończ instalację", +"<a href=\"http://owncloud.org/\">ownCloud</a> is a personal cloud which runs on your own server.</p>" => "<a href=\"http://owncloud.org/\">ownCloud</a> jest osobistą chmurą działającą na Twoim własnym serwerze.</p>", +"Login failed!" => "Nie udało się zalogować!", +"You are logged out." => "Jesteś wylogowany.", +"prev" => "wstecz", +"next" => "dalej", +"Search" => "Szukaj" +); diff --git a/core/l10n/xgettextfiles b/core/l10n/xgettextfiles new file mode 100644 index 00000000000..b5d83a880d4 --- /dev/null +++ b/core/l10n/xgettextfiles @@ -0,0 +1,7 @@ +../templates/404.php +../templates/installation.php +../templates/layout.guest.php +../templates/login.php +../templates/logout.php +../templates/part.pagenavi.php +../templates/part.searchbox.php diff --git a/templates/404.php b/core/templates/404.php index 8909db29a40..b78828e6301 100644 --- a/templates/404.php +++ b/core/templates/404.php @@ -1,6 +1,6 @@ <?php if(!isset($_)){//also provide standalone error page - require_once '../lib/base.php'; + require_once '../../lib/base.php'; require( 'template.php' ); $tmpl = new OC_TEMPLATE( '', '404', 'guest' ); @@ -12,7 +12,7 @@ if(!isset($_)){//also provide standalone error page <img src="<?php echo image_path("", "weather-clear.png"); ?>" alt="ownCloud" /> <ul> <li class='error'> - Error 404, Cloud not found<br/> + <?php echo $l->t( 'Error 404, Cloud not found' ); ?><br/> <p class='hint'><?php if(isset($_['file'])) echo $_['file']?></p> </li> </ul> diff --git a/templates/error.php b/core/templates/error.php index ae3f029708f..ae3f029708f 100644 --- a/templates/error.php +++ b/core/templates/error.php diff --git a/core/templates/installation.php b/core/templates/installation.php new file mode 100644 index 00000000000..93c00547ab9 --- /dev/null +++ b/core/templates/installation.php @@ -0,0 +1,70 @@ +<div id="login"> + <img src="<?php echo image_path('', 'owncloud-logo-medium-white.png'); ?>" alt="ownCloud" /> + <form action="index.php" method="post" id="setup_form"> + <input type="hidden" name="install" value="true" /> + <p class="intro"> + <?php echo $l->t( 'Welcome to <strong>ownCloud</strong>, your personnal cloud.' ); ?><br /> + <?php echo $l->t( 'To finish the installation, please follow the steps below.' ); ?> + </p> + + <?php if(count($_['errors']) > 0): ?> + <ul class="errors"> + <?php foreach($_['errors'] as $err): ?> + <li> + <?php if(is_array($err)):?> + <?php print $err['error']; ?> + <p class='hint'><?php print $err['hint']; ?></p> + <?php else: ?> + <?php print $err; ?> + <?php endif; ?> + </li> + <?php endforeach; ?> + </ul> + <?php endif; ?> + + <fieldset> + <legend><?php echo $l->t( 'Create an <strong>admin account.</strong>' ); ?></legend> + <p><label for="adminlogin"><?php echo $l->t( 'Login:' ); ?></label><input type="text" name="adminlogin" id="adminlogin" value="<?php print OC_HELPER::init_var('adminlogin'); ?>" /></p> + <p><label for="adminpass"><?php echo $l->t( 'Password:' ); ?></label><input type="password" name="adminpass" id="adminpass" value="<?php print OC_HELPER::init_var('adminpass'); ?>" /></p> + </fieldset> + + <a id='showAdvanced'><?php echo $l->t( 'Advanced' ); ?> <img src='<?php echo OC_HELPER::imagePath('','drop-arrow.png'); ?>'></img></a> + + <fieldset id='datadirField'> + <legend><?php echo $l->t( 'Set where to store the data.' ); ?></legend> + <p><label for="directory"><?php echo $l->t( 'Data directory:' ); ?></label><input type="text" name="directory" id="directory" value="<?php print OC_HELPER::init_var('directory', $_['directory']); ?>" /></p> + </fieldset> + + <fieldset id='databaseField'> + <legend><?php echo $l->t( 'Configure your database.' ); ?></legend> + <?php if($_['hasSQLite']): ?> + <input type='hidden' id='hasSQLite' value='true'/> + <?php if(!$_['hasMySQL']): ?> + <p><?php echo $l->t( 'I will use a SQLite database. You have nothing to do!' ); ?></p> + <input type="hidden" id="dbtype" name="dbtype" value="sqlite" /> + <?php else: ?> + <p><label class="sqlite" for="sqlite"><?php echo $l->t( 'SQLite' ); ?></label><input type="radio" name="dbtype" value='sqlite' id="sqlite" <?php OC_HELPER::init_radio('dbtype', 'sqlite', 'sqlite'); ?>/></p> + <?php endif; ?> + <?php endif; ?> + + <?php if($_['hasMySQL']): ?> + <input type='hidden' id='hasMySQL' value='true'/> + <?php if(!$_['hasSQLite']): ?> + <p><?php echo $l->t( 'I will use a MySQL database.' ); ?></p> + <input type="hidden" id="dbtype" name="dbtype" value="mysql" /> + <?php else: ?> + <p><label class="mysql" for="mysql">MySQL </label><input type="radio" name="dbtype" value='mysql' id="mysql" <?php OC_HELPER::init_radio('dbtype', 'mysql', 'sqlite'); ?>/></p> + <?php endif; ?> + <div id="use_mysql"> + <p><label for="dbhost"><?php echo $l->t( 'Host:' ); ?></label><input type="text" name="dbhost" id="dbhost" value="<?php print OC_HELPER::init_var('dbhost', 'localhost'); ?>" /></p> + <p><label for="dbname"><?php echo $l->t( 'Database name:' ); ?></label><input type="text" name="dbname" id="dbname" value="<?php print OC_HELPER::init_var('dbname'); ?>" /></p> + <p><label for="dbtableprefix"><?php echo $l->t( 'Table prefix:' ); ?></label><input type="text" name="dbtableprefix" id="dbtableprefix" value="<?php print OC_HELPER::init_var('dbtableprefix', 'oc_'); ?>" /></p> + <p><label for="dbuser"><?php echo $l->t( 'MySQL user login:' ); ?></label><input type="text" name="dbuser" id="dbuser" value="<?php print OC_HELPER::init_var('dbuser'); ?>" /></p> + <p><label for="dbpass"><?php echo $l->t( 'MySQL user password:' ); ?></label><input type="password" name="dbpass" id="dbpass" value="<?php print OC_HELPER::init_var('dbpass'); ?>" /></p> + </div> + <?php endif; ?> + </fieldset> + + <p class="submit"><input type="submit" value="<?php echo $l->t( 'Finish setup' ); ?>" /></p> + </form> +</div> diff --git a/templates/layout.admin.php b/core/templates/layout.admin.php index 541427f5d5e..8668aa64fda 100644 --- a/templates/layout.admin.php +++ b/core/templates/layout.admin.php @@ -7,9 +7,24 @@ <?php foreach($_['cssfiles'] as $cssfile): ?> <link rel="stylesheet" href="<?php echo $cssfile; ?>" type="text/css" media="screen" /> <?php endforeach; ?> + <script type="text/javascript"> + var oc_webroot = '<?php global $WEBROOT; echo $WEBROOT; ?>'; + // </script> <?php foreach($_['jsfiles'] as $jsfile): ?> <script type="text/javascript" src="<?php echo $jsfile; ?>"></script> <?php endforeach; ?> + <?php foreach($_['headers'] as $header): ?> + <?php + echo '<'.$header['tag'].' '; + foreach($header['attributes'] as $name=>$value){ + echo "$name='$value' "; + }; + echo '>'; + echo $header['text']; + echo '</'.$header['tag'].'>'; + ?> + <script type="text/javascript" src="<?php echo $jsfile; ?>"></script> + <?php endforeach; ?> </head> <body id="body-settings"> @@ -29,18 +44,20 @@ <li><a style="background-image:url(<?php echo $entry['icon']; ?>)" href="<?php echo $entry['href']; ?>" title="" <?php if( $entry["active"] ): ?> class="active"<?php endif; ?>><?php echo $entry['name'] ?></a></li> <?php if( sizeof( $entry["subnavigation"] )): ?> <?php foreach($entry["subnavigation"] as $subentry):?> - <li><a style="background-color:#FF8800;" href="<?php echo $subentry['href']; ?>" title=""><?php echo $subentry['name'] ?></a></li> - <?php endforeach; ?> - <?php endif; ?> - <?php endforeach; ?> - <?php foreach($_['adminnavigation'] as $entry):?> - <li><a style="background-image:url(<?php echo $entry['icon']; ?>)" href="<?php echo $entry['href']; ?>" title="" <?php if( $entry["active"] ): ?> class="active"<?php endif; ?>><?php echo $entry['name'] ?></a></li> - <?php if( sizeof( $entry["subnavigation"] )): ?> - <?php foreach($entry["subnavigation"] as $subentry):?> - <li><a style="background-color:#FF8800;" href="<?php echo $subentry['href']; ?>" title=""><?php echo $subentry['name'] ?></a></li> + <li><a style="background-color:#FF8800;" href="<?php echo $subentry['href']; ?>" title="" <?php if( $subentry["active"] ): ?> class="active"<?php endif; ?>><?php echo $subentry['name'] ?></a></li> <?php endforeach; ?> <?php endif; ?> <?php endforeach; ?> + <?php if(isset($_['adminnavigation'])):?> + <?php foreach($_['adminnavigation'] as $entry):?> + <li><a style="background-image:url(<?php echo $entry['icon']; ?>)" href="<?php echo $entry['href']; ?>" title="" <?php if( $entry["active"] ): ?> class="active"<?php endif; ?>><?php echo $entry['name'] ?></a></li> + <?php if( sizeof( $entry["subnavigation"] )): ?> + <?php foreach($entry["subnavigation"] as $subentry):?> + <li><a style="background-color:#FF8800;" href="<?php echo $subentry['href']; ?>" title=""><?php echo $subentry['name'] ?> <?php if( $subentry["active"] ): ?> active<?php endif; ?></a></li> + <?php endforeach; ?> + <?php endif; ?> + <?php endforeach; ?> + <?php endif; ?> </ul> </div> diff --git a/templates/layout.guest.php b/core/templates/layout.guest.php index c9575530820..5655a64d8da 100644 --- a/templates/layout.guest.php +++ b/core/templates/layout.guest.php @@ -7,13 +7,29 @@ <?php foreach($_['cssfiles'] as $cssfile): ?> <link rel="stylesheet" href="<?php echo $cssfile; ?>" type="text/css" media="screen" /> <?php endforeach; ?> + <script type="text/javascript"> + var oc_webroot = '<?php global $WEBROOT; echo $WEBROOT; ?>'; + // </script> <?php foreach($_['jsfiles'] as $jsfile): ?> <script type="text/javascript" src="<?php echo $jsfile; ?>"></script> <?php endforeach; ?> + + <?php foreach($_['headers'] as $header): ?> + <?php + echo '<'.$header['tag'].' '; + foreach($header['attributes'] as $name=>$value){ + echo "$name='$value' "; + }; + echo '>'; + echo $header['text']; + echo '</'.$header['tag'].'>'; + ?> + <script type="text/javascript" src="<?php echo $jsfile; ?>"></script> + <?php endforeach; ?> </head> <body id="body-login"> <?php echo $_['content']; ?> - <p class="info"><a href="http://owncloud.org/">ownCloud</a> is a personal cloud which runs on your own server.</p> + <p class="info"><?php echo $l->t( '<a href="http://owncloud.org/">ownCloud</a> is a personal cloud which runs on your own server.</p>' ); ?> </body> </html> diff --git a/templates/layout.user.php b/core/templates/layout.user.php index da30df294f2..2a9a817498d 100644 --- a/templates/layout.user.php +++ b/core/templates/layout.user.php @@ -7,9 +7,24 @@ <?php foreach($_['cssfiles'] as $cssfile): ?> <link rel="stylesheet" href="<?php echo $cssfile; ?>" type="text/css" media="screen" /> <?php endforeach; ?> + <script type="text/javascript"> + var oc_webroot = '<?php global $WEBROOT; echo $WEBROOT; ?>'; + // </script> <?php foreach($_['jsfiles'] as $jsfile): ?> <script type="text/javascript" src="<?php echo $jsfile; ?>"></script> <?php endforeach; ?> + <?php foreach($_['headers'] as $header): ?> + <?php + echo '<'.$header['tag'].' '; + foreach($header['attributes'] as $name=>$value){ + echo "$name='$value' "; + }; + echo '>'; + echo $header['text']; + echo '</'.$header['tag'].'>'; + ?> + <script type="text/javascript" src="<?php echo $jsfile; ?>"></script> + <?php endforeach; ?> </head> <body id="body-user"> diff --git a/templates/login.php b/core/templates/login.php index 845ae831a40..e0f6ce23e2e 100644 --- a/templates/login.php +++ b/core/templates/login.php @@ -3,7 +3,7 @@ <form action="index.php" method="post" id="login_form"> <fieldset> <?php if($_['error']): ?> - Login failed! + <?php echo $l->t( 'Login failed!' ); ?> <?php endif; ?> <input type="text" name="user" id="user" value="" /> <input type="password" name="password" id="password" value="" /> diff --git a/core/templates/logout.php b/core/templates/logout.php new file mode 100644 index 00000000000..8cbbdd9cc8d --- /dev/null +++ b/core/templates/logout.php @@ -0,0 +1 @@ +<?php echo $l->t( 'You are logged out.' ); ?>
\ No newline at end of file diff --git a/templates/part.pagenavi.php b/core/templates/part.pagenavi.php index d48d0cada32..0602b793882 100644 --- a/templates/part.pagenavi.php +++ b/core/templates/part.pagenavi.php @@ -3,7 +3,7 @@ <tr> <td width="1"> <?php if($_['page']>0):?> - <span class="pagerbutton1"><a href="<?php echo $_['url'].($_['page']-1);?>">prev</a> </span> + <span class="pagerbutton1"><a href="<?php echo $_['url'].($_['page']-1);?>"><?php echo $l->t( 'prev' ); ?></a> </span> <?php endif; ?> </td> <td> @@ -23,7 +23,7 @@ </td> <td width="1"> <?php if(($_['page']+1)<$_['pagecount']):?> - <span class="pagerbutton2"><a href="<?php echo $_['url'].($_['page']+1);?>">next</a></span> + <span class="pagerbutton2"><a href="<?php echo $_['url'].($_['page']+1);?>"><?php echo $l->t( 'next' ); ?></a></span> <?php endif; ?> </td> </tr> diff --git a/templates/part.searchbox.php b/core/templates/part.searchbox.php index 910af81ebb2..7465a7326ee 100644 --- a/templates/part.searchbox.php +++ b/core/templates/part.searchbox.php @@ -1,4 +1,4 @@ <form class='searchbox' action='<?php echo $_['searchurl']?>' method='post'> <input name='query' value='<?php if(isset($_POST['query'])){echo $_POST['query'];};?>'/> - <input type='submit' value='Search' class='prettybutton'/> + <input type='submit' value='<?php echo $l->t( 'Search' ); ?>' class='prettybutton'/> </form>
\ No newline at end of file diff --git a/db_structure.xml b/db_structure.xml index 599352c2a8d..19cdccef8a4 100644 --- a/db_structure.xml +++ b/db_structure.xml @@ -208,7 +208,7 @@ </field> <index> - <name>path</name> + <name>locks_path</name> <field> <name>path</name> <sorting>ascending</sorting> @@ -216,7 +216,7 @@ </index> <index> - <name>path_2</name> + <name>locks_path_2</name> <field> <name>path</name> <sorting>ascending</sorting> @@ -224,7 +224,7 @@ </index> <index> - <name>path_3</name> + <name>locks_path_3</name> <field> <name>path</name> <sorting>ascending</sorting> @@ -236,7 +236,7 @@ </index> <index> - <name>expires</name> + <name>locks_expires</name> <field> <name>expires</name> <sorting>ascending</sorting> @@ -253,7 +253,7 @@ </index> <index> - <name>token</name> + <name>locks_token</name> <unique>true</unique> <field> <name>token</name> diff --git a/docs/createtranslation.pl b/docs/createtranslation.pl new file mode 100644 index 00000000000..12ba22a5ea4 --- /dev/null +++ b/docs/createtranslation.pl @@ -0,0 +1,29 @@ +#!/usr/bin/perl +use strict; +use Locale::PO; +use Data::Dumper; + +opendir( DIR, '.' ); +my @files = readdir( DIR ); +closedir( DIR ); + +foreach my $i ( @files ){ + next unless $i =~ m/^(.*)\.po$/; + my $lang = $1; + my $hash = Locale::PO->load_file_ashash( $i ); + + # Create array + my @strings = (); + foreach my $key ( keys( %{$hash} )){ + next if $key eq '""'; + next if $hash->{$key}->msgstr() eq '""'; + push( @strings, $hash->{$key}->msgid()." => ".$hash->{$key}->msgstr()); + } + + # Write PHP file + open( OUT, ">$lang.php" ); + print OUT "<?php \$TRANSLATIONS = array(\n"; + print OUT join( ",\n", @strings ); + print OUT "\n);\n"; + close( OUT ); +}
\ No newline at end of file diff --git a/docs/getstrings.pl b/docs/getstrings.pl new file mode 100644 index 00000000000..0325438b551 --- /dev/null +++ b/docs/getstrings.pl @@ -0,0 +1,18 @@ +#!/usr/bin/perl +use strict; + +if( -e 'messages.pot' ){ + `xgettext --files-from=xgettextfiles --join-existing --output=messages.pot --keyword=t` +} +else{ + `xgettext --files-from=xgettextfiles --output=messages.pot --keyword=t` +} + +opendir( DIR, '.' ); +my @files = readdir( DIR ); +closedir( DIR ); + +foreach my $i ( @files ){ + next unless $i =~ m/^(.*)\.po$/; + `xgettext --files-from=xgettextfiles --join-existing --output=$i --keyword=t` +} diff --git a/files/admin.php b/files/admin.php index 59b822468ed..5c9923aff86 100644 --- a/files/admin.php +++ b/files/admin.php @@ -28,7 +28,7 @@ require( 'template.php' ); // Check if we are a user -if( !OC_USER::isLoggedIn() || !OC_GROUP::inGroup( $_SESSION['user_id'], 'admin' )){ +if( !OC_USER::isLoggedIn() || !OC_GROUP::inGroup( OC_USER::getUser(), 'admin' )){ header( "Location: ".OC_HELPER::linkTo( "index.php" )); exit(); } diff --git a/files/appinfo/app.php b/files/appinfo/app.php index bf67812cf38..06ca16e82d4 100644 --- a/files/appinfo/app.php +++ b/files/appinfo/app.php @@ -3,7 +3,7 @@ OC_APP::register( array( "order" => 2, "id" => "files", "name" => "Files" )); OC_APP::addNavigationEntry( array( "id" => "files_index", "order" => 1, "href" => OC_HELPER::linkTo( "files", "index.php" ), "icon" => OC_HELPER::imagePath( "files", "home.png" ), "name" => "Files" )); -OC_APP::addSettingsPage( array( "id" => "files_administration", "order" => 1, "href" => OC_HELPER::linkTo( "files", "admin.php" ), "name" => "Files", "icon" => OC_HELPER::imagePath( "files", "folder.png" ))); +OC_APP::addAdminPage( array( "id" => "files_administration", "order" => 3, "href" => OC_HELPER::linkTo( "files", "admin.php" ), "name" => "Files", "icon" => OC_HELPER::imagePath( "files", "folder.png" ))); // To add navigation sub entries use diff --git a/files/css/files.css b/files/css/files.css index 7c7965ab847..702ddefc19c 100644 --- a/files/css/files.css +++ b/files/css/files.css @@ -110,5 +110,5 @@ table td.filename a width:16px; display: -moz-inline-box; /* fallback for older firefox versions*/ display: inline-block; - background-image:url('../../img/drop-arrow.png'); + background-image:url('../img/drop-arrow.png'); }
\ No newline at end of file diff --git a/files/img/drop-arrow.png b/files/img/drop-arrow.png Binary files differnew file mode 100644 index 00000000000..315395d5d42 --- /dev/null +++ b/files/img/drop-arrow.png diff --git a/files/js/fileactions.js b/files/js/fileactions.js index dec1d1cfb04..1bdbc4ac0bb 100644 --- a/files/js/fileactions.js +++ b/files/js/fileactions.js @@ -8,7 +8,7 @@ FileActions={ FileActions.actions[mime][name]=action; }, setDefault:function(mime,name){ - FileActions.defaults[mime]=FileActions.actions[mime][name]; + FileActions.defaults[mime]=name; }, get:function(mime,type){ var actions={}; @@ -35,15 +35,18 @@ FileActions={ if(mime){ var mimePart=mime.substr(0,mime.indexOf('/')); } + var name=false; if(mime && FileActions.defaults[mime]){ - return FileActions.defaults[mime]; + name=FileActions.defaults[mime]; }else if(mime && FileActions.defaults[mimePart]){ - return FileActions.defaults[mimePart]; + name=FileActions.defaults[mimePart]; }else if(type && FileActions.defaults[type]){ - return FileActions.defaults[type]; + name=FileActions.defaults[type]; }else{ - return FileActions.defaults.all; + name=FileActions.defaults.all; } + var actions=this.get(mime,type); + return actions[name]; }, display:function(parent){ $('#file_menu ul').empty(); diff --git a/files/js/filelist.js b/files/js/filelist.js index 14cce8a3897..089a34581de 100644 --- a/files/js/filelist.js +++ b/files/js/filelist.js @@ -49,6 +49,10 @@ FileList={ } } } - $(fileElements[pos]).after(element); + if(fileElements.length){ + $(fileElements[pos]).after(element); + }else{ + $('#fileList').append(element); + } } -}
\ No newline at end of file +} diff --git a/files/js/files.js b/files/js/files.js index 0172ab1b1a9..45931b9bae3 100644 --- a/files/js/files.js +++ b/files/js/files.js @@ -51,7 +51,8 @@ $(document).ready(function() { } }); - $('#file_newfolder_submit').click(function() { + $('#file_newfolder_form').submit(function(event) { + event.preventDefault(); $.ajax({ url: 'ajax/newfolder.php', data: "dir="+$('#dir').val()+"&foldername="+$('#file_newfolder_name').val(), diff --git a/files/templates/admin.php b/files/templates/admin.php index f768931eb2f..4dde9c510c4 100644 --- a/files/templates/admin.php +++ b/files/templates/admin.php @@ -1,16 +1,26 @@ -<form action='#' method='post'> +<script type="text/javascript"> +function switchPublicFolder() +{ + var publicEnable = document.forms['filesForm'].elements['publicEnable'].checked; + var sharingaimGroup = document.forms['filesForm'].elements['sharingaim']; + for(i=0;i<sharingaimGroup.length;i++) { + sharingaimGroup[i].disabled = !publicEnable; + } +} +</script> +<form name="filesForm" action='#' method='post'> <?php if($_['htaccessWorking']):?> - Maximum upload size <input name='maxUploadSize' value='<?php echo $_['uploadMaxFilesize'] ?>'/><br/> + <label for="maxUploadSize"><?php echo $l->t( 'Maximum upload size' ); ?> </label><input name='maxUploadSize' id="maxUploadSize" value='<?php echo $_['uploadMaxFilesize'] ?>'/><br/> <?php endif;?> - <input type="checkbox" /> Allow public folders<br> + <input type="checkbox" name="publicEnable" id="publicEnable" onClick="switchPublicFolder()" /><label for="publicEnable"> <?php echo $l->t( 'Allow public folders' ); ?></label><br> - (if public is enabled)<br> - <input type="radio" name="sharingaim" checked="checked" /> separated from webdav storage<br> - <input type="radio" name="sharingaim" /> let the user decide<br> - <input type="radio" name="sharingaim" /> folder "/public" in webdav storage<br> - (endif)<br> + <div style="padding-left: 20px"> + <input type="radio" name="sharingaim" id="separated" checked="checked" /><label for="separated"> <?php echo $l->t( 'separated from webdav storage' ); ?></label><br> + <input type="radio" name="sharingaim" id="userdecide" /><label for="userdecide"> <?php echo $l->t( 'let the user decide' ); ?></label><br> + <input type="radio" name="sharingaim" id="inwebdav" /><label for="inwebdav"> <?php echo $l->t( 'folder "/public" in webdav storage' ); ?></label> + </div> - <input type="checkbox" /> Allow downloading shared files<br> - <input type="checkbox" /> Allow uploading in shared directory<br> + <input type="checkbox" id="downloadShared" /><label for="downloadShared"> <?php echo $l->t( 'Allow downloading shared files' ); ?></label><br> + <input type="checkbox" id="uploadShared" /><label for="uploadShared"> <?php echo $l->t( 'Allow uploading in shared directory' ); ?></label><br> <input type='submit' value='Save'/> </form> diff --git a/files/templates/index.php b/files/templates/index.php index 11cf0360e1e..6eaa380506d 100644 --- a/files/templates/index.php +++ b/files/templates/index.php @@ -13,11 +13,11 @@ </form> <form id="file_newfolder_form"> <input type="text" class="prettybutton" name="file_newfolder_name" id="file_newfolder_name" value="New Folder" /> - <input class="prettybutton" type="button" id="file_newfolder_submit" name="file_newfolder_submit" value="OK" /> + <input class="prettybutton" type="submit" id="file_newfolder_submit" name="file_newfolder_submit" value="OK" /> </form> - <a href="" title="" class="download">Download</a> - <a href="" title="" class="share">Share</a> - <a href="" title="" class="delete">Delete</a> + <a href="" title="" class="download"><?php echo $l->t( 'Download' ); ?></a> + <!--<a href="" title="" class="share"><?php echo $l->t( 'Share' ); ?></a>--> + <a href="" title="" class="delete"><?php echo $l->t( 'Delete' ); ?></a> </div> <div id="file_action_panel"> </div> @@ -31,9 +31,9 @@ <thead> <tr> <th><input type="checkbox" id="select_all" /></th> - <th>Name</th> - <th>Size</th> - <th>Modified</th> + <th><?php echo $l->t( 'Name' ); ?></th> + <th><?php echo $l->t( 'Size' ); ?></th> + <th><?php echo $l->t( 'Modified' ); ?></th> <th></th> </tr> </thead> diff --git a/help/l10n/da.php b/help/l10n/da.php new file mode 100644 index 00000000000..2b8120c0c38 --- /dev/null +++ b/help/l10n/da.php @@ -0,0 +1,4 @@ +<?php $TRANSLATIONS = array( +"Questions and Answers" => "Spørgsmål og Svar", +"ASK A QUESTION" => "STIL ET SPØRGSMÅL" +); diff --git a/help/l10n/de.php b/help/l10n/de.php new file mode 100644 index 00000000000..07c5d1bb771 --- /dev/null +++ b/help/l10n/de.php @@ -0,0 +1,4 @@ +<?php $TRANSLATIONS = array( +"Questions and Answers" => "Fragen & Antworten", +"ASK A QUESTION" => "Stell eine Frage" +); diff --git a/help/l10n/nl.php b/help/l10n/nl.php new file mode 100644 index 00000000000..11a28894c72 --- /dev/null +++ b/help/l10n/nl.php @@ -0,0 +1,4 @@ +<?php $TRANSLATIONS = array( +"Questions and Answers" => "Vraag en Antwoord", +"ASK A QUESTION" => "Stel een vraag" +); diff --git a/help/l10n/pl.php b/help/l10n/pl.php new file mode 100644 index 00000000000..7d37913d037 --- /dev/null +++ b/help/l10n/pl.php @@ -0,0 +1,4 @@ +<?php $TRANSLATIONS = array( +"Questions and Answers" => "Pytania i odpowiedzi", +"ASK A QUESTION" => "ZADAJ PYTANIE" +); diff --git a/help/l10n/xgettextfiles b/help/l10n/xgettextfiles new file mode 100644 index 00000000000..a24bcc89a85 --- /dev/null +++ b/help/l10n/xgettextfiles @@ -0,0 +1 @@ +../templates/index.php diff --git a/help/templates/index.php b/help/templates/index.php index a117c3d5fb4..ac7e12b757a 100644 --- a/help/templates/index.php +++ b/help/templates/index.php @@ -1,5 +1,5 @@ -<h1>Questions and Answers</h1> +<h1><?php echo $l->t( 'Questions and Answers' ); ?></h1> <table cellspacing="0" width="100%"> <tbody> @@ -18,6 +18,6 @@ $pageNavi=OC_UTIL::getPageNavi($_['pagecount'],$_['page'],$url); $pageNavi->printPage(); ?> -<a target="_blank" class="prettybutton" href="http://apps.owncloud.com/knowledgebase/editquestion.php?action=new">ASK A QUESTION</a> +<a target="_blank" class="prettybutton" href="http://apps.owncloud.com/knowledgebase/editquestion.php?action=new"><?php echo $l->t( 'ASK A QUESTION' ); ?></a> diff --git a/index.php b/index.php index f4d6f27a3c4..d1726676c66 100644 --- a/index.php +++ b/index.php @@ -27,6 +27,8 @@ require_once(dirname(__FILE__).'/lib/base.php'); require_once('appconfig.php'); require_once('template.php'); +OC_UTIL::addScript('setup'); + $not_installed = !OC_CONFIG::getValue('installed', false); $install_called = (isset($_POST['install']) AND $_POST['install']=='true'); @@ -45,7 +47,7 @@ elseif($not_installed OR $install_called) { elseif(OC_USER::isLoggedIn()) { if(isset($_GET["logout"]) and ($_GET["logout"])) { OC_USER::logout(); - header("Location: $WEBROOT"); + header("Location: ".$WEBROOT.'/'); exit(); } else { diff --git a/l10n/da/admin.po b/l10n/da/admin.po new file mode 100644 index 00000000000..be62e2cd3db --- /dev/null +++ b/l10n/da/admin.po @@ -0,0 +1,96 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2011-06-20 22:00+0200\n" +"PO-Revision-Date: 2011-06-21 15:08+0100\n" +"Last-Translator: Mikkel Bjerg Larsen <mikkelbjerglarsen@gmail.com>\n" +"Language-Team: LANGUAGE <LL@li.org>\n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../templates/app.php:22 +msgid "read more" +msgstr "læs mere" + +#: ../templates/app.php:24 +msgid "INSTALL" +msgstr "INSTALLER" + +#: ../templates/app_noconn.php:6 +#: ../templates/apps.php:6 +msgid "Apps Repository" +msgstr "Applikation arkiv" + +#: ../templates/app_noconn.php:7 +msgid "Cannot connect to apps repository" +msgstr "Kan ikke oprette forbindelse til applikations arkivet" + +#: ../templates/apps.php:13 +#: ../templates/users.php:6 +#: ../templates/users.php:20 +#: ../templates/users.php:50 +msgid "Name" +msgstr "Navn" + +#: ../templates/apps.php:14 +msgid "Modified" +msgstr "Ændret" + +#: ../templates/system.php:6 +msgid "Administration" +msgstr "Administration" + +#: ../templates/system.php:7 +msgid "System Settings" +msgstr "System indstillinger" + +#: ../templates/users.php:13 +msgid "Add user" +msgstr "Tilføj bruger" + +#: ../templates/users.php:21 +msgid "Password" +msgstr "Kodeord" + +#: ../templates/users.php:30 +msgid "Create user" +msgstr "Lav bruger" + +#: ../templates/users.php:40 +#: ../templates/users.php:68 +msgid "remove" +msgstr "slet" + +#: ../templates/users.php:46 +#: ../templates/users.php:7 +msgid "Groups" +msgstr "Grupper" + +#: ../templates/users.php:58 +msgid "Create group" +msgstr "Lav gruppe" + +#: ../templates/users.php:94 +msgid "Force new password:" +msgstr "Tving ny adgangskode" + +#: ../templates/users.php:96 +msgid "Set" +msgstr "Indstil" + +#: ../templates/users.php:102 +msgid "Do you really want to delete user" +msgstr "Vil du virkelig slette denne bruger?" + +#: ../templates/users.php:109 +msgid "Do you really want to delete group" +msgstr "Vil du virkelig slette denne gruppe?" + diff --git a/l10n/da/core.po b/l10n/da/core.po new file mode 100644 index 00000000000..df83958287b --- /dev/null +++ b/l10n/da/core.po @@ -0,0 +1,118 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2011-06-20 22:00+0200\n" +"PO-Revision-Date: 2011-06-21 15:10+0100\n" +"Last-Translator: Mikkel Bjerg Larsen <mikkelbjerglarsen@gmail.com>\n" +"Language-Team: LANGUAGE <LL@li.org>\n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../templates/404.php:15 +msgid "Error 404, Cloud not found" +msgstr "Fejl 404, Skyen kan ikke findes" + +#: ../templates/installation.php:6 +msgid "Welcome to <strong>ownCloud</strong>, your personnal cloud." +msgstr "Velkommen til <strong>ownCloud</strong>, din personlige Sky." + +#: ../templates/installation.php:7 +msgid "To finish the installation, please follow the steps below." +msgstr "For at fuldføre installationen, følg venligst nedenstående trin" + +#: ../templates/installation.php:26 +msgid "Create an <strong>admin account.</strong>" +msgstr "Lav en <strong>administrator konto.</strong>" + +#: ../templates/installation.php:27 +msgid "Login:" +msgstr "Login:" + +#: ../templates/installation.php:28 +msgid "Password:" +msgstr "Kodeord:" + +#: ../templates/installation.php:31 +msgid "Advanced" +msgstr "Avanceret" + +#: ../templates/installation.php:34 +msgid "Set where to store the data." +msgstr "Indstil data mappe." + +#: ../templates/installation.php:35 +msgid "Data directory:" +msgstr "Data mappe:" + +#: ../templates/installation.php:39 +msgid "Configure your database." +msgstr "Konfigurer din database." + +#: ../templates/installation.php:43 +msgid "I will use a SQLite database. You have nothing to do!" +msgstr "Jeg vil benytte en SQLite database. Du skal ikke gøre noget!" + +#: ../templates/installation.php:46 +msgid "SQLite" +msgstr "SQLite" + +#: ../templates/installation.php:53 +msgid "I will use a MySQL database." +msgstr "Jeg vil benytte en MySQL database." + +#: ../templates/installation.php:59 +msgid "Host:" +msgstr "Host:" + +#: ../templates/installation.php:60 +msgid "Database name:" +msgstr "Database navn:" + +#: ../templates/installation.php:61 +msgid "Table prefix:" +msgstr "Tabel prefix:" + +#: ../templates/installation.php:62 +msgid "MySQL user login:" +msgstr "MySQL bruger login:" + +#: ../templates/installation.php:63 +msgid "MySQL user password:" +msgstr "MySQL bruger password:" + +#: ../templates/installation.php:68 +msgid "Finish setup" +msgstr "Afslut installation" + +#: ../templates/layout.guest.php:20 +msgid "<a href=\"http://owncloud.org/\">ownCloud</a> is a personal cloud which runs on your own server.</p>" +msgstr "<a href=\"http://owncloud.org/\">ownCloud</a> er din personly sky der køre på din egen server.</p>" + +#: ../templates/login.php:6 +msgid "Login failed!" +msgstr "Login mislykkedes" + +#: ../templates/logout.php:1 +msgid "You are logged out." +msgstr "Du er nu logget ud" + +#: ../templates/part.pagenavi.php:6 +msgid "prev" +msgstr "forrige" + +#: ../templates/part.pagenavi.php:26 +msgid "next" +msgstr "næste" + +#: ../templates/part.searchbox.php:3 +msgid "Search" +msgstr "Søg" + diff --git a/l10n/da/help.po b/l10n/da/help.po new file mode 100644 index 00000000000..d09d34e0aa8 --- /dev/null +++ b/l10n/da/help.po @@ -0,0 +1,26 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2011-06-20 22:00+0200\n" +"PO-Revision-Date: 2011-06-21 15:02+0100\n" +"Last-Translator: Mikkel Bjerg Larsen <mikkelbjerglarsen@gmail.com>\n" +"Language-Team: LANGUAGE <LL@li.org>\n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../templates/index.php:2 +msgid "Questions and Answers" +msgstr "Spørgsmål og Svar" + +#: ../templates/index.php:21 +msgid "ASK A QUESTION" +msgstr "STIL ET SPØRGSMÅL" + diff --git a/l10n/da/log.po b/l10n/da/log.po new file mode 100644 index 00000000000..4c81d97ea4b --- /dev/null +++ b/l10n/da/log.po @@ -0,0 +1,66 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2011-06-20 22:00+0200\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" +"Language-Team: LANGUAGE <LL@li.org>\n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../templates/index.php:4 +msgid "Filter:" +msgstr "Filter:" + +#: ../templates/index.php:7 +msgid "Logins" +msgstr "Logins" + +#: ../templates/index.php:8 +msgid "Logouts" +msgstr "Logouts" + +#: ../templates/index.php:9 +msgid "Downloads" +msgstr "Downloads" + +#: ../templates/index.php:10 +msgid "Uploads" +msgstr "Uploads" + +#: ../templates/index.php:11 +msgid "Creations" +msgstr "Oprettelser" + +#: ../templates/index.php:12 +msgid "Deletions" +msgstr "Sletninger" + +#: ../templates/index.php:15 +msgid "Show:" +msgstr "Vis:" + +#: ../templates/index.php:16 +msgid "entries per page." +msgstr "poster pr side." + +#: ../templates/index.php:26 +msgid "What" +msgstr "Hvilket" + +#: ../templates/index.php:27 +msgid "When" +msgstr "Hvornår" + +#: ../templates/index.php:45 +msgid "Clear log entries before" +msgstr "Slet log poster før" diff --git a/l10n/da/settings.po b/l10n/da/settings.po new file mode 100644 index 00000000000..c7981c921fb --- /dev/null +++ b/l10n/da/settings.po @@ -0,0 +1,87 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2011-06-20 22:00+0200\n" +"PO-Revision-Date: 2011-06-21 15:00+0100\n" +"Last-Translator: Mikkel Bjerg Larsen <mikkelbjerglarsen@gmail.com>\n" +"Language-Team: LANGUAGE <LL@li.org>\n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../templates/index.php:3 +msgid "Account information" +msgstr "Konto information" + +#: ../templates/index.php:5 +msgid "You're currently using" +msgstr "Du udnytter i øjeblikket" + +#: ../templates/index.php:5 +msgid "of your" +msgstr "af din" + +#: ../templates/index.php:5 +msgid "space" +msgstr "plads" + +#: ../templates/index.php:11 +msgid "Change Password" +msgstr "Ændre adgangskode" + +#: ../templates/index.php:12 +msgid "Your password got changed" +msgstr "Din adgangskode er ændret" + +#: ../templates/index.php:15 +msgid "Old password:" +msgstr "Gamle adgangskode" + +#: ../templates/index.php:19 +msgid "New password" +msgstr "Nye adgangskode" + +#: ../templates/index.php:24 +msgid "Show new password" +msgstr "Vis den nye adgangskode" + +#: ../templates/index.php:34 +msgid "Language" +msgstr "Sprog" + +#: ../ajax/changepassword.php:13 +#: ../ajax/setlanguage.php:13 +msgid "Authentication error" +msgstr "Godkendelsesfejl" + +#: ../ajax/changepassword.php:19 +msgid "You have to enter the old and the new password!" +msgstr "Du skal indtaste din gamle og nye adganskode" + +#: ../ajax/changepassword.php:25 +msgid "Your old password is wrong!" +msgstr "Din gamle adgangskode er forkert!" + +#: ../ajax/changepassword.php:31 +msgid "Password changed" +msgstr "Adgangskoden er ændret" + +#: ../ajax/changepassword.php:34 +msgid "Unable to change password" +msgstr "Kan ikke ændre din adgangskode" + +#: ../ajax/setlanguage.php:21 +msgid "Language changed" +msgstr "Sprog ændret" + +#: ../ajax/setlanguage.php:23 +msgid "Invalid request" +msgstr "Invalid forespørgsel" + diff --git a/l10n/de/admin.po b/l10n/de/admin.po new file mode 100644 index 00000000000..58db3b78e6d --- /dev/null +++ b/l10n/de/admin.po @@ -0,0 +1,91 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2011-06-20 22:00+0200\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" +"Language-Team: LANGUAGE <LL@li.org>\n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../templates/app.php:22 +msgid "read more" +msgstr "mehr …" + +#: ../templates/app.php:24 +msgid "INSTALL" +msgstr "Installieren" + +#: ../templates/app_noconn.php:6 ../templates/apps.php:6 +msgid "Apps Repository" +msgstr "Anwendungen" + +#: ../templates/app_noconn.php:7 +msgid "Cannot connect to apps repository" +msgstr "Verbindung fehlgeschlagen" + +#: ../templates/apps.php:13 ../templates/users.php:6 ../templates/users.php:20 +#: ../templates/users.php:50 +msgid "Name" +msgstr "Name" + +#: ../templates/apps.php:14 +msgid "Modified" +msgstr "Änderungsdatum" + +#: ../templates/system.php:6 +msgid "Administration" +msgstr "Verwaltung" + +#: ../templates/system.php:7 +msgid "System Settings" +msgstr "Systemeinstellungen" + +#: ../templates/users.php:7 ../templates/users.php:46 +msgid "Groups" +msgstr "Gruppen" + +#: ../templates/users.php:13 +msgid "Add user" +msgstr "Nutzer hinzufügen" + +#: ../templates/users.php:21 +msgid "Password" +msgstr "Passwort" + +#: ../templates/users.php:30 +msgid "Create user" +msgstr "Nutzer erstellen" + +#: ../templates/users.php:40 ../templates/users.php:68 +msgid "remove" +msgstr "entfernen" + +#: ../templates/users.php:58 +msgid "Create group" +msgstr "Gruppe erstellen" + +#: ../templates/users.php:94 +msgid "Force new password:" +msgstr "Neues Passwort:" + +#: ../templates/users.php:96 +msgid "Set" +msgstr "OK" + +#: ../templates/users.php:102 +msgid "Do you really want to delete user" +msgstr "Möchtest du den Nutzer wirklich entfernen?" + +#: ../templates/users.php:109 +msgid "Do you really want to delete group" +msgstr "Möchtest du die Gruppe wirklich entfernen?" diff --git a/l10n/de/core.po b/l10n/de/core.po new file mode 100644 index 00000000000..b78c7996190 --- /dev/null +++ b/l10n/de/core.po @@ -0,0 +1,122 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2011-06-20 22:00+0200\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" +"Language-Team: LANGUAGE <LL@li.org>\n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../templates/404.php:15 +msgid "Error 404, Cloud not found" +msgstr "Cloud konnte nicht gefunden werden." + +#: ../templates/installation.php:6 +msgid "Welcome to <strong>ownCloud</strong>, your personnal cloud." +msgstr "Willkommen bei <strong>ownCloud</strong>, deinem persönlichen Online-Speicher." + +#: ../templates/installation.php:7 +msgid "To finish the installation, please follow the steps below." +msgstr "Die Installation ist fast abgeschlossen." + +#: ../templates/installation.php:26 +msgid "Create an <strong>admin account.</strong>" +msgstr "<strong>Verwaltungskonto</strong> erstellen." + +#: ../templates/installation.php:27 +msgid "Login:" +msgstr "Benutzername:" + +#: ../templates/installation.php:28 +msgid "Password:" +msgstr "Passwort:" + +#: ../templates/installation.php:31 +msgid "Advanced" +msgstr "Erweitert" + +#: ../templates/installation.php:34 +msgid "Set where to store the data." +msgstr "Speicherort der Daten" + +#: ../templates/installation.php:35 +msgid "Data directory:" +msgstr "Datenverzeichnis:" + +#: ../templates/installation.php:39 +msgid "Configure your database." +msgstr "Datenbank einstellen." + +#: ../templates/installation.php:43 +msgid "I will use a SQLite database. You have nothing to do!" +msgstr "Es wird eine SQLite-Datenbank genutzt." + +#: ../templates/installation.php:46 +msgid "SQLite" +msgstr "SQLite" + +#: ../templates/installation.php:53 +msgid "I will use a MySQL database." +msgstr "Es wird eine MySQL-Datenbank genutzt." + +#: ../templates/installation.php:59 +msgid "Host:" +msgstr "Host:" + +#: ../templates/installation.php:60 +msgid "Database name:" +msgstr "Datenbankname:" + +#: ../templates/installation.php:61 +msgid "Table prefix:" +msgstr "Tabellenpräfix:" + +#: ../templates/installation.php:62 +msgid "MySQL user login:" +msgstr "MySQL-Nutzername:" + +#: ../templates/installation.php:63 +msgid "MySQL user password:" +msgstr "MySQL-Passwort:" + +#: ../templates/layout.guest.php:17 ../templates/layout.guest.php:20 +msgid "" +"<a href=\"http://owncloud.org/\">ownCloud</a> is a personal cloud which runs " +"on your own server.</p>" +msgstr "" +"<a href=\"http://owncloud.org/\">ownCloud</a> ist ein privater Online-Speicher " +"für deinen eigenen Server.</p>" + +#: ../templates/login.php:6 +msgid "Login failed!" +msgstr "Anmeldung Fehlgeschlagen!" + +#: ../templates/logout.php:1 +msgid "You are logged out." +msgstr "Sie wurden abgemeldet." + +#: ../templates/part.pagenavi.php:6 +msgid "prev" +msgstr "zurück" + +#: ../templates/part.pagenavi.php:26 +msgid "next" +msgstr "weiter" + +#: ../templates/part.searchbox.php:3 +msgid "Search" +msgstr "Suchen" + +#: ../templates/installation.php:68 +msgid "Finish setup" +msgstr "Installation abschließen" diff --git a/l10n/de/help.po b/l10n/de/help.po new file mode 100644 index 00000000000..37029fffc70 --- /dev/null +++ b/l10n/de/help.po @@ -0,0 +1,26 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2011-06-20 22:00+0200\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" +"Language-Team: LANGUAGE <LL@li.org>\n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../templates/index.php:2 +msgid "Questions and Answers" +msgstr "Fragen & Antworten" + +#: ../templates/index.php:21 +msgid "ASK A QUESTION" +msgstr "Stell eine Frage" diff --git a/l10n/de/log.po b/l10n/de/log.po new file mode 100644 index 00000000000..f552e1fd14c --- /dev/null +++ b/l10n/de/log.po @@ -0,0 +1,67 @@ +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# +# Jakob Sack <mail@jakobsack.de>, 2011. +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2011-06-20 22:00+0200\n" +"PO-Revision-Date: 2011-06-21 16:44+0200\n" +"Last-Translator: Jakob Sack <mail@jakobsack.de>\n" +"Language-Team: German <kde-i18n-de@kde.org>\n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 1.2\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#: ../templates/index.php:4 +msgid "Filter:" +msgstr "Filter:" + +#: ../templates/index.php:7 +msgid "Logins" +msgstr "Anmeldungen" + +#: ../templates/index.php:8 +msgid "Logouts" +msgstr "Abmeldungen" + +#: ../templates/index.php:9 +msgid "Downloads" +msgstr "Downloads" + +#: ../templates/index.php:10 +msgid "Uploads" +msgstr "Uploads" + +#: ../templates/index.php:11 +msgid "Creations" +msgstr "Erstellungen" + +#: ../templates/index.php:12 +msgid "Deletions" +msgstr "Löschungen" + +#: ../templates/index.php:15 +msgid "Show:" +msgstr "Zeige" + +#: ../templates/index.php:16 +msgid "entries per page." +msgstr "Einträge pro Seite" + +#: ../templates/index.php:26 +msgid "What" +msgstr "Was" + +#: ../templates/index.php:27 +msgid "When" +msgstr "Wann" + +#: ../templates/index.php:45 +msgid "Clear log entries before" +msgstr "Lösche Einträge vor dem" + diff --git a/l10n/de/settings.po b/l10n/de/settings.po new file mode 100644 index 00000000000..423514bc130 --- /dev/null +++ b/l10n/de/settings.po @@ -0,0 +1,86 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2011-06-20 22:00+0200\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" +"Language-Team: LANGUAGE <LL@li.org>\n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../templates/index.php:3 +msgid "Account information" +msgstr "Konto-Information" + +#: ../templates/index.php:5 +msgid "You're currently using" +msgstr "Du benutzt gerade" + +#: ../templates/index.php:5 +msgid "of your" +msgstr "von deinem" + +#: ../templates/index.php:5 +msgid "space" +msgstr "Speicherplatz" + +#: ../templates/index.php:11 +msgid "Change Password" +msgstr "Passwort ändern" + +#: ../templates/index.php:12 +msgid "Your password got changed" +msgstr "Dein Passwort wurde geändert." + +#: ../templates/index.php:15 +msgid "Old password:" +msgstr "Aktuelles Passwort:" + +#: ../templates/index.php:19 +msgid "New password" +msgstr "Neues Passwort:" + +#: ../templates/index.php:24 +msgid "Show new password" +msgstr "Neues Passwort anzeigen" + +#: ../templates/index.php:34 +msgid "Language" +msgstr "Sprache" + +#: ../ajax/changepassword.php:13 ../ajax/setlanguage.php:13 +msgid "Authentication error" +msgstr "Berechtigungsfehler" + +#: ../ajax/changepassword.php:19 +msgid "You have to enter the old and the new password!" +msgstr "Du musst das aktuelle und ein neues Passwort angeben!" + +#: ../ajax/changepassword.php:25 +msgid "Your old password is wrong!" +msgstr "Du hast dein aktuelles Passwort falsch eingegeben!" + +#: ../ajax/changepassword.php:31 +msgid "Password changed" +msgstr "Passwort geändert" + +#: ../ajax/changepassword.php:34 +msgid "Unable to change password" +msgstr "Passwort konnte nicht geändert werden" + +#: ../ajax/setlanguage.php:21 +msgid "Language changed" +msgstr "Sprache geändert" + +#: ../ajax/setlanguage.php:23 +msgid "Invalid request" +msgstr "Ungültige Anfrage" diff --git a/l10n/l10n.pl b/l10n/l10n.pl new file mode 100644 index 00000000000..0ad33d2116b --- /dev/null +++ b/l10n/l10n.pl @@ -0,0 +1,102 @@ +#!/usr/bin/perl +use strict; +use Locale::PO; +use Cwd; +use Data::Dumper; + +sub crawl{ + my( $dir ) = @_; + my @found = (); + + opendir( DIR, $dir ); + my @files = readdir( DIR ); + closedir( DIR ); + + foreach my $i ( @files ){ + next if substr( $i, 0, 1 ) eq '.'; + if( -d $dir.'/'.$i ){ + push( @found, crawl( $dir.'/'.$i )); + } + elsif( $i eq 'xgettextfiles' ){ + push( @found, $dir ); + } + } + + return @found; +} + +my $task = shift( @ARGV ); +my $place = '..'; + +die( "Usuage: l10n.pl task\ntask: read, write\n") unless $task && $place; + +# Our current position +my $whereami = cwd(); +die( "Program must be executed in a l10n-folder called 'l10n'" ) unless $whereami =~ m/\/l10n$/; + +# Where are i18n-files? +my @dirs = crawl( $place ); + +# Languages +mkdir( 'templates' ) unless -d 'templates'; + +my @languages = (); +opendir( DIR, '.' ); +my @files = readdir( DIR ); +closedir( DIR ); +foreach my $i ( @files ){ + push( @languages, $i ) if -d $i && substr( $i, 0, 1 ) ne '.'; +} + +if( $task eq 'read' ){ + foreach my $dir ( @dirs ){ + my @temp = split( /\//, $dir ); + pop( @temp ); + my $app = pop( @temp ); + chdir( $dir ); + my $output = "${whereami}/templates/$app.pot"; + + if( -e $output ){ + `xgettext --files-from=xgettextfiles --join-existing --output="$output" --keyword=t` + } + else{ + `xgettext --files-from=xgettextfiles --output="$output" --keyword=t` + } + chdir( $whereami ); + } +} +elsif( $task eq 'write' ){ + foreach my $dir ( @dirs ){ + my @temp = split( /\//, $dir ); + pop( @temp ); + my $app = pop( @temp ); + chdir( $dir ); + foreach my $language ( @languages ){ + next if $language eq 'templates'; + + my $input = "${whereami}/$language/$app.po"; + next unless -e $input; + + my $array = Locale::PO->load_file_asarray( $input ); + # Create array + my @strings = (); + foreach my $string ( @{$array} ){ + next if $string->msgid() eq '""'; + next if $string->msgstr() eq '""'; + push( @strings, $string->msgid()." => ".$string->msgstr()); + } + next if $#strings == -1; # Skip empty files + + # Write PHP file + open( OUT, ">$language.php" ); + print OUT "<?php \$TRANSLATIONS = array(\n"; + print OUT join( ",\n", @strings ); + print OUT "\n);\n"; + close( OUT ); + } + chdir( $whereami ); + } +} +else{ + print "unknown task!\n"; +} diff --git a/l10n/nl/admin.po b/l10n/nl/admin.po new file mode 100644 index 00000000000..506d5906b8a --- /dev/null +++ b/l10n/nl/admin.po @@ -0,0 +1,92 @@ +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# +# Robin Appelman <icewind1991@gmail.com>, 2011. +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2011-06-20 22:00+0200\n" +"PO-Revision-Date: 2011-06-21 15:00+0200\n" +"Last-Translator: Robin Appelman <icewind1991@gmail.com>\n" +"Language-Team: American English <kde-i18n-doc@kde.org>\n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 1.2\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: ../templates/app.php:22 +msgid "read more" +msgstr "Meer informatie" + +#: ../templates/app.php:24 +msgid "INSTALL" +msgstr "Installeer" + +#: ../templates/app_noconn.php:6 ../templates/apps.php:6 +msgid "Apps Repository" +msgstr "Applicatiedatabase" + +#: ../templates/app_noconn.php:7 +msgid "Cannot connect to apps repository" +msgstr "Kan geen verbinding maken met de applicatiedatabase" + +#: ../templates/apps.php:13 ../templates/users.php:6 ../templates/users.php:20 +#: ../templates/users.php:50 +msgid "Name" +msgstr "Naam" + +#: ../templates/apps.php:14 +msgid "Modified" +msgstr "Laatst aangepast" + +#: ../templates/system.php:6 +msgid "Administration" +msgstr "Administratie" + +#: ../templates/system.php:7 +msgid "System Settings" +msgstr "Systeeminstellingen" + +#: ../templates/users.php:7 ../templates/users.php:46 +msgid "Groups" +msgstr "Groepen" + +#: ../templates/users.php:13 +msgid "Add user" +msgstr "Gebruiker toevoegen" + +#: ../templates/users.php:21 +msgid "Password" +msgstr "Wachtwoord" + +#: ../templates/users.php:30 +msgid "Create user" +msgstr "Gebruiker aanmaken" + +#: ../templates/users.php:40 ../templates/users.php:68 +msgid "remove" +msgstr "verwijder" + +#: ../templates/users.php:58 +msgid "Create group" +msgstr "Groep aanmaken" + +#: ../templates/users.php:94 +msgid "Force new password:" +msgstr "Forceer nieuw wachtwoord:" + +#: ../templates/users.php:96 +msgid "Set" +msgstr "Ok" + +#: ../templates/users.php:102 +msgid "Do you really want to delete user" +msgstr "Wilt u deze gebruiker verwijderen" + +#: ../templates/users.php:109 +msgid "Do you really want to delete group" +msgstr "Wilt u deze groep verwijderen" + diff --git a/l10n/nl/core.po b/l10n/nl/core.po new file mode 100644 index 00000000000..3923dcb413d --- /dev/null +++ b/l10n/nl/core.po @@ -0,0 +1,122 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2011-06-20 22:00+0200\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" +"Language-Team: LANGUAGE <LL@li.org>\n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../templates/404.php:15 +msgid "Error 404, Cloud not found" +msgstr "Fout 404, Cloud niet gevonden." + +#: ../templates/installation.php:6 +msgid "Welcome to <strong>ownCloud</strong>, your personnal cloud." +msgstr "Welkom by <strong>ownCloud</strong>, uw persoonlijke cloud" + +#: ../templates/installation.php:7 +msgid "To finish the installation, please follow the steps below." +msgstr "Volg de volgende stappen om de installatie te voltooien." + +#: ../templates/installation.php:26 +msgid "Create an <strong>admin account.</strong>" +msgstr "Maak een <strong>beheerdersaccount</strong> aan" + +#: ../templates/installation.php:27 +msgid "Login:" +msgstr "Gebruikersnaam:" + +#: ../templates/installation.php:28 +msgid "Password:" +msgstr "Wachtwoord:" + +#: ../templates/installation.php:31 +msgid "Advanced" +msgstr "Geavanceerd" + +#: ../templates/installation.php:34 +msgid "Set where to store the data." +msgstr "Bepaal de opslaglocatie." + +#: ../templates/installation.php:35 +msgid "Data directory:" +msgstr "Gegevensmap:" + +#: ../templates/installation.php:39 +msgid "Configure your database." +msgstr "Configureer uw database." + +#: ../templates/installation.php:43 +msgid "I will use a SQLite database. You have nothing to do!" +msgstr "Er zal een SQLite database gebruikt worden. U hoeft geen verdere instellingen te maken." + +#: ../templates/installation.php:46 +msgid "SQLite" +msgstr "SQLite" + +#: ../templates/installation.php:53 +msgid "I will use a MySQL database." +msgstr "Er zal een MySQL database gebruikt worden." + +#: ../templates/installation.php:59 +msgid "Host:" +msgstr "Host:" + +#: ../templates/installation.php:60 +msgid "Database name:" +msgstr "Databasenaam:" + +#: ../templates/installation.php:61 +msgid "Table prefix:" +msgstr "Voorvoegsel voor tabelnamen:" + +#: ../templates/installation.php:62 +msgid "MySQL user login:" +msgstr "MySQL gebruikersnaam." + +#: ../templates/installation.php:63 +msgid "MySQL user password:" +msgstr "MySQL wachtwoord" + +#: ../templates/installation.php:68 +msgid "Finish setup" +msgstr "Installatie afronden" + +#: ../templates/layout.guest.php:20 +msgid "" +"<a href=\"http://owncloud.org/\">ownCloud</a> is a personal cloud which runs " +"on your own server.</p>" +msgstr "" +"<a href=\"http://owncloud.org/\">ownCloud</a> is een persoonlijke cloud die " +"op uw eigen server draait.</p>" + +#: ../templates/login.php:6 +msgid "Login failed!" +msgstr "Aanmelden mislukt." + +#: ../templates/logout.php:1 +msgid "You are logged out." +msgstr "U bent afgemeld." + +#: ../templates/part.pagenavi.php:6 +msgid "prev" +msgstr "vorige" + +#: ../templates/part.pagenavi.php:26 +msgid "next" +msgstr "volgende" + +#: ../templates/part.searchbox.php:3 +msgid "Search" +msgstr "Zoeken" diff --git a/l10n/nl/help.po b/l10n/nl/help.po new file mode 100644 index 00000000000..b1f1f4bc447 --- /dev/null +++ b/l10n/nl/help.po @@ -0,0 +1,27 @@ +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# +# Robin Appelman <icewind1991@gmail.com>, 2011. +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2011-06-20 22:00+0200\n" +"PO-Revision-Date: 2011-06-21 15:03+0200\n" +"Last-Translator: Robin Appelman <icewind1991@gmail.com>\n" +"Language-Team: Dutch <>\n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 1.2\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: ../templates/index.php:2 +msgid "Questions and Answers" +msgstr "Vraag en Antwoord" + +#: ../templates/index.php:21 +msgid "ASK A QUESTION" +msgstr "Stel een vraag" + diff --git a/l10n/nl/log.po b/l10n/nl/log.po new file mode 100644 index 00000000000..3bf2f43a920 --- /dev/null +++ b/l10n/nl/log.po @@ -0,0 +1,67 @@ +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# +# Robin Appelman <icewind1991@gmail.com>, 2011. +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2011-06-20 22:00+0200\n" +"PO-Revision-Date: 2011-06-21 15:01+0200\n" +"Last-Translator: Robin Appelman <icewind1991@gmail.com>\n" +"Language-Team: American English <kde-i18n-doc@kde.org>\n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 1.2\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: ../templates/index.php:4 +msgid "Filter:" +msgstr "Filter:" + +#: ../templates/index.php:7 +msgid "Logins" +msgstr "Aanmeldingen" + +#: ../templates/index.php:8 +msgid "Logouts" +msgstr "Afmeldingen" + +#: ../templates/index.php:9 +msgid "Downloads" +msgstr "Downloads" + +#: ../templates/index.php:10 +msgid "Uploads" +msgstr "Uploads" + +#: ../templates/index.php:11 +msgid "Creations" +msgstr "Creaties" + +#: ../templates/index.php:12 +msgid "Deletions" +msgstr "Verwijderingen" + +#: ../templates/index.php:15 +msgid "Show:" +msgstr "Laat" + +#: ../templates/index.php:16 +msgid "entries per page." +msgstr "resulaten per pagina zien" + +#: ../templates/index.php:26 +msgid "What" +msgstr "Wat" + +#: ../templates/index.php:27 +msgid "When" +msgstr "Wanneer" + +#: ../templates/index.php:45 +msgid "Clear log entries before" +msgstr "Verwijder logboekitem ouder dan" + diff --git a/l10n/nl/settings.po b/l10n/nl/settings.po new file mode 100644 index 00000000000..866e8b702cd --- /dev/null +++ b/l10n/nl/settings.po @@ -0,0 +1,86 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2011-06-20 22:00+0200\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" +"Language-Team: LANGUAGE <LL@li.org>\n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../templates/index.php:3 +msgid "Account information" +msgstr "Gebruikersgegevens" + +#: ../templates/index.php:5 +msgid "You're currently using" +msgstr "U gebruikt momenteel" + +#: ../templates/index.php:5 +msgid "of your" +msgstr "van de" + +#: ../templates/index.php:5 +msgid "space" +msgstr "beschikbare ruimte." + +#: ../templates/index.php:11 +msgid "Change Password" +msgstr "Wachtwoord aanpassen" + +#: ../templates/index.php:12 +msgid "Your password got changed" +msgstr "Uw wachtwoord is aangepast" + +#: ../templates/index.php:15 +msgid "Old password:" +msgstr "Oud wachtwoord:" + +#: ../templates/index.php:19 +msgid "New password" +msgstr "Nieuw wachtwoord" + +#: ../templates/index.php:24 +msgid "Show new password" +msgstr "Toon nieuw wachtwoord" + +#: ../templates/index.php:34 +msgid "Language" +msgstr "Taal" + +#: ../ajax/changepassword.php:13 ../ajax/setlanguage.php:13 +msgid "Authentication error" +msgstr "Authenticatiefout." + +#: ../ajax/changepassword.php:19 +msgid "You have to enter the old and the new password!" +msgstr "U moet het oude en nieuwe wachtwoord invullen." + +#: ../ajax/changepassword.php:25 +msgid "Your old password is wrong!" +msgstr "Het oude wachtwoord is verkeerd." + +#: ../ajax/changepassword.php:31 +msgid "Password changed" +msgstr "Wachtwoord aangepast" + +#: ../ajax/changepassword.php:34 +msgid "Unable to change password" +msgstr "Wachtwoord aanpassen is niet mogelijk" + +#: ../ajax/setlanguage.php:21 +msgid "Language changed" +msgstr "Taal aangepast" + +#: ../ajax/setlanguage.php:23 +msgid "Invalid request" +msgstr "Ongeldig verzoek" diff --git a/l10n/pl/admin.po b/l10n/pl/admin.po new file mode 100644 index 00000000000..858dccf6687 --- /dev/null +++ b/l10n/pl/admin.po @@ -0,0 +1,96 @@ +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# +# Kamil Domański <kdomanski@kdemail.net>, 2011. +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2011-06-21 16:19+0200\n" +"PO-Revision-Date: 2011-06-22 03:28+0200\n" +"Last-Translator: Kamil Domański <kdomanski@kdemail.net>\n" +"Language-Team: American English <kde-i18n-doc@kde.org>\n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 1.2\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: ../templates/app.php:22 +msgid "read more" +msgstr "czytaj więcej" + +#: ../templates/app.php:24 +msgid "INSTALL" +msgstr "INSTALUJ" + +#: ../templates/app_noconn.php:6 ../templates/apps.php:6 +msgid "Apps Repository" +msgstr "Repozytorium aplikacji" + +#: ../templates/app_noconn.php:7 +msgid "Cannot connect to apps repository" +msgstr "Nie można połączyć się z repozytorium aplikacji" + +#: ../templates/apps.php:13 ../templates/users.php:6 ../templates/users.php:20 +#: ../templates/users.php:50 +msgid "Name" +msgstr "Nazwa" + +#: ../templates/apps.php:14 +msgid "Modified" +msgstr "Zmodyfikowano" + +#: ../templates/system.php:6 +msgid "Administration" +msgstr "Administracja" + +#: ../templates/system.php:7 +msgid "System Settings" +msgstr "Ustawienia systemowe" + +#: ../templates/users.php:13 +msgid "Add user" +msgstr "Dodaj użytkownika" + +#: ../templates/users.php:21 +msgid "Password" +msgstr "Hasło" + +#: ../templates/users.php:30 +msgid "Create user" +msgstr "Utwórz użytkownika" + +#: ../templates/users.php:40 ../templates/users.php:68 +msgid "remove" +msgstr "usuń" + +#: ../templates/users.php:46 ../templates/users.php:7 +msgid "Groups" +msgstr "Grupy" + +#: ../templates/users.php:58 +msgid "Create group" +msgstr "Utwórz grupę" + +#: ../templates/users.php:94 +msgid "Force new password:" +msgstr "Wymuś nowe hasło" + +#: ../templates/users.php:96 +msgid "Set" +msgstr "Ustaw" + +#: ../templates/users.php:102 +msgid "Do you really want to delete user" +msgstr "Czy naprawdę chcesz usunąć użytkownika" + +#: ../templates/users.php:109 +msgid "Do you really want to delete group" +msgstr "Czy naprawdę chcesz usunąć grupę" + +#: ../templates/users.php:1 +msgid "Users" +msgstr "Użytkownicy" + diff --git a/l10n/pl/core.po b/l10n/pl/core.po new file mode 100644 index 00000000000..717555818e2 --- /dev/null +++ b/l10n/pl/core.po @@ -0,0 +1,123 @@ +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# +# Kamil Domański <kdomanski@kdemail.net>, 2011. +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2011-06-21 16:19+0200\n" +"PO-Revision-Date: 2011-06-22 03:36+0200\n" +"Last-Translator: Kamil Domański <kdomanski@kdemail.net>\n" +"Language-Team: American English <kde-i18n-doc@kde.org>\n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 1.2\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: ../templates/404.php:15 +msgid "Error 404, Cloud not found" +msgstr "Błąd 404, Chmura nie znaleziona" + +#: ../templates/installation.php:6 +msgid "Welcome to <strong>ownCloud</strong>, your personnal cloud." +msgstr "Witaj w <strong>ownCloud</strong>, Twojej osobistej chmurze." + +#: ../templates/installation.php:7 +msgid "To finish the installation, please follow the steps below." +msgstr "By zakończyć instalację, podążaj poniższymi krokami." + +#: ../templates/installation.php:26 +msgid "Create an <strong>admin account.</strong>" +msgstr "Utwórz <strong>konto administratora</strong>." + +#: ../templates/installation.php:27 +msgid "Login:" +msgstr "Login:" + +#: ../templates/installation.php:28 +msgid "Password:" +msgstr "Hasło:" + +#: ../templates/installation.php:31 +msgid "Advanced" +msgstr "Zaawansowane" + +#: ../templates/installation.php:34 +msgid "Set where to store the data." +msgstr "Ustaw, gdzie przechowywać dane." + +#: ../templates/installation.php:35 +msgid "Data directory:" +msgstr "Katalog danych:" + +#: ../templates/installation.php:39 +msgid "Configure your database." +msgstr "Skonfiguruj Twoją bazę danych." + +#: ../templates/installation.php:43 +msgid "I will use a SQLite database. You have nothing to do!" +msgstr "Użyję bazy SQLite. Nie masz tu nic do roboty!" + +#: ../templates/installation.php:46 +msgid "SQLite" +msgstr "SQLite" + +#: ../templates/installation.php:53 +msgid "I will use a MySQL database." +msgstr "Użyję bazy danych MySQL." + +#: ../templates/installation.php:59 +msgid "Host:" +msgstr "Host:" + +#: ../templates/installation.php:60 +msgid "Database name:" +msgstr "Nazwa bazy:" + +#: ../templates/installation.php:61 +msgid "Table prefix:" +msgstr "Przedrostek tabeli:" + +#: ../templates/installation.php:62 +msgid "MySQL user login:" +msgstr "Login użytkownika MySQL:" + +#: ../templates/installation.php:63 +msgid "MySQL user password:" +msgstr "Hasło użytkownika MySQL:" + +#: ../templates/installation.php:68 +msgid "Finish setup" +msgstr "Zakończ instalację" + +#: ../templates/layout.guest.php:20 +msgid "" +"<a href=\"http://owncloud.org/\">ownCloud</a> is a personal cloud which runs " +"on your own server.</p>" +msgstr "" +"<a href=\"http://owncloud.org/\">ownCloud</a> jest osobistą chmurą działającą " +"na Twoim własnym serwerze.</p>" + +#: ../templates/login.php:6 +msgid "Login failed!" +msgstr "Nie udało się zalogować!" + +#: ../templates/logout.php:1 +msgid "You are logged out." +msgstr "Jesteś wylogowany." + +#: ../templates/part.pagenavi.php:6 +msgid "prev" +msgstr "wstecz" + +#: ../templates/part.pagenavi.php:26 +msgid "next" +msgstr "dalej" + +#: ../templates/part.searchbox.php:3 +msgid "Search" +msgstr "Szukaj" + diff --git a/l10n/pl/help.po b/l10n/pl/help.po new file mode 100644 index 00000000000..a9d8481d5ce --- /dev/null +++ b/l10n/pl/help.po @@ -0,0 +1,28 @@ +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# +# Kamil Domański <kdomanski@kdemail.net>, 2011. +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2011-06-21 16:19+0200\n" +"PO-Revision-Date: 2011-06-22 03:45+0200\n" +"Last-Translator: Kamil Domański <kdomanski@kdemail.net>\n" +"Language-Team: Polish <owncloud@kde.org>\n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 1.2\n" +"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 " +"|| n%100>=20) ? 1 : 2);\n" + +#: ../templates/index.php:2 +msgid "Questions and Answers" +msgstr "Pytania i odpowiedzi" + +#: ../templates/index.php:21 +msgid "ASK A QUESTION" +msgstr "ZADAJ PYTANIE" + diff --git a/l10n/pl/log.po b/l10n/pl/log.po new file mode 100644 index 00000000000..9c426ec2318 --- /dev/null +++ b/l10n/pl/log.po @@ -0,0 +1,68 @@ +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# +# Kamil Domański <kdomanski@kdemail.net>, 2011. +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2011-06-21 16:19+0200\n" +"PO-Revision-Date: 2011-06-22 03:50+0200\n" +"Last-Translator: Kamil Domański <kdomanski@kdemail.net>\n" +"Language-Team: Polish <owncloud@kde.org>\n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 1.2\n" +"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 " +"|| n%100>=20) ? 1 : 2);\n" + +#: ../templates/index.php:4 +msgid "Filter:" +msgstr "Filtr:" + +#: ../templates/index.php:7 +msgid "Logins" +msgstr "Zalogowania" + +#: ../templates/index.php:8 +msgid "Logouts" +msgstr "Wylogowani" + +#: ../templates/index.php:9 +msgid "Downloads" +msgstr "Pobrania" + +#: ../templates/index.php:10 +msgid "Uploads" +msgstr "Wgrania" + +#: ../templates/index.php:11 +msgid "Creations" +msgstr "Utworzenia" + +#: ../templates/index.php:12 +msgid "Deletions" +msgstr "Usunięcia" + +#: ../templates/index.php:15 +msgid "Show:" +msgstr "Pokaż:" + +#: ../templates/index.php:16 +msgid "entries per page." +msgstr "wpisów na stronę." + +#: ../templates/index.php:26 +msgid "What" +msgstr "Co" + +#: ../templates/index.php:27 +msgid "When" +msgstr "Kiedy" + +#: ../templates/index.php:45 +msgid "Clear log entries before" +msgstr "Wyczyść spisy dziennika sprzed" + diff --git a/l10n/pl/settings.po b/l10n/pl/settings.po new file mode 100644 index 00000000000..6dec38f1054 --- /dev/null +++ b/l10n/pl/settings.po @@ -0,0 +1,88 @@ +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# +# Kamil Domański <kdomanski@kdemail.net>, 2011. +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2011-06-21 16:19+0200\n" +"PO-Revision-Date: 2011-06-22 03:52+0200\n" +"Last-Translator: Kamil Domański <kdomanski@kdemail.net>\n" +"Language-Team: Polish <owncloud@kde.org>\n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 1.2\n" +"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 " +"|| n%100>=20) ? 1 : 2);\n" + +#: ../templates/index.php:3 +msgid "Account information" +msgstr "Dane konta" + +#: ../templates/index.php:5 +msgid "You're currently using" +msgstr "Obecnie używasz" + +#: ../templates/index.php:5 +msgid "of your" +msgstr "ze swoich" + +#: ../templates/index.php:5 +msgid "space" +msgstr "przestrzeni" + +#: ../templates/index.php:11 +msgid "Change Password" +msgstr "Zmień hasło" + +#: ../templates/index.php:12 +msgid "Your password got changed" +msgstr "Twoje hasło zostało zmienione" + +#: ../templates/index.php:15 +msgid "Old password:" +msgstr "Stare hasło" + +#: ../templates/index.php:19 +msgid "New password" +msgstr "Nowe hasło" + +#: ../templates/index.php:24 +msgid "Show new password" +msgstr "Pokaż nowe hasło" + +#: ../templates/index.php:34 +msgid "Language" +msgstr "Język" + +#: ../ajax/changepassword.php:13 ../ajax/setlanguage.php:13 +msgid "Authentication error" +msgstr "Błąd uwierzytelniania" + +#: ../ajax/changepassword.php:19 +msgid "You have to enter the old and the new password!" +msgstr "Musisz wprowadzić zarówno stare, jak i nowe hasło!" + +#: ../ajax/changepassword.php:25 +msgid "Your old password is wrong!" +msgstr "Twoje stare hasło jest błędne!" + +#: ../ajax/changepassword.php:31 +msgid "Password changed" +msgstr "Hasło zmienione" + +#: ../ajax/changepassword.php:34 +msgid "Unable to change password" +msgstr "NIe można zmienić hasła" + +#: ../ajax/setlanguage.php:21 +msgid "Language changed" +msgstr "Język zmieniony" + +#: ../ajax/setlanguage.php:23 +msgid "Invalid request" +msgstr "Nieprawidłowe żądanie" + diff --git a/l10n/templates/admin.pot b/l10n/templates/admin.pot new file mode 100644 index 00000000000..cb01fee4d23 --- /dev/null +++ b/l10n/templates/admin.pot @@ -0,0 +1,95 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2011-06-21 16:19+0200\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" +"Language-Team: LANGUAGE <LL@li.org>\n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../templates/app.php:22 +msgid "read more" +msgstr "" + +#: ../templates/app.php:24 +msgid "INSTALL" +msgstr "" + +#: ../templates/app_noconn.php:6 ../templates/apps.php:6 +msgid "Apps Repository" +msgstr "" + +#: ../templates/app_noconn.php:7 +msgid "Cannot connect to apps repository" +msgstr "" + +#: ../templates/apps.php:13 ../templates/users.php:6 ../templates/users.php:20 +#: ../templates/users.php:50 +msgid "Name" +msgstr "" + +#: ../templates/apps.php:14 +msgid "Modified" +msgstr "" + +#: ../templates/system.php:6 +msgid "Administration" +msgstr "" + +#: ../templates/system.php:7 +msgid "System Settings" +msgstr "" + +#: ../templates/users.php:13 +msgid "Add user" +msgstr "" + +#: ../templates/users.php:21 +msgid "Password" +msgstr "" + +#: ../templates/users.php:30 +msgid "Create user" +msgstr "" + +#: ../templates/users.php:40 ../templates/users.php:68 +msgid "remove" +msgstr "" + +#: ../templates/users.php:46 ../templates/users.php:7 +msgid "Groups" +msgstr "" + +#: ../templates/users.php:58 +msgid "Create group" +msgstr "" + +#: ../templates/users.php:94 +msgid "Force new password:" +msgstr "" + +#: ../templates/users.php:96 +msgid "Set" +msgstr "" + +#: ../templates/users.php:102 +msgid "Do you really want to delete user" +msgstr "" + +#: ../templates/users.php:109 +msgid "Do you really want to delete group" +msgstr "" + +#: ../templates/users.php:1 +msgid "Users" +msgstr "" diff --git a/l10n/templates/core.pot b/l10n/templates/core.pot new file mode 100644 index 00000000000..679ca60a989 --- /dev/null +++ b/l10n/templates/core.pot @@ -0,0 +1,120 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2011-06-21 16:19+0200\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" +"Language-Team: LANGUAGE <LL@li.org>\n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../templates/404.php:15 +msgid "Error 404, Cloud not found" +msgstr "" + +#: ../templates/installation.php:6 +msgid "Welcome to <strong>ownCloud</strong>, your personnal cloud." +msgstr "" + +#: ../templates/installation.php:7 +msgid "To finish the installation, please follow the steps below." +msgstr "" + +#: ../templates/installation.php:26 +msgid "Create an <strong>admin account.</strong>" +msgstr "" + +#: ../templates/installation.php:27 +msgid "Login:" +msgstr "" + +#: ../templates/installation.php:28 +msgid "Password:" +msgstr "" + +#: ../templates/installation.php:31 +msgid "Advanced" +msgstr "" + +#: ../templates/installation.php:34 +msgid "Set where to store the data." +msgstr "" + +#: ../templates/installation.php:35 +msgid "Data directory:" +msgstr "" + +#: ../templates/installation.php:39 +msgid "Configure your database." +msgstr "" + +#: ../templates/installation.php:43 +msgid "I will use a SQLite database. You have nothing to do!" +msgstr "" + +#: ../templates/installation.php:46 +msgid "SQLite" +msgstr "" + +#: ../templates/installation.php:53 +msgid "I will use a MySQL database." +msgstr "" + +#: ../templates/installation.php:59 +msgid "Host:" +msgstr "" + +#: ../templates/installation.php:60 +msgid "Database name:" +msgstr "" + +#: ../templates/installation.php:61 +msgid "Table prefix:" +msgstr "" + +#: ../templates/installation.php:62 +msgid "MySQL user login:" +msgstr "" + +#: ../templates/installation.php:63 +msgid "MySQL user password:" +msgstr "" + +#: ../templates/installation.php:68 +msgid "Finish setup" +msgstr "" + +#: ../templates/layout.guest.php:20 +msgid "" +"<a href=\"http://owncloud.org/\">ownCloud</a> is a personal cloud which runs " +"on your own server.</p>" +msgstr "" + +#: ../templates/login.php:6 +msgid "Login failed!" +msgstr "" + +#: ../templates/logout.php:1 +msgid "You are logged out." +msgstr "" + +#: ../templates/part.pagenavi.php:6 +msgid "prev" +msgstr "" + +#: ../templates/part.pagenavi.php:26 +msgid "next" +msgstr "" + +#: ../templates/part.searchbox.php:3 +msgid "Search" +msgstr "" diff --git a/l10n/templates/help.pot b/l10n/templates/help.pot new file mode 100644 index 00000000000..43b9b26ff0c --- /dev/null +++ b/l10n/templates/help.pot @@ -0,0 +1,26 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2011-06-21 16:19+0200\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" +"Language-Team: LANGUAGE <LL@li.org>\n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../templates/index.php:2 +msgid "Questions and Answers" +msgstr "" + +#: ../templates/index.php:21 +msgid "ASK A QUESTION" +msgstr "" diff --git a/l10n/templates/log.pot b/l10n/templates/log.pot new file mode 100644 index 00000000000..91339d45132 --- /dev/null +++ b/l10n/templates/log.pot @@ -0,0 +1,66 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2011-06-21 16:19+0200\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" +"Language-Team: LANGUAGE <LL@li.org>\n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../templates/index.php:4 +msgid "Filter:" +msgstr "" + +#: ../templates/index.php:7 +msgid "Logins" +msgstr "" + +#: ../templates/index.php:8 +msgid "Logouts" +msgstr "" + +#: ../templates/index.php:9 +msgid "Downloads" +msgstr "" + +#: ../templates/index.php:10 +msgid "Uploads" +msgstr "" + +#: ../templates/index.php:11 +msgid "Creations" +msgstr "" + +#: ../templates/index.php:12 +msgid "Deletions" +msgstr "" + +#: ../templates/index.php:15 +msgid "Show:" +msgstr "" + +#: ../templates/index.php:16 +msgid "entries per page." +msgstr "" + +#: ../templates/index.php:26 +msgid "What" +msgstr "" + +#: ../templates/index.php:27 +msgid "When" +msgstr "" + +#: ../templates/index.php:45 +msgid "Clear log entries before" +msgstr "" diff --git a/l10n/templates/settings.pot b/l10n/templates/settings.pot new file mode 100644 index 00000000000..ff8029ae465 --- /dev/null +++ b/l10n/templates/settings.pot @@ -0,0 +1,86 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2011-06-21 16:19+0200\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" +"Language-Team: LANGUAGE <LL@li.org>\n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../templates/index.php:3 +msgid "Account information" +msgstr "" + +#: ../templates/index.php:5 +msgid "You're currently using" +msgstr "" + +#: ../templates/index.php:5 +msgid "of your" +msgstr "" + +#: ../templates/index.php:5 +msgid "space" +msgstr "" + +#: ../templates/index.php:11 +msgid "Change Password" +msgstr "" + +#: ../templates/index.php:12 +msgid "Your password got changed" +msgstr "" + +#: ../templates/index.php:15 +msgid "Old password:" +msgstr "" + +#: ../templates/index.php:19 +msgid "New password" +msgstr "" + +#: ../templates/index.php:24 +msgid "Show new password" +msgstr "" + +#: ../templates/index.php:34 +msgid "Language" +msgstr "" + +#: ../ajax/changepassword.php:13 ../ajax/setlanguage.php:13 +msgid "Authentication error" +msgstr "" + +#: ../ajax/changepassword.php:19 +msgid "You have to enter the old and the new password!" +msgstr "" + +#: ../ajax/changepassword.php:25 +msgid "Your old password is wrong!" +msgstr "" + +#: ../ajax/changepassword.php:31 +msgid "Password changed" +msgstr "" + +#: ../ajax/changepassword.php:34 +msgid "Unable to change password" +msgstr "" + +#: ../ajax/setlanguage.php:21 +msgid "Language changed" +msgstr "" + +#: ../ajax/setlanguage.php:23 +msgid "Invalid request" +msgstr "" diff --git a/lib/HTTP/WebDAV/Server/Filesystem.php b/lib/HTTP/WebDAV/Server/Filesystem.php index 164892c9d86..5f261643624 100644 --- a/lib/HTTP/WebDAV/Server/Filesystem.php +++ b/lib/HTTP/WebDAV/Server/Filesystem.php @@ -687,9 +687,14 @@ VALUES (?,?,?,?,?,'timeout',?,?)"); function UNLOCK(&$options) { $query = OC_DB::prepare("DELETE FROM *PREFIX*locks + WHERE path = '$options[path]' + AND token = '$options[token]'"); + /* + $query = OC_DB::prepare("DELETE FROM *PREFIX*locks WHERE path = ? AND token = ?"); - $query->execute(array($options[path]),$options[token]); + */ + $query->execute();#array($options[path]),$options[token]); return PEAR::isError($result) ? "409 Conflict" : "204 No Content"; } diff --git a/lib/MDB2/Driver/Datatype/sqlite3.php b/lib/MDB2/Driver/Datatype/sqlite3.php new file mode 100644 index 00000000000..378d5540cbe --- /dev/null +++ b/lib/MDB2/Driver/Datatype/sqlite3.php @@ -0,0 +1,412 @@ +<?php +// vim: set et ts=4 sw=4 fdm=marker: +// +----------------------------------------------------------------------+ +// | PHP version 5 | +// +----------------------------------------------------------------------+ +// | Copyright (c) 2011 Robin Appelman | +// | All rights reserved. | +// +----------------------------------------------------------------------+ +// | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB | +// | API as well as database abstraction for PHP applications. | +// | This LICENSE is in the BSD license style. | +// | | +// | Redistribution and use in source and binary forms, with or without | +// | modification, are permitted provided that the following conditions | +// | are met: | +// | | +// | Redistributions of source code must retain the above copyright | +// | notice, this list of conditions and the following disclaimer. | +// | | +// | Redistributions in binary form must reproduce the above copyright | +// | notice, this list of conditions and the following disclaimer in the | +// | documentation and/or other materials provided with the distribution. | +// | | +// | Neither the name of Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, | +// | Lukas Smith nor the names of his contributors may be used to endorse | +// | or promote products derived from this software without specific prior| +// | written permission. | +// | | +// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | +// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | +// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | +// | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE | +// | REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | +// | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | +// | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS| +// | OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED | +// | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | +// | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY| +// | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | +// | POSSIBILITY OF SUCH DAMAGE. | +// +----------------------------------------------------------------------+ +// | Author: Robin Appelman <icewind1991@gmail.com | +// +----------------------------------------------------------------------+ +// +// $Id: sqlite.php,v 1.67 2008/02/22 19:58:06 quipo Exp $ +// + +require_once('MDB2/Driver/Datatype/Common.php'); + +/** + * MDB2 SQLite driver + * + * @package MDB2 + * @category Database + * @author Lukas Smith <smith@pooteeweet.org> + */ +class MDB2_Driver_Datatype_sqlite3 extends MDB2_Driver_Datatype_Common +{ + // {{{ _getCollationFieldDeclaration() + + /** + * Obtain DBMS specific SQL code portion needed to set the COLLATION + * of a field declaration to be used in statements like CREATE TABLE. + * + * @param string $collation name of the collation + * + * @return string DBMS specific SQL code portion needed to set the COLLATION + * of a field declaration. + */ + function _getCollationFieldDeclaration($collation) + { + return 'COLLATE '.$collation; + } + + // }}} + // {{{ getTypeDeclaration() + + /** + * Obtain DBMS specific SQL code portion needed to declare an text type + * field to be used in statements like CREATE TABLE. + * + * @param array $field associative array with the name of the properties + * of the field being declared as array indexes. Currently, the types + * of supported field properties are as follows: + * + * length + * Integer value that determines the maximum length of the text + * field. If this argument is missing the field should be + * declared to have the longest length allowed by the DBMS. + * + * default + * Text value to be used as default for this field. + * + * notnull + * Boolean flag that indicates whether this field is constrained + * to not be set to null. + * @return string DBMS specific SQL code portion that should be used to + * declare the specified field. + * @access public + */ + function getTypeDeclaration($field) + { + $db =$this->getDBInstance(); + if (PEAR::isError($db)) { + return $db; + } + + switch ($field['type']) { + case 'text': + $length = !empty($field['length']) + ? $field['length'] : false; + $fixed = !empty($field['fixed']) ? $field['fixed'] : false; + return $fixed ? ($length ? 'CHAR('.$length.')' : 'CHAR('.$db->options['default_text_field_length'].')') + : ($length ? 'VARCHAR('.$length.')' : 'TEXT'); + case 'clob': + if (!empty($field['length'])) { + $length = $field['length']; + if ($length <= 255) { + return 'TINYTEXT'; + } elseif ($length <= 65532) { + return 'TEXT'; + } elseif ($length <= 16777215) { + return 'MEDIUMTEXT'; + } + } + return 'LONGTEXT'; + case 'blob': + if (!empty($field['length'])) { + $length = $field['length']; + if ($length <= 255) { + return 'TINYBLOB'; + } elseif ($length <= 65532) { + return 'BLOB'; + } elseif ($length <= 16777215) { + return 'MEDIUMBLOB'; + } + } + return 'LONGBLOB'; + case 'integer': + if (!empty($field['length'])) { + $length = $field['length']; + if ($length <= 2) { + return 'SMALLINT'; + } elseif ($length == 3 || $length == 4) { + return 'INTEGER'; + } elseif ($length > 4) { + return 'BIGINT'; + } + } + return 'INTEGER'; + case 'boolean': + return 'BOOLEAN'; + case 'date': + return 'DATE'; + case 'time': + return 'TIME'; + case 'timestamp': + return 'DATETIME'; + case 'float': + return 'DOUBLE'.($db->options['fixed_float'] ? '('. + ($db->options['fixed_float']+2).','.$db->options['fixed_float'].')' : ''); + case 'decimal': + $length = !empty($field['length']) ? $field['length'] : 18; + $scale = !empty($field['scale']) ? $field['scale'] : $db->options['decimal_places']; + return 'DECIMAL('.$length.','.$scale.')'; + } + return ''; + } + + // }}} + // {{{ _getIntegerDeclaration() + + /** + * Obtain DBMS specific SQL code portion needed to declare an integer type + * field to be used in statements like CREATE TABLE. + * + * @param string $name name the field to be declared. + * @param string $field associative array with the name of the properties + * of the field being declared as array indexes. + * Currently, the types of supported field + * properties are as follows: + * + * unsigned + * Boolean flag that indicates whether the field + * should be declared as unsigned integer if + * possible. + * + * default + * Integer value to be used as default for this + * field. + * + * notnull + * Boolean flag that indicates whether this field is + * constrained to not be set to null. + * @return string DBMS specific SQL code portion that should be used to + * declare the specified field. + * @access protected + */ + function _getIntegerDeclaration($name, $field) + { + $db =$this->getDBInstance(); + if (PEAR::isError($db)) { + return $db; + } + + $default = $autoinc = ''; + if (!empty($field['autoincrement'])) { + $autoinc = ' PRIMARY KEY AUTOINCREMENT'; + } elseif (array_key_exists('default', $field)) { + if ($field['default'] === '') { + $field['default'] = empty($field['notnull']) ? null : 0; + } + $default = ' DEFAULT '.$this->quote($field['default'], 'integer'); + } + + $notnull = empty($field['notnull']) ? '' : ' NOT NULL'; + $unsigned = empty($field['unsigned']) ? '' : ' UNSIGNED'; + $name = $db->quoteIdentifier($name, true); + if($autoinc){ + return $name.' '.$this->getTypeDeclaration($field).$autoinc; + }else{ + return $name.' '.$this->getTypeDeclaration($field).$unsigned.$default.$notnull.$autoinc; + } + } + + // }}} + // {{{ matchPattern() + + /** + * build a pattern matching string + * + * @access public + * + * @param array $pattern even keys are strings, odd are patterns (% and _) + * @param string $operator optional pattern operator (LIKE, ILIKE and maybe others in the future) + * @param string $field optional field name that is being matched against + * (might be required when emulating ILIKE) + * + * @return string SQL pattern + */ + function matchPattern($pattern, $operator = null, $field = null) + { + $db =$this->getDBInstance(); + if (PEAR::isError($db)) { + return $db; + } + + $match = ''; + if (!is_null($operator)) { + $field = is_null($field) ? '' : $field.' '; + $operator = strtoupper($operator); + switch ($operator) { + // case insensitive + case 'ILIKE': + $match = $field.'LIKE '; + break; + // case sensitive + case 'LIKE': + $match = $field.'LIKE '; + break; + default: + return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null, + 'not a supported operator type:'. $operator, __FUNCTION__); + } + } + $match.= "'"; + foreach ($pattern as $key => $value) { + if ($key % 2) { + $match.= $value; + } else { + $match.= $db->escapePattern($db->escape($value)); + } + } + $match.= "'"; + $match.= $this->patternEscapeString(); + return $match; + } + + // }}} + // {{{ _mapNativeDatatype() + + /** + * Maps a native array description of a field to a MDB2 datatype and length + * + * @param array $field native field description + * @return array containing the various possible types, length, sign, fixed + * @access public + */ + function _mapNativeDatatype($field) + { + $db_type = strtolower($field['type']); + $length = !empty($field['length']) ? $field['length'] : null; + $unsigned = !empty($field['unsigned']) ? $field['unsigned'] : null; + $fixed = null; + $type = array(); + switch ($db_type) { + case 'boolean': + $type[] = 'boolean'; + break; + case 'tinyint': + $type[] = 'integer'; + $type[] = 'boolean'; + if (preg_match('/^(is|has)/', $field['name'])) { + $type = array_reverse($type); + } + $unsigned = preg_match('/ unsigned/i', $field['type']); + $length = 1; + break; + case 'smallint': + $type[] = 'integer'; + $unsigned = preg_match('/ unsigned/i', $field['type']); + $length = 2; + break; + case 'mediumint': + $type[] = 'integer'; + $unsigned = preg_match('/ unsigned/i', $field['type']); + $length = 3; + break; + case 'int': + case 'integer': + case 'serial': + $type[] = 'integer'; + $unsigned = preg_match('/ unsigned/i', $field['type']); + $length = 4; + break; + case 'bigint': + case 'bigserial': + $type[] = 'integer'; + $unsigned = preg_match('/ unsigned/i', $field['type']); + $length = 8; + break; + case 'clob': + $type[] = 'clob'; + $fixed = false; + break; + case 'tinytext': + case 'mediumtext': + case 'longtext': + case 'text': + case 'varchar': + case 'varchar2': + $fixed = false; + case 'char': + $type[] = 'text'; + if ($length == '1') { + $type[] = 'boolean'; + if (preg_match('/^(is|has)/', $field['name'])) { + $type = array_reverse($type); + } + } elseif (strstr($db_type, 'text')) { + $type[] = 'clob'; + $type = array_reverse($type); + } + if ($fixed !== false) { + $fixed = true; + } + break; + case 'date': + $type[] = 'date'; + $length = null; + break; + case 'datetime': + case 'timestamp': + $type[] = 'timestamp'; + $length = null; + break; + case 'time': + $type[] = 'time'; + $length = null; + break; + case 'float': + case 'double': + case 'real': + $type[] = 'float'; + break; + case 'decimal': + case 'numeric': + $type[] = 'decimal'; + $length = $length.','.$field['decimal']; + break; + case 'tinyblob': + case 'mediumblob': + case 'longblob': + case 'blob': + $type[] = 'blob'; + $length = null; + break; + case 'year': + $type[] = 'integer'; + $type[] = 'date'; + $length = null; + break; + default: + $db =$this->getDBInstance(); + if (PEAR::isError($db)) { + return $db; + } + return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null, + 'unknown database attribute type: '.$db_type, __FUNCTION__); + } + + if ((int)$length <= 0) { + $length = null; + } + + return array($type, $length, $unsigned, $fixed); + } + + // }}} +} + +?>
\ No newline at end of file diff --git a/lib/MDB2/Driver/Function/sqlite3.php b/lib/MDB2/Driver/Function/sqlite3.php new file mode 100644 index 00000000000..0d6b329f0ad --- /dev/null +++ b/lib/MDB2/Driver/Function/sqlite3.php @@ -0,0 +1,161 @@ +<?php +// vim: set et ts=4 sw=4 fdm=marker: +// +----------------------------------------------------------------------+ +// | PHP versions 5 | +// +----------------------------------------------------------------------+ +// | Copyright (c) 2011 Robin Appelman | +// | All rights reserved. | +// +----------------------------------------------------------------------+ +// | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB | +// | API as well as database abstraction for PHP applications. | +// | This LICENSE is in the BSD license style. | +// | | +// | Redistribution and use in source and binary forms, with or without | +// | modification, are permitted provided that the following conditions | +// | are met: | +// | | +// | Redistributions of source code must retain the above copyright | +// | notice, this list of conditions and the following disclaimer. | +// | | +// | Redistributions in binary form must reproduce the above copyright | +// | notice, this list of conditions and the following disclaimer in the | +// | documentation and/or other materials provided with the distribution. | +// | | +// | Neither the name of Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, | +// | Lukas Smith nor the names of his contributors may be used to endorse | +// | or promote products derived from this software without specific prior| +// | written permission. | +// | | +// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | +// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | +// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | +// | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE | +// | REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | +// | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | +// | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS| +// | OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED | +// | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | +// | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY| +// | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | +// | POSSIBILITY OF SUCH DAMAGE. | +// +----------------------------------------------------------------------+ +// | Author: Robin Appelman <icewind1991@gmail.com> | +// +----------------------------------------------------------------------+ +// +// + +require_once('MDB2/Driver/Function/Common.php'); + +/** + * MDB2 SQLite driver for the function modules + * + * @package MDB2 + * @category Database + * @author Lukas Smith <smith@pooteeweet.org> + */ +class MDB2_Driver_Function_sqlite3 extends MDB2_Driver_Function_Common +{ + // {{{ constructor + + /** + * Constructor + */ + function __construct($db_index) + { + parent::__construct($db_index); + // create all sorts of UDFs + } + + // {{{ now() + + /** + * Return string to call a variable with the current timestamp inside an SQL statement + * There are three special variables for current date and time. + * + * @return string to call a variable with the current timestamp + * @access public + */ + function now($type = 'timestamp') + { + switch ($type) { + case 'time': + return 'time(\'now\')'; + case 'date': + return 'date(\'now\')'; + case 'timestamp': + default: + return 'datetime(\'now\')'; + } + } + + // }}} + // {{{ unixtimestamp() + + /** + * return string to call a function to get the unix timestamp from a iso timestamp + * + * @param string $expression + * + * @return string to call a variable with the timestamp + * @access public + */ + function unixtimestamp($expression) + { + return 'strftime("%s",'. $expression.', "utc")'; + } + + // }}} + // {{{ substring() + + /** + * return string to call a function to get a substring inside an SQL statement + * + * @return string to call a function to get a substring + * @access public + */ + function substring($value, $position = 1, $length = null) + { + if (!is_null($length)) { + return "substr($value,$position,$length)"; + } + return "substr($value,$position,length($value))"; + } + + // }}} + // {{{ random() + + /** + * return string to call a function to get random value inside an SQL statement + * + * @return return string to generate float between 0 and 1 + * @access public + */ + function random() + { + return '((RANDOM()+2147483648)/4294967296)'; + } + + // }}} + // {{{ replace() + + /** + * return string to call a function to get a replacement inside an SQL statement. + * + * @return string to call a function to get a replace + * @access public + */ + function replace($str, $from_str, $to_str) + { + $db =& $this->getDBInstance(); + if (PEAR::isError($db)) { + return $db; + } + + $error =& $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null, + 'method not implemented', __FUNCTION__); + return $error; + } + + // }}} +} +?> diff --git a/lib/MDB2/Driver/Manager/sqlite3.php b/lib/MDB2/Driver/Manager/sqlite3.php new file mode 100644 index 00000000000..7096126a523 --- /dev/null +++ b/lib/MDB2/Driver/Manager/sqlite3.php @@ -0,0 +1,1364 @@ +<?php +// vim: set et ts=4 sw=4 fdm=marker: +// +----------------------------------------------------------------------+ +// | PHP versions 5 | +// +----------------------------------------------------------------------+ +// | Copyright (c) 2011 Robin Appelman | +// | All rights reserved. | +// +----------------------------------------------------------------------+ +// | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB | +// | API as well as database abstraction for PHP applications. | +// | This LICENSE is in the BSD license style. | +// | | +// | Redistribution and use in source and binary forms, with or without | +// | modification, are permitted provided that the following conditions | +// | are met: | +// | | +// | Redistributions of source code must retain the above copyright | +// | notice, this list of conditions and the following disclaimer. | +// | | +// | Redistributions in binary form must reproduce the above copyright | +// | notice, this list of conditions and the following disclaimer in the | +// | documentation and/or other materials provided with the distribution. | +// | | +// | Neither the name of Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, | +// | Lukas Smith nor the names of his contributors may be used to endorse | +// | or promote products derived from this software without specific prior| +// | written permission. | +// | | +// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | +// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | +// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | +// | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE | +// | REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | +// | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | +// | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS| +// | OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED | +// | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | +// | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY| +// | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | +// | POSSIBILITY OF SUCH DAMAGE. | +// +----------------------------------------------------------------------+ +// | Author: Robin Appelman <icewind1991@gmail.com> | +// +----------------------------------------------------------------------+ +// +// + +require_once('MDB2/Driver/Manager/Common.php'); + +/** + * MDB2 SQLite driver for the management modules + * + * @package MDB2 + * @category Database + * @author Lukas Smith <smith@pooteeweet.org> + * @author Lorenzo Alberton <l.alberton@quipo.it> + */ +class MDB2_Driver_Manager_sqlite3 extends MDB2_Driver_Manager_Common +{ + // {{{ createDatabase() + + /** + * create a new database + * + * @param string $name name of the database that should be created + * @param array $options array with charset info + * + * @return mixed MDB2_OK on success, a MDB2 error on failure + * @access public + */ + function createDatabase($name, $options = array()) + { + global $SERVERROOT; + $datadir=OC_CONFIG::getValue( "datadirectory", "$SERVERROOT/data" ); + $db =$this->getDBInstance(); + if (PEAR::isError($db)) { + return $db; + } + + $database_file = $db->_getDatabaseFile($name); + if (file_exists($database_file)) { + return $db->raiseError(MDB2_ERROR_ALREADY_EXISTS, null, null, + 'database already exists', __FUNCTION__); + } + $php_errormsg = ''; + $database_file="$datadir/$database_file.db"; + $handle=new SQLite3($database_file); + if (!$handle) { + return $db->raiseError(MDB2_ERROR_CANNOT_CREATE, null, null, + (isset($php_errormsg) ? $php_errormsg : 'could not create the database file'), __FUNCTION__); + } + //sqlite doesn't support the latin1 we use +// if (!empty($options['charset'])) { +// $query = 'PRAGMA encoding = ' . $db->quote($options['charset'], 'text'); +// $handle->exec($query); +// } + $handle->close(); + return MDB2_OK; + } + + // }}} + // {{{ dropDatabase() + + /** + * drop an existing database + * + * @param string $name name of the database that should be dropped + * @return mixed MDB2_OK on success, a MDB2 error on failure + * @access public + */ + function dropDatabase($name) + { + $db =$this->getDBInstance(); + if (PEAR::isError($db)) { + return $db; + } + + $database_file = $db->_getDatabaseFile($name); + if (!@file_exists($database_file)) { + return $db->raiseError(MDB2_ERROR_CANNOT_DROP, null, null, + 'database does not exist', __FUNCTION__); + } + $result = @unlink($database_file); + if (!$result) { + return $db->raiseError(MDB2_ERROR_CANNOT_DROP, null, null, + (isset($php_errormsg) ? $php_errormsg : 'could not remove the database file'), __FUNCTION__); + } + return MDB2_OK; + } + + // }}} + // {{{ _getAdvancedFKOptions() + + /** + * Return the FOREIGN KEY query section dealing with non-standard options + * as MATCH, INITIALLY DEFERRED, ON UPDATE, ... + * + * @param array $definition + * @return string + * @access protected + */ + function _getAdvancedFKOptions($definition) + { + $query = ''; + if (!empty($definition['match'])) { + $query .= ' MATCH '.$definition['match']; + } + if (!empty($definition['onupdate']) && (strtoupper($definition['onupdate']) != 'NO ACTION')) { + $query .= ' ON UPDATE '.$definition['onupdate']; + } + if (!empty($definition['ondelete']) && (strtoupper($definition['ondelete']) != 'NO ACTION')) { + $query .= ' ON DELETE '.$definition['ondelete']; + } + if (!empty($definition['deferrable'])) { + $query .= ' DEFERRABLE'; + } else { + $query .= ' NOT DEFERRABLE'; + } + if (!empty($definition['initiallydeferred'])) { + $query .= ' INITIALLY DEFERRED'; + } else { + $query .= ' INITIALLY IMMEDIATE'; + } + return $query; + } + + // }}} + // {{{ _getCreateTableQuery() + + /** + * Create a basic SQL query for a new table creation + * @param string $name Name of the database that should be created + * @param array $fields Associative array that contains the definition of each field of the new table + * @param array $options An associative array of table options + * @return mixed string (the SQL query) on success, a MDB2 error on failure + * @see createTable() + */ + function _getCreateTableQuery($name, $fields, $options = array()) + { + $db =$this->getDBInstance(); + if (PEAR::isError($db)) { + return $db; + } + + if (!$name) { + return $db->raiseError(MDB2_ERROR_CANNOT_CREATE, null, null, + 'no valid table name specified', __FUNCTION__); + } + if (empty($fields)) { + return $db->raiseError(MDB2_ERROR_CANNOT_CREATE, null, null, + 'no fields specified for table "'.$name.'"', __FUNCTION__); + } + $query_fields = $this->getFieldDeclarationList($fields); + if (PEAR::isError($query_fields)) { + return $query_fields; + } + if (!empty($options['primary'])) { + $query_fields.= ', PRIMARY KEY ('.implode(', ', array_keys($options['primary'])).')'; + } + if (!empty($options['foreign_keys'])) { + foreach ($options['foreign_keys'] as $fkname => $fkdef) { + if (empty($fkdef)) { + continue; + } + $query_fields.= ', CONSTRAINT '.$fkname.' FOREIGN KEY ('.implode(', ', array_keys($fkdef['fields'])).')'; + $query_fields.= ' REFERENCES '.$fkdef['references']['table'].' ('.implode(', ', array_keys($fkdef['references']['fields'])).')'; + $query_fields.= $this->_getAdvancedFKOptions($fkdef); + } + } + + $name = $db->quoteIdentifier($name, true); + $result = 'CREATE '; + if (!empty($options['temporary'])) { + $result .= $this->_getTemporaryTableQuery(); + } + $result .= " TABLE $name ($query_fields)"; + return $result; + } + + // }}} + // {{{ createTable() + + /** + * create a new table + * + * @param string $name Name of the database that should be created + * @param array $fields Associative array that contains the definition + * of each field of the new table + * @param array $options An associative array of table options + * + * @return mixed MDB2_OK on success, a MDB2 error on failure + * @access public + */ + function createTable($name, $fields, $options = array()) + { + $result = parent::createTable($name, $fields, $options); + if (PEAR::isError($result)) { + return $result; + } + // create triggers to enforce FOREIGN KEY constraints + if (!empty($options['foreign_keys'])) { + $db =$this->getDBInstance(); + if (PEAR::isError($db)) { + return $db; + } + foreach ($options['foreign_keys'] as $fkname => $fkdef) { + if (empty($fkdef)) { + continue; + } + //set actions to default if not set + $fkdef['onupdate'] = empty($fkdef['onupdate']) ? $db->options['default_fk_action_onupdate'] : strtoupper($fkdef['onupdate']); + $fkdef['ondelete'] = empty($fkdef['ondelete']) ? $db->options['default_fk_action_ondelete'] : strtoupper($fkdef['ondelete']); + + $trigger_names = array( + 'insert' => $fkname.'_insert_trg', + 'update' => $fkname.'_update_trg', + 'pk_update' => $fkname.'_pk_update_trg', + 'pk_delete' => $fkname.'_pk_delete_trg', + ); + + //create the [insert|update] triggers on the FK table + $table_fields = array_keys($fkdef['fields']); + $referenced_fields = array_keys($fkdef['references']['fields']); + $query = 'CREATE TRIGGER %s BEFORE %s ON '.$name + .' FOR EACH ROW BEGIN' + .' SELECT RAISE(ROLLBACK, \'%s on table "'.$name.'" violates FOREIGN KEY constraint "'.$fkname.'"\')' + .' WHERE (SELECT '; + $aliased_fields = array(); + foreach ($referenced_fields as $field) { + $aliased_fields[] = $fkdef['references']['table'] .'.'.$field .' AS '.$field; + } + $query .= implode(',', $aliased_fields) + .' FROM '.$fkdef['references']['table'] + .' WHERE '; + $conditions = array(); + for ($i=0; $i<count($table_fields); $i++) { + $conditions[] = $referenced_fields[$i] .' = NEW.'.$table_fields[$i]; + } + $query .= implode(' AND ', $conditions).') IS NULL; END;'; + $result = $db->exec(sprintf($query, $trigger_names['insert'], 'INSERT', 'insert')); + if (PEAR::isError($result)) { + return $result; + } + + $result = $db->exec(sprintf($query, $trigger_names['update'], 'UPDATE', 'update')); + if (PEAR::isError($result)) { + return $result; + } + + //create the ON [UPDATE|DELETE] triggers on the primary table + $restrict_action = 'SELECT RAISE(ROLLBACK, \'%s on table "'.$name.'" violates FOREIGN KEY constraint "'.$fkname.'"\')' + .' WHERE (SELECT '; + $aliased_fields = array(); + foreach ($table_fields as $field) { + $aliased_fields[] = $name .'.'.$field .' AS '.$field; + } + $restrict_action .= implode(',', $aliased_fields) + .' FROM '.$name + .' WHERE '; + $conditions = array(); + $new_values = array(); + $null_values = array(); + for ($i=0; $i<count($table_fields); $i++) { + $conditions[] = $table_fields[$i] .' = OLD.'.$referenced_fields[$i]; + $new_values[] = $table_fields[$i] .' = NEW.'.$referenced_fields[$i]; + $null_values[] = $table_fields[$i] .' = NULL'; + } + $conditions2 = array(); + for ($i=0; $i<count($referenced_fields); $i++) { + $conditions2[] = 'NEW.'.$referenced_fields[$i] .' <> OLD.'.$referenced_fields[$i]; + } + $restrict_action .= implode(' AND ', $conditions).') IS NOT NULL' + .' AND (' .implode(' OR ', $conditions2) .')'; + + $cascade_action_update = 'UPDATE '.$name.' SET '.implode(', ', $new_values) .' WHERE '.implode(' AND ', $conditions); + $cascade_action_delete = 'DELETE FROM '.$name.' WHERE '.implode(' AND ', $conditions); + $setnull_action = 'UPDATE '.$name.' SET '.implode(', ', $null_values).' WHERE '.implode(' AND ', $conditions); + + if ('SET DEFAULT' == $fkdef['onupdate'] || 'SET DEFAULT' == $fkdef['ondelete']) { + $db->loadModule('Reverse', null, true); + $default_values = array(); + foreach ($table_fields as $table_field) { + $field_definition = $db->reverse->getTableFieldDefinition($name, $field); + if (PEAR::isError($field_definition)) { + return $field_definition; + } + $default_values[] = $table_field .' = '. $field_definition[0]['default']; + } + $setdefault_action = 'UPDATE '.$name.' SET '.implode(', ', $default_values).' WHERE '.implode(' AND ', $conditions); + } + + $query = 'CREATE TRIGGER %s' + .' %s ON '.$fkdef['references']['table'] + .' FOR EACH ROW BEGIN '; + + if ('CASCADE' == $fkdef['onupdate']) { + $sql_update = sprintf($query, $trigger_names['pk_update'], 'AFTER UPDATE', 'update') . $cascade_action_update. '; END;'; + } elseif ('SET NULL' == $fkdef['onupdate']) { + $sql_update = sprintf($query, $trigger_names['pk_update'], 'BEFORE UPDATE', 'update') . $setnull_action. '; END;'; + } elseif ('SET DEFAULT' == $fkdef['onupdate']) { + $sql_update = sprintf($query, $trigger_names['pk_update'], 'BEFORE UPDATE', 'update') . $setdefault_action. '; END;'; + } elseif ('NO ACTION' == $fkdef['onupdate']) { + $sql_update = sprintf($query.$restrict_action, $trigger_names['pk_update'], 'AFTER UPDATE', 'update') . '; END;'; + } elseif ('RESTRICT' == $fkdef['onupdate']) { + $sql_update = sprintf($query.$restrict_action, $trigger_names['pk_update'], 'BEFORE UPDATE', 'update') . '; END;'; + } + if ('CASCADE' == $fkdef['ondelete']) { + $sql_delete = sprintf($query, $trigger_names['pk_delete'], 'AFTER DELETE', 'delete') . $cascade_action_delete. '; END;'; + } elseif ('SET NULL' == $fkdef['ondelete']) { + $sql_delete = sprintf($query, $trigger_names['pk_delete'], 'BEFORE DELETE', 'delete') . $setnull_action. '; END;'; + } elseif ('SET DEFAULT' == $fkdef['ondelete']) { + $sql_delete = sprintf($query, $trigger_names['pk_delete'], 'BEFORE DELETE', 'delete') . $setdefault_action. '; END;'; + } elseif ('NO ACTION' == $fkdef['ondelete']) { + $sql_delete = sprintf($query.$restrict_action, $trigger_names['pk_delete'], 'AFTER DELETE', 'delete') . '; END;'; + } elseif ('RESTRICT' == $fkdef['ondelete']) { + $sql_delete = sprintf($query.$restrict_action, $trigger_names['pk_delete'], 'BEFORE DELETE', 'delete') . '; END;'; + } + + if (PEAR::isError($result)) { + return $result; + } + $result = $db->exec($sql_delete); + if (PEAR::isError($result)) { + return $result; + } + $result = $db->exec($sql_update); + if (PEAR::isError($result)) { + return $result; + } + } + } + if (PEAR::isError($result)) { + return $result; + } + return MDB2_OK; + } + + // }}} + // {{{ dropTable() + + /** + * drop an existing table + * + * @param string $name name of the table that should be dropped + * @return mixed MDB2_OK on success, a MDB2 error on failure + * @access public + */ + function dropTable($name) + { + $db =$this->getDBInstance(); + if (PEAR::isError($db)) { + return $db; + } + + //delete the triggers associated to existing FK constraints + $constraints = $this->listTableConstraints($name); + if (!PEAR::isError($constraints) && !empty($constraints)) { + $db->loadModule('Reverse', null, true); + foreach ($constraints as $constraint) { + $definition = $db->reverse->getTableConstraintDefinition($name, $constraint); + if (!PEAR::isError($definition) && !empty($definition['foreign'])) { + $result = $this->_dropFKTriggers($name, $constraint, $definition['references']['table']); + if (PEAR::isError($result)) { + return $result; + } + } + } + } + + $name = $db->quoteIdentifier($name, true); + return $db->exec("DROP TABLE $name"); + } + + // }}} + // {{{ vacuum() + + /** + * Optimize (vacuum) all the tables in the db (or only the specified table) + * and optionally run ANALYZE. + * + * @param string $table table name (all the tables if empty) + * @param array $options an array with driver-specific options: + * - timeout [int] (in seconds) [mssql-only] + * - analyze [boolean] [pgsql and mysql] + * - full [boolean] [pgsql-only] + * - freeze [boolean] [pgsql-only] + * + * @return mixed MDB2_OK success, a MDB2 error on failure + * @access public + */ + function vacuum($table = null, $options = array()) + { + $db =$this->getDBInstance(); + if (PEAR::isError($db)) { + return $db; + } + + $query = 'VACUUM'; + if (!empty($table)) { + $query .= ' '.$db->quoteIdentifier($table, true); + } + return $db->exec($query); + } + + // }}} + // {{{ alterTable() + + /** + * alter an existing table + * + * @param string $name name of the table that is intended to be changed. + * @param array $changes associative array that contains the details of each type + * of change that is intended to be performed. The types of + * changes that are currently supported are defined as follows: + * + * name + * + * New name for the table. + * + * add + * + * Associative array with the names of fields to be added as + * indexes of the array. The value of each entry of the array + * should be set to another associative array with the properties + * of the fields to be added. The properties of the fields should + * be the same as defined by the MDB2 parser. + * + * + * remove + * + * Associative array with the names of fields to be removed as indexes + * of the array. Currently the values assigned to each entry are ignored. + * An empty array should be used for future compatibility. + * + * rename + * + * Associative array with the names of fields to be renamed as indexes + * of the array. The value of each entry of the array should be set to + * another associative array with the entry named name with the new + * field name and the entry named Declaration that is expected to contain + * the portion of the field declaration already in DBMS specific SQL code + * as it is used in the CREATE TABLE statement. + * + * change + * + * Associative array with the names of the fields to be changed as indexes + * of the array. Keep in mind that if it is intended to change either the + * name of a field and any other properties, the change array entries + * should have the new names of the fields as array indexes. + * + * The value of each entry of the array should be set to another associative + * array with the properties of the fields to that are meant to be changed as + * array entries. These entries should be assigned to the new values of the + * respective properties. The properties of the fields should be the same + * as defined by the MDB2 parser. + * + * Example + * array( + * 'name' => 'userlist', + * 'add' => array( + * 'quota' => array( + * 'type' => 'integer', + * 'unsigned' => 1 + * ) + * ), + * 'remove' => array( + * 'file_limit' => array(), + * 'time_limit' => array() + * ), + * 'change' => array( + * 'name' => array( + * 'length' => '20', + * 'definition' => array( + * 'type' => 'text', + * 'length' => 20, + * ), + * ) + * ), + * 'rename' => array( + * 'sex' => array( + * 'name' => 'gender', + * 'definition' => array( + * 'type' => 'text', + * 'length' => 1, + * 'default' => 'M', + * ), + * ) + * ) + * ) + * + * @param boolean $check indicates whether the function should just check if the DBMS driver + * can perform the requested table alterations if the value is true or + * actually perform them otherwise. + * @access public + * + * @return mixed MDB2_OK on success, a MDB2 error on failure + */ + function alterTable($name, $changes, $check, $options = array()) + { + $db =$this->getDBInstance(); + if (PEAR::isError($db)) { + return $db; + } + + foreach ($changes as $change_name => $change) { + switch ($change_name) { + case 'add': + case 'remove': + case 'change': + case 'name': + case 'rename': + break; + default: + return $db->raiseError(MDB2_ERROR_CANNOT_ALTER, null, null, + 'change type "'.$change_name.'" not yet supported', __FUNCTION__); + } + } + + if ($check) { + return MDB2_OK; + } + + $db->loadModule('Reverse', null, true); + + // actually sqlite 2.x supports no ALTER TABLE at all .. so we emulate it + $fields = $db->manager->listTableFields($name); + if (PEAR::isError($fields)) { + return $fields; + } + + $fields = array_flip($fields); + foreach ($fields as $field => $value) { + $definition = $db->reverse->getTableFieldDefinition($name, $field); + if (PEAR::isError($definition)) { + return $definition; + } + $fields[$field] = $definition[0]; + } + + $indexes = $db->manager->listTableIndexes($name); + if (PEAR::isError($indexes)) { + return $indexes; + } + + $indexes = array_flip($indexes); + foreach ($indexes as $index => $value) { + $definition = $db->reverse->getTableIndexDefinition($name, $index); + if (PEAR::isError($definition)) { + return $definition; + } + $indexes[$index] = $definition; + } + + $constraints = $db->manager->listTableConstraints($name); + if (PEAR::isError($constraints)) { + return $constraints; + } + + if (!array_key_exists('foreign_keys', $options)) { + $options['foreign_keys'] = array(); + } + $constraints = array_flip($constraints); + foreach ($constraints as $constraint => $value) { + if (!empty($definition['primary'])) { + if (!array_key_exists('primary', $options)) { + $options['primary'] = $definition['fields']; + //remove from the $constraint array, it's already handled by createTable() + unset($constraints[$constraint]); + } + } else { + $c_definition = $db->reverse->getTableConstraintDefinition($name, $constraint); + if (PEAR::isError($c_definition)) { + return $c_definition; + } + if (!empty($c_definition['foreign'])) { + if (!array_key_exists($constraint, $options['foreign_keys'])) { + $options['foreign_keys'][$constraint] = $c_definition; + } + //remove from the $constraint array, it's already handled by createTable() + unset($constraints[$constraint]); + } else { + $constraints[$constraint] = $c_definition; + } + } + } + + $name_new = $name; + $create_order = $select_fields = array_keys($fields); + foreach ($changes as $change_name => $change) { + switch ($change_name) { + case 'add': + foreach ($change as $field_name => $field) { + $fields[$field_name] = $field; + $create_order[] = $field_name; + } + break; + case 'remove': + foreach ($change as $field_name => $field) { + unset($fields[$field_name]); + $select_fields = array_diff($select_fields, array($field_name)); + $create_order = array_diff($create_order, array($field_name)); + } + break; + case 'change': + foreach ($change as $field_name => $field) { + $fields[$field_name] = $field['definition']; + } + break; + case 'name': + $name_new = $change; + break; + case 'rename': + foreach ($change as $field_name => $field) { + unset($fields[$field_name]); + $fields[$field['name']] = $field['definition']; + $create_order[array_search($field_name, $create_order)] = $field['name']; + } + break; + default: + return $db->raiseError(MDB2_ERROR_CANNOT_ALTER, null, null, + 'change type "'.$change_name.'" not yet supported', __FUNCTION__); + } + } + + $data = null; + if (!empty($select_fields)) { + $query = 'SELECT '.implode(', ', $select_fields).' FROM '.$db->quoteIdentifier($name, true); + $data = $db->queryAll($query, null, MDB2_FETCHMODE_ORDERED); + } + + $result = $this->dropTable($name); + if (PEAR::isError($result)) { + return $result; + } + + $result = $this->createTable($name_new, $fields, $options); + if (PEAR::isError($result)) { + return $result; + } + + foreach ($indexes as $index => $definition) { + $this->createIndex($name_new, $index, $definition); + } + + foreach ($constraints as $constraint => $definition) { + $this->createConstraint($name_new, $constraint, $definition); + } + + if (!empty($select_fields) && !empty($data)) { + $query = 'INSERT INTO '.$db->quoteIdentifier($name_new, true); + $query.= '('.implode(', ', array_slice(array_keys($fields), 0, count($select_fields))).')'; + $query.=' VALUES (?'.str_repeat(', ?', (count($select_fields) - 1)).')'; + $stmt =$db->prepare($query, null, MDB2_PREPARE_MANIP); + if (PEAR::isError($stmt)) { + return $stmt; + } + foreach ($data as $row) { + $result = $stmt->execute($row); + if (PEAR::isError($result)) { + return $result; + } + } + } + return MDB2_OK; + } + + // }}} + // {{{ listDatabases() + + /** + * list all databases + * + * @return mixed array of database names on success, a MDB2 error on failure + * @access public + */ + function listDatabases() + { + $db =$this->getDBInstance(); + if (PEAR::isError($db)) { + return $db; + } + + return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null, + 'list databases is not supported', __FUNCTION__); + } + + // }}} + // {{{ listUsers() + + /** + * list all users + * + * @return mixed array of user names on success, a MDB2 error on failure + * @access public + */ + function listUsers() + { + $db =$this->getDBInstance(); + if (PEAR::isError($db)) { + return $db; + } + + return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null, + 'list databases is not supported', __FUNCTION__); + } + + // }}} + // {{{ listViews() + + /** + * list all views in the current database + * + * @return mixed array of view names on success, a MDB2 error on failure + * @access public + */ + function listViews($dummy=null) + { + $db =$this->getDBInstance(); + if (PEAR::isError($db)) { + return $db; + } + + $query = "SELECT name FROM sqlite_master WHERE type='view' AND sql NOT NULL"; + $result = $db->queryCol($query); + if (PEAR::isError($result)) { + return $result; + } + if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) { + $result = array_map(($db->options['field_case'] == CASE_LOWER ? 'strtolower' : 'strtoupper'), $result); + } + return $result; + } + + // }}} + // {{{ listTableViews() + + /** + * list the views in the database that reference a given table + * + * @param string table for which all referenced views should be found + * @return mixed array of view names on success, a MDB2 error on failure + * @access public + */ + function listTableViews($table) + { + $db =$this->getDBInstance(); + if (PEAR::isError($db)) { + return $db; + } + + $query = "SELECT name, sql FROM sqlite_master WHERE type='view' AND sql NOT NULL"; + $views = $db->queryAll($query, array('text', 'text'), MDB2_FETCHMODE_ASSOC); + if (PEAR::isError($views)) { + return $views; + } + $result = array(); + foreach ($views as $row) { + if (preg_match("/^create view .* \bfrom\b\s+\b{$table}\b /i", $row['sql'])) { + if (!empty($row['name'])) { + $result[$row['name']] = true; + } + } + } + + if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) { + $result = array_change_key_case($result, $db->options['field_case']); + } + return array_keys($result); + } + + // }}} + // {{{ listTables() + + /** + * list all tables in the current database + * + * @return mixed array of table names on success, a MDB2 error on failure + * @access public + */ + function listTables($dummy=null) + { + $db =$this->getDBInstance(); + if (PEAR::isError($db)) { + return $db; + } + + $query = "SELECT name FROM sqlite_master WHERE type='table' AND sql NOT NULL ORDER BY name"; + $table_names = $db->queryCol($query); + if (PEAR::isError($table_names)) { + return $table_names; + } + $result = array(); + foreach ($table_names as $table_name) { + if (!$this->_fixSequenceName($table_name, true)) { + $result[] = $table_name; + } + } + if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) { + $result = array_map(($db->options['field_case'] == CASE_LOWER ? 'strtolower' : 'strtoupper'), $result); + } + return $result; + } + + // }}} + // {{{ listTableFields() + + /** + * list all fields in a table in the current database + * + * @param string $table name of table that should be used in method + * @return mixed array of field names on success, a MDB2 error on failure + * @access public + */ + function listTableFields($table) + { + $db =$this->getDBInstance(); + if (PEAR::isError($db)) { + return $db; + } + + $result = $db->loadModule('Reverse', null, true); + if (PEAR::isError($result)) { + return $result; + } + $query = "SELECT sql FROM sqlite_master WHERE type='table' AND "; + if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) { + $query.= 'LOWER(name)='.$db->quote(strtolower($table), 'text'); + } else { + $query.= 'name='.$db->quote($table, 'text'); + } + $sql = $db->queryOne($query); + if (PEAR::isError($sql)) { + return $sql; + } + $columns = $db->reverse->_getTableColumns($sql); + $fields = array(); + foreach ($columns as $column) { + if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) { + if ($db->options['field_case'] == CASE_LOWER) { + $column['name'] = strtolower($column['name']); + } else { + $column['name'] = strtoupper($column['name']); + } + } else { + $column = array_change_key_case($column, $db->options['field_case']); + } + $fields[] = $column['name']; + } + return $fields; + } + + // }}} + // {{{ listTableTriggers() + + /** + * list all triggers in the database that reference a given table + * + * @param string table for which all referenced triggers should be found + * @return mixed array of trigger names on success, a MDB2 error on failure + * @access public + */ + function listTableTriggers($table = null) + { + $db =$this->getDBInstance(); + if (PEAR::isError($db)) { + return $db; + } + + $query = "SELECT name FROM sqlite_master WHERE type='trigger' AND sql NOT NULL"; + if (!is_null($table)) { + if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) { + $query.= ' AND LOWER(tbl_name)='.$db->quote(strtolower($table), 'text'); + } else { + $query.= ' AND tbl_name='.$db->quote($table, 'text'); + } + } + $result = $db->queryCol($query); + if (PEAR::isError($result)) { + return $result; + } + if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) { + $result = array_map(($db->options['field_case'] == CASE_LOWER ? 'strtolower' : 'strtoupper'), $result); + } + return $result; + } + + // }}} + // {{{ createIndex() + + /** + * Get the stucture of a field into an array + * + * @param string $table name of the table on which the index is to be created + * @param string $name name of the index to be created + * @param array $definition associative array that defines properties of the index to be created. + * Currently, only one property named FIELDS is supported. This property + * is also an associative with the names of the index fields as array + * indexes. Each entry of this array is set to another type of associative + * array that specifies properties of the index that are specific to + * each field. + * + * Currently, only the sorting property is supported. It should be used + * to define the sorting direction of the index. It may be set to either + * ascending or descending. + * + * Not all DBMS support index sorting direction configuration. The DBMS + * drivers of those that do not support it ignore this property. Use the + * function support() to determine whether the DBMS driver can manage indexes. + + * Example + * array( + * 'fields' => array( + * 'user_name' => array( + * 'sorting' => 'ascending' + * ), + * 'last_login' => array() + * ) + * ) + * @return mixed MDB2_OK on success, a MDB2 error on failure + * @access public + */ + function createIndex($table, $name, $definition) + { + $db =$this->getDBInstance(); + if (PEAR::isError($db)) { + return $db; + } + + $table = $db->quoteIdentifier($table, true); + $name = $db->getIndexName($name); + $query = "CREATE INDEX $name ON $table"; + $fields = array(); + foreach ($definition['fields'] as $field_name => $field) { + $field_string = $field_name; + if (!empty($field['sorting'])) { + switch ($field['sorting']) { + case 'ascending': + $field_string.= ' ASC'; + break; + case 'descending': + $field_string.= ' DESC'; + break; + } + } + $fields[] = $field_string; + } + $query .= ' ('.implode(', ', $fields) . ')'; + return $db->exec($query); + } + + // }}} + // {{{ dropIndex() + + /** + * drop existing index + * + * @param string $table name of table that should be used in method + * @param string $name name of the index to be dropped + * @return mixed MDB2_OK on success, a MDB2 error on failure + * @access public + */ + function dropIndex($table, $name) + { + $db =$this->getDBInstance(); + if (PEAR::isError($db)) { + return $db; + } + + $name = $db->getIndexName($name); + return $db->exec("DROP INDEX $name"); + } + + // }}} + // {{{ listTableIndexes() + + /** + * list all indexes in a table + * + * @param string $table name of table that should be used in method + * @return mixed array of index names on success, a MDB2 error on failure + * @access public + */ + function listTableIndexes($table) + { + $db =$this->getDBInstance(); + if (PEAR::isError($db)) { + return $db; + } + + $table = $db->quote($table, 'text'); + $query = "SELECT sql FROM sqlite_master WHERE type='index' AND "; + if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) { + $query.= 'LOWER(tbl_name)='.strtolower($table); + } else { + $query.= "tbl_name=$table"; + } + $query.= " AND sql NOT NULL ORDER BY name"; + $indexes = $db->queryCol($query, 'text'); + if (PEAR::isError($indexes)) { + return $indexes; + } + + $result = array(); + foreach ($indexes as $sql) { + if (preg_match("/^create index ([^ ]+) on /i", $sql, $tmp)) { + $index = $this->_fixIndexName($tmp[1]); + if (!empty($index)) { + $result[$index] = true; + } + } + } + + if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) { + $result = array_change_key_case($result, $db->options['field_case']); + } + return array_keys($result); + } + + // }}} + // {{{ createConstraint() + + /** + * create a constraint on a table + * + * @param string $table name of the table on which the constraint is to be created + * @param string $name name of the constraint to be created + * @param array $definition associative array that defines properties of the constraint to be created. + * Currently, only one property named FIELDS is supported. This property + * is also an associative with the names of the constraint fields as array + * constraints. Each entry of this array is set to another type of associative + * array that specifies properties of the constraint that are specific to + * each field. + * + * Example + * array( + * 'fields' => array( + * 'user_name' => array(), + * 'last_login' => array() + * ) + * ) + * @return mixed MDB2_OK on success, a MDB2 error on failure + * @access public + */ + function createConstraint($table, $name, $definition) + { + $db =$this->getDBInstance(); + if (PEAR::isError($db)) { + return $db; + } + + if (!empty($definition['primary'])) { + return $db->manager->alterTable($table, array(), false, array('primary' => $definition['fields'])); + } + + if (!empty($definition['foreign'])) { + return $db->manager->alterTable($table, array(), false, array('foreign_keys' => array($name => $definition))); + } + + $table = $db->quoteIdentifier($table, true); + $name = $db->getIndexName($name); + $query = "CREATE UNIQUE INDEX $name ON $table"; + $fields = array(); + foreach ($definition['fields'] as $field_name => $field) { + $field_string = $field_name; + if (!empty($field['sorting'])) { + switch ($field['sorting']) { + case 'ascending': + $field_string.= ' ASC'; + break; + case 'descending': + $field_string.= ' DESC'; + break; + } + } + $fields[] = $field_string; + } + $query .= ' ('.implode(', ', $fields) . ')'; + return $db->exec($query); + } + + // }}} + // {{{ dropConstraint() + + /** + * drop existing constraint + * + * @param string $table name of table that should be used in method + * @param string $name name of the constraint to be dropped + * @param string $primary hint if the constraint is primary + * @return mixed MDB2_OK on success, a MDB2 error on failure + * @access public + */ + function dropConstraint($table, $name, $primary = false) + { + if ($primary || $name == 'PRIMARY') { + return $this->alterTable($table, array(), false, array('primary' => null)); + } + + $db =$this->getDBInstance(); + if (PEAR::isError($db)) { + return $db; + } + + //is it a FK constraint? If so, also delete the associated triggers + $db->loadModule('Reverse', null, true); + $definition = $db->reverse->getTableConstraintDefinition($table, $name); + if (!PEAR::isError($definition) && !empty($definition['foreign'])) { + //first drop the FK enforcing triggers + $result = $this->_dropFKTriggers($table, $name, $definition['references']['table']); + if (PEAR::isError($result)) { + return $result; + } + //then drop the constraint itself + return $this->alterTable($table, array(), false, array('foreign_keys' => array($name => null))); + } + + $name = $db->getIndexName($name); + return $db->exec("DROP INDEX $name"); + } + + // }}} + // {{{ _dropFKTriggers() + + /** + * Drop the triggers created to enforce the FOREIGN KEY constraint on the table + * + * @param string $table table name + * @param string $fkname FOREIGN KEY constraint name + * @param string $referenced_table referenced table name + * + * @return mixed MDB2_OK on success, a MDB2 error on failure + * @access private + */ + function _dropFKTriggers($table, $fkname, $referenced_table) + { + $db =$this->getDBInstance(); + if (PEAR::isError($db)) { + return $db; + } + + $triggers = $this->listTableTriggers($table); + $triggers2 = $this->listTableTriggers($referenced_table); + if (!PEAR::isError($triggers2) && !PEAR::isError($triggers)) { + $triggers = array_merge($triggers, $triggers2); + $pattern = '/^'.$fkname.'(_pk)?_(insert|update|delete)_trg$/i'; + foreach ($triggers as $trigger) { + if (preg_match($pattern, $trigger)) { + $result = $db->exec('DROP TRIGGER '.$trigger); + if (PEAR::isError($result)) { + return $result; + } + } + } + } + return MDB2_OK; + } + + // }}} + // {{{ listTableConstraints() + + /** + * list all constraints in a table + * + * @param string $table name of table that should be used in method + * @return mixed array of constraint names on success, a MDB2 error on failure + * @access public + */ + function listTableConstraints($table) + { + $db =$this->getDBInstance(); + if (PEAR::isError($db)) { + return $db; + } + + $table = $db->quote($table, 'text'); + $query = "SELECT sql FROM sqlite_master WHERE type='index' AND "; + if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) { + $query.= 'LOWER(tbl_name)='.strtolower($table); + } else { + $query.= "tbl_name=$table"; + } + $query.= " AND sql NOT NULL ORDER BY name"; + $indexes = $db->queryCol($query, 'text'); + if (PEAR::isError($indexes)) { + return $indexes; + } + + $result = array(); + foreach ($indexes as $sql) { + if (preg_match("/^create unique index ([^ ]+) on /i", $sql, $tmp)) { + $index = $this->_fixIndexName($tmp[1]); + if (!empty($index)) { + $result[$index] = true; + } + } + } + + // also search in table definition for PRIMARY KEYs... + $query = "SELECT sql FROM sqlite_master WHERE type='table' AND "; + if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) { + $query.= 'LOWER(name)='.strtolower($table); + } else { + $query.= "name=$table"; + } + $query.= " AND sql NOT NULL ORDER BY name"; + $table_def = $db->queryOne($query, 'text'); + if (PEAR::isError($table_def)) { + return $table_def; + } + if (preg_match("/\bPRIMARY\s+KEY\b/i", $table_def, $tmp)) { + $result['primary'] = true; + } + + // ...and for FOREIGN KEYs + if (preg_match_all("/\bCONSTRAINT\b\s+([^\s]+)\s+\bFOREIGN\s+KEY/imsx", $table_def, $tmp)) { + foreach ($tmp[1] as $fk) { + $result[$fk] = true; + } + } + + if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) { + $result = array_change_key_case($result, $db->options['field_case']); + } + return array_keys($result); + } + + // }}} + // {{{ createSequence() + + /** + * create sequence + * + * @param string $seq_name name of the sequence to be created + * @param string $start start value of the sequence; default is 1 + * @return mixed MDB2_OK on success, a MDB2 error on failure + * @access public + */ + function createSequence($seq_name, $start = 1) + { + $db =$this->getDBInstance(); + if (PEAR::isError($db)) { + return $db; + } + + $sequence_name = $db->quoteIdentifier($db->getSequenceName($seq_name), true); + $seqcol_name = $db->quoteIdentifier($db->options['seqcol_name'], true); + $query = "CREATE TABLE $sequence_name ($seqcol_name INTEGER PRIMARY KEY DEFAULT 0 NOT NULL)"; + $res = $db->exec($query); + if (PEAR::isError($res)) { + return $res; + } + if ($start == 1) { + return MDB2_OK; + } + $res = $db->exec("INSERT INTO $sequence_name ($seqcol_name) VALUES (".($start-1).')'); + if (!PEAR::isError($res)) { + return MDB2_OK; + } + // Handle error + $result = $db->exec("DROP TABLE $sequence_name"); + if (PEAR::isError($result)) { + return $db->raiseError($result, null, null, + 'could not drop inconsistent sequence table', __FUNCTION__); + } + return $db->raiseError($res, null, null, + 'could not create sequence table', __FUNCTION__); + } + + // }}} + // {{{ dropSequence() + + /** + * drop existing sequence + * + * @param string $seq_name name of the sequence to be dropped + * @return mixed MDB2_OK on success, a MDB2 error on failure + * @access public + */ + function dropSequence($seq_name) + { + $db =$this->getDBInstance(); + if (PEAR::isError($db)) { + return $db; + } + + $sequence_name = $db->quoteIdentifier($db->getSequenceName($seq_name), true); + return $db->exec("DROP TABLE $sequence_name"); + } + + // }}} + // {{{ listSequences() + + /** + * list all sequences in the current database + * + * @return mixed array of sequence names on success, a MDB2 error on failure + * @access public + */ + function listSequences($dummy=null) + { + $db =$this->getDBInstance(); + if (PEAR::isError($db)) { + return $db; + } + + $query = "SELECT name FROM sqlite_master WHERE type='table' AND sql NOT NULL ORDER BY name"; + $table_names = $db->queryCol($query); + if (PEAR::isError($table_names)) { + return $table_names; + } + $result = array(); + foreach ($table_names as $table_name) { + if ($sqn = $this->_fixSequenceName($table_name, true)) { + $result[] = $sqn; + } + } + if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) { + $result = array_map(($db->options['field_case'] == CASE_LOWER ? 'strtolower' : 'strtoupper'), $result); + } + return $result; + } + + // }}} +} +?>
\ No newline at end of file diff --git a/lib/MDB2/Driver/Native/sqlite3.php b/lib/MDB2/Driver/Native/sqlite3.php new file mode 100644 index 00000000000..81dc67dea65 --- /dev/null +++ b/lib/MDB2/Driver/Native/sqlite3.php @@ -0,0 +1,58 @@ +<?php +// vim: set et ts=4 sw=4 fdm=marker: +// +----------------------------------------------------------------------+ +// | PHP versions 5 | +// +----------------------------------------------------------------------+ +// | Copyright (c) 2011 Robin Appelman | +// | All rights reserved. | +// +----------------------------------------------------------------------+ +// | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB | +// | API as well as database abstraction for PHP applications. | +// | This LICENSE is in the BSD license style. | +// | | +// | Redistribution and use in source and binary forms, with or without | +// | modification, are permitted provided that the following conditions | +// | are met: | +// | | +// | Redistributions of source code must retain the above copyright | +// | notice, this list of conditions and the following disclaimer. | +// | | +// | Redistributions in binary form must reproduce the above copyright | +// | notice, this list of conditions and the following disclaimer in the | +// | documentation and/or other materials provided with the distribution. | +// | | +// | Neither the name of Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, | +// | Lukas Smith nor the names of his contributors may be used to endorse | +// | or promote products derived from this software without specific prior| +// | written permission. | +// | | +// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | +// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | +// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | +// | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE | +// | REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | +// | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | +// | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS| +// | OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED | +// | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | +// | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY| +// | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | +// | POSSIBILITY OF SUCH DAMAGE. | +// +----------------------------------------------------------------------+ +// | Author: Robin Appelman <icewind1991@gmail.com> | +// +----------------------------------------------------------------------+ +// +// +require_once 'MDB2/Driver/Native/Common.php'; + +/** + * MDB2 SQLite driver for the native module + * + * @package MDB2 + * @category Database + * @author Lukas Smith <smith@pooteeweet.org> + */ +class MDB2_Driver_Native_sqlite extends MDB2_Driver_Native_Common +{ +} +?>
\ No newline at end of file diff --git a/lib/MDB2/Driver/Reverse/sqlite3.php b/lib/MDB2/Driver/Reverse/sqlite3.php new file mode 100644 index 00000000000..d488977b158 --- /dev/null +++ b/lib/MDB2/Driver/Reverse/sqlite3.php @@ -0,0 +1,607 @@ +<?php +// vim: set et ts=4 sw=4 fdm=marker: +// +----------------------------------------------------------------------+ +// | PHP versions 5 | +// +----------------------------------------------------------------------+ +// | Copyright (c) 2011 Robin Appelman | +// | All rights reserved. | +// +----------------------------------------------------------------------+ +// | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB | +// | API as well as database abstraction for PHP applications. | +// | This LICENSE is in the BSD license style. | +// | | +// | Redistribution and use in source and binary forms, with or without | +// | modification, are permitted provided that the following conditions | +// | are met: | +// | | +// | Redistributions of source code must retain the above copyright | +// | notice, this list of conditions and the following disclaimer. | +// | | +// | Redistributions in binary form must reproduce the above copyright | +// | notice, this list of conditions and the following disclaimer in the | +// | documentation and/or other materials provided with the distribution. | +// | | +// | Neither the name of Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, | +// | Lukas Smith nor the names of his contributors may be used to endorse | +// | or promote products derived from this software without specific prior| +// | written permission. | +// | | +// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | +// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | +// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | +// | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE | +// | REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | +// | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | +// | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS| +// | OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED | +// | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | +// | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY| +// | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | +// | POSSIBILITY OF SUCH DAMAGE. | +// +----------------------------------------------------------------------+ +// | Author: Robin Appelman <icewind1991@gmail.com> | +// +----------------------------------------------------------------------+ +// +// + +require_once('MDB2/Driver/Reverse/Common.php'); + +/** + * MDB2 SQlite driver for the schema reverse engineering module + * + * @package MDB2 + * @category Database + * @author Lukas Smith <smith@pooteeweet.org> + */ +class MDB2_Driver_Reverse_sqlite3 extends MDB2_Driver_Reverse_Common +{ + /** + * Remove SQL comments from the field definition + * + * @access private + */ + function _removeComments($sql) { + $lines = explode("\n", $sql); + foreach ($lines as $k => $line) { + $pieces = explode('--', $line); + if (count($pieces) > 1 && (substr_count($pieces[0], '\'') % 2) == 0) { + $lines[$k] = substr($line, 0, strpos($line, '--')); + } + } + return implode("\n", $lines); + } + + /** + * + */ + function _getTableColumns($sql) + { + $db =$this->getDBInstance(); + if (PEAR::isError($db)) { + return $db; + } + $start_pos = strpos($sql, '('); + $end_pos = strrpos($sql, ')'); + $column_def = substr($sql, $start_pos+1, $end_pos-$start_pos-1); + // replace the decimal length-places-separator with a colon + $column_def = preg_replace('/(\d),(\d)/', '\1:\2', $column_def); + $column_def = $this->_removeComments($column_def); + $column_sql = explode(',', $column_def); + $columns = array(); + $count = count($column_sql); + if ($count == 0) { + return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null, + 'unexpected empty table column definition list', __FUNCTION__); + } + $regexp = '/^\s*([^\s]+) +(CHAR|VARCHAR|VARCHAR2|TEXT|BOOLEAN|SMALLINT|INT|INTEGER|DECIMAL|BIGINT|DOUBLE|FLOAT|DATETIME|DATE|TIME|LONGTEXT|LONGBLOB)( ?\(([1-9][0-9]*)(:([1-9][0-9]*))?\))?( NULL| NOT NULL)?( UNSIGNED)?( NULL| NOT NULL)?( PRIMARY KEY)?( DEFAULT (\'[^\']*\'|[^ ]+))?( NULL| NOT NULL)?( PRIMARY KEY)?(\s*\-\-.*)?$/i'; + $regexp2 = '/^\s*([^ ]+) +(PRIMARY|UNIQUE|CHECK)$/i'; + for ($i=0, $j=0; $i<$count; ++$i) { + if (!preg_match($regexp, trim($column_sql[$i]), $matches)) { + if (!preg_match($regexp2, trim($column_sql[$i]))) { + continue; + } + return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null, + 'unexpected table column SQL definition: "'.$column_sql[$i].'"', __FUNCTION__); + } + $columns[$j]['name'] = trim($matches[1], implode('', $db->identifier_quoting)); + $columns[$j]['type'] = strtolower($matches[2]); + if (isset($matches[4]) && strlen($matches[4])) { + $columns[$j]['length'] = $matches[4]; + } + if (isset($matches[6]) && strlen($matches[6])) { + $columns[$j]['decimal'] = $matches[6]; + } + if (isset($matches[8]) && strlen($matches[8])) { + $columns[$j]['unsigned'] = true; + } + if (isset($matches[9]) && strlen($matches[9])) { + $columns[$j]['autoincrement'] = true; + } + if (isset($matches[12]) && strlen($matches[12])) { + $default = $matches[12]; + if (strlen($default) && $default[0]=="'") { + $default = str_replace("''", "'", substr($default, 1, strlen($default)-2)); + } + if ($default === 'NULL') { + $default = null; + } + $columns[$j]['default'] = $default; + } + if (isset($matches[7]) && strlen($matches[7])) { + $columns[$j]['notnull'] = ($matches[7] === ' NOT NULL'); + } else if (isset($matches[9]) && strlen($matches[9])) { + $columns[$j]['notnull'] = ($matches[9] === ' NOT NULL'); + } else if (isset($matches[13]) && strlen($matches[13])) { + $columns[$j]['notnull'] = ($matches[13] === ' NOT NULL'); + } + ++$j; + } + return $columns; + } + + // {{{ getTableFieldDefinition() + + /** + * Get the stucture of a field into an array + * + * @param string $table_name name of table that should be used in method + * @param string $field_name name of field that should be used in method + * @return mixed data array on success, a MDB2 error on failure. + * The returned array contains an array for each field definition, + * with (some of) these indices: + * [notnull] [nativetype] [length] [fixed] [default] [type] [mdb2type] + * @access public + */ + function getTableFieldDefinition($table_name, $field_name) + { + $db =$this->getDBInstance(); + if (PEAR::isError($db)) { + return $db; + } + + list($schema, $table) = $this->splitTableSchema($table_name); + + $result = $db->loadModule('Datatype', null, true); + if (PEAR::isError($result)) { + return $result; + } + $query = "SELECT sql FROM sqlite_master WHERE type='table' AND "; + if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) { + $query.= 'LOWER(name)='.$db->quote(strtolower($table), 'text'); + } else { + $query.= 'name='.$db->quote($table, 'text'); + } + $sql = $db->queryOne($query); + if (PEAR::isError($sql)) { + return $sql; + } + $columns = $this->_getTableColumns($sql); + foreach ($columns as $column) { + if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) { + if ($db->options['field_case'] == CASE_LOWER) { + $column['name'] = strtolower($column['name']); + } else { + $column['name'] = strtoupper($column['name']); + } + } else { + $column = array_change_key_case($column, $db->options['field_case']); + } + if ($field_name == $column['name']) { + $mapped_datatype = $db->datatype->mapNativeDatatype($column); + if (PEAR::isError($mapped_datatype)) { + return $mapped_datatype; + } + list($types, $length, $unsigned, $fixed) = $mapped_datatype; + $notnull = false; + if (!empty($column['notnull'])) { + $notnull = $column['notnull']; + } + $default = false; + if (array_key_exists('default', $column)) { + $default = $column['default']; + if (is_null($default) && $notnull) { + $default = ''; + } + } + $autoincrement = false; + if (!empty($column['autoincrement'])) { + $autoincrement = true; + } + + $definition[0] = array( + 'notnull' => $notnull, + 'nativetype' => preg_replace('/^([a-z]+)[^a-z].*/i', '\\1', $column['type']) + ); + if (!is_null($length)) { + $definition[0]['length'] = $length; + } + if (!is_null($unsigned)) { + $definition[0]['unsigned'] = $unsigned; + } + if (!is_null($fixed)) { + $definition[0]['fixed'] = $fixed; + } + if ($default !== false) { + $definition[0]['default'] = $default; + } + if ($autoincrement !== false) { + $definition[0]['autoincrement'] = $autoincrement; + } + foreach ($types as $key => $type) { + $definition[$key] = $definition[0]; + if ($type == 'clob' || $type == 'blob') { + unset($definition[$key]['default']); + } + $definition[$key]['type'] = $type; + $definition[$key]['mdb2type'] = $type; + } + return $definition; + } + } + + return $db->raiseError(MDB2_ERROR_NOT_FOUND, null, null, + 'it was not specified an existing table column', __FUNCTION__); + } + + // }}} + // {{{ getTableIndexDefinition() + + /** + * Get the stucture of an index into an array + * + * @param string $table_name name of table that should be used in method + * @param string $index_name name of index that should be used in method + * @return mixed data array on success, a MDB2 error on failure + * @access public + */ + function getTableIndexDefinition($table_name, $index_name) + { + $db =$this->getDBInstance(); + if (PEAR::isError($db)) { + return $db; + } + + list($schema, $table) = $this->splitTableSchema($table_name); + + $query = "SELECT sql FROM sqlite_master WHERE type='index' AND "; + if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) { + $query.= 'LOWER(name)=%s AND LOWER(tbl_name)=' . $db->quote(strtolower($table), 'text'); + } else { + $query.= 'name=%s AND tbl_name=' . $db->quote($table, 'text'); + } + $query.= ' AND sql NOT NULL ORDER BY name'; + $index_name_mdb2 = $db->getIndexName($index_name); + if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) { + $qry = sprintf($query, $db->quote(strtolower($index_name_mdb2), 'text')); + } else { + $qry = sprintf($query, $db->quote($index_name_mdb2, 'text')); + } + $sql = $db->queryOne($qry, 'text'); + if (PEAR::isError($sql) || empty($sql)) { + // fallback to the given $index_name, without transformation + if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) { + $qry = sprintf($query, $db->quote(strtolower($index_name), 'text')); + } else { + $qry = sprintf($query, $db->quote($index_name, 'text')); + } + $sql = $db->queryOne($qry, 'text'); + } + if (PEAR::isError($sql)) { + return $sql; + } + if (!$sql) { + return $db->raiseError(MDB2_ERROR_NOT_FOUND, null, null, + 'it was not specified an existing table index', __FUNCTION__); + } + + $sql = strtolower($sql); + $start_pos = strpos($sql, '('); + $end_pos = strrpos($sql, ')'); + $column_names = substr($sql, $start_pos+1, $end_pos-$start_pos-1); + $column_names = explode(',', $column_names); + + if (preg_match("/^create unique/", $sql)) { + return $db->raiseError(MDB2_ERROR_NOT_FOUND, null, null, + 'it was not specified an existing table index', __FUNCTION__); + } + + $definition = array(); + $count = count($column_names); + for ($i=0; $i<$count; ++$i) { + $column_name = strtok($column_names[$i], ' '); + $collation = strtok(' '); + $definition['fields'][$column_name] = array( + 'position' => $i+1 + ); + if (!empty($collation)) { + $definition['fields'][$column_name]['sorting'] = + ($collation=='ASC' ? 'ascending' : 'descending'); + } + } + + if (empty($definition['fields'])) { + return $db->raiseError(MDB2_ERROR_NOT_FOUND, null, null, + 'it was not specified an existing table index', __FUNCTION__); + } + return $definition; + } + + // }}} + // {{{ getTableConstraintDefinition() + + /** + * Get the stucture of a constraint into an array + * + * @param string $table_name name of table that should be used in method + * @param string $constraint_name name of constraint that should be used in method + * @return mixed data array on success, a MDB2 error on failure + * @access public + */ + function getTableConstraintDefinition($table_name, $constraint_name) + { + $db =$this->getDBInstance(); + if (PEAR::isError($db)) { + return $db; + } + + list($schema, $table) = $this->splitTableSchema($table_name); + + $query = "SELECT sql FROM sqlite_master WHERE type='index' AND "; + if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) { + $query.= 'LOWER(name)=%s AND LOWER(tbl_name)=' . $db->quote(strtolower($table), 'text'); + } else { + $query.= 'name=%s AND tbl_name=' . $db->quote($table, 'text'); + } + $query.= ' AND sql NOT NULL ORDER BY name'; + $constraint_name_mdb2 = $db->getIndexName($constraint_name); + if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) { + $qry = sprintf($query, $db->quote(strtolower($constraint_name_mdb2), 'text')); + } else { + $qry = sprintf($query, $db->quote($constraint_name_mdb2, 'text')); + } + $sql = $db->queryOne($qry, 'text'); + if (PEAR::isError($sql) || empty($sql)) { + // fallback to the given $index_name, without transformation + if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) { + $qry = sprintf($query, $db->quote(strtolower($constraint_name), 'text')); + } else { + $qry = sprintf($query, $db->quote($constraint_name, 'text')); + } + $sql = $db->queryOne($qry, 'text'); + } + if (PEAR::isError($sql)) { + return $sql; + } + //default values, eventually overridden + $definition = array( + 'primary' => false, + 'unique' => false, + 'foreign' => false, + 'check' => false, + 'fields' => array(), + 'references' => array( + 'table' => '', + 'fields' => array(), + ), + 'onupdate' => '', + 'ondelete' => '', + 'match' => '', + 'deferrable' => false, + 'initiallydeferred' => false, + ); + if (!$sql) { + $query = "SELECT sql FROM sqlite_master WHERE type='table' AND "; + if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) { + $query.= 'LOWER(name)='.$db->quote(strtolower($table), 'text'); + } else { + $query.= 'name='.$db->quote($table, 'text'); + } + $query.= " AND sql NOT NULL ORDER BY name"; + $sql = $db->queryOne($query, 'text'); + if (PEAR::isError($sql)) { + return $sql; + } + if ($constraint_name == 'primary') { + // search in table definition for PRIMARY KEYs + if (preg_match("/\bPRIMARY\s+KEY\b\s*\(([^)]+)/i", $sql, $tmp)) { + $definition['primary'] = true; + $definition['fields'] = array(); + $column_names = explode(',', $tmp[1]); + $colpos = 1; + foreach ($column_names as $column_name) { + $definition['fields'][trim($column_name)] = array( + 'position' => $colpos++ + ); + } + return $definition; + } + if (preg_match("/\"([^\"]+)\"[^\,\"]+\bPRIMARY\s+KEY\b[^\,\)]*/i", $sql, $tmp)) { + $definition['primary'] = true; + $definition['fields'] = array(); + $column_names = explode(',', $tmp[1]); + $colpos = 1; + foreach ($column_names as $column_name) { + $definition['fields'][trim($column_name)] = array( + 'position' => $colpos++ + ); + } + return $definition; + } + } else { + // search in table definition for FOREIGN KEYs + $pattern = "/\bCONSTRAINT\b\s+%s\s+ + \bFOREIGN\s+KEY\b\s*\(([^\)]+)\)\s* + \bREFERENCES\b\s+([^\s]+)\s*\(([^\)]+)\)\s* + (?:\bMATCH\s*([^\s]+))?\s* + (?:\bON\s+UPDATE\s+([^\s,\)]+))?\s* + (?:\bON\s+DELETE\s+([^\s,\)]+))?\s* + /imsx"; + $found_fk = false; + if (preg_match(sprintf($pattern, $constraint_name_mdb2), $sql, $tmp)) { + $found_fk = true; + } elseif (preg_match(sprintf($pattern, $constraint_name), $sql, $tmp)) { + $found_fk = true; + } + if ($found_fk) { + $definition['foreign'] = true; + $definition['match'] = 'SIMPLE'; + $definition['onupdate'] = 'NO ACTION'; + $definition['ondelete'] = 'NO ACTION'; + $definition['references']['table'] = $tmp[2]; + $column_names = explode(',', $tmp[1]); + $colpos = 1; + foreach ($column_names as $column_name) { + $definition['fields'][trim($column_name)] = array( + 'position' => $colpos++ + ); + } + $referenced_cols = explode(',', $tmp[3]); + $colpos = 1; + foreach ($referenced_cols as $column_name) { + $definition['references']['fields'][trim($column_name)] = array( + 'position' => $colpos++ + ); + } + if (isset($tmp[4])) { + $definition['match'] = $tmp[4]; + } + if (isset($tmp[5])) { + $definition['onupdate'] = $tmp[5]; + } + if (isset($tmp[6])) { + $definition['ondelete'] = $tmp[6]; + } + return $definition; + } + } + $sql = false; + } + if (!$sql) { + return $db->raiseError(MDB2_ERROR_NOT_FOUND, null, null, + $constraint_name . ' is not an existing table constraint', __FUNCTION__); + } + + $sql = strtolower($sql); + $start_pos = strpos($sql, '('); + $end_pos = strrpos($sql, ')'); + $column_names = substr($sql, $start_pos+1, $end_pos-$start_pos-1); + $column_names = explode(',', $column_names); + + if (!preg_match("/^create unique/", $sql)) { + return $db->raiseError(MDB2_ERROR_NOT_FOUND, null, null, + $constraint_name . ' is not an existing table constraint', __FUNCTION__); + } + + $definition['unique'] = true; + $count = count($column_names); + for ($i=0; $i<$count; ++$i) { + $column_name = strtok($column_names[$i]," "); + $collation = strtok(" "); + $definition['fields'][$column_name] = array( + 'position' => $i+1 + ); + if (!empty($collation)) { + $definition['fields'][$column_name]['sorting'] = + ($collation=='ASC' ? 'ascending' : 'descending'); + } + } + + if (empty($definition['fields'])) { + return $db->raiseError(MDB2_ERROR_NOT_FOUND, null, null, + $constraint_name . ' is not an existing table constraint', __FUNCTION__); + } + return $definition; + } + + // }}} + // {{{ getTriggerDefinition() + + /** + * Get the structure of a trigger into an array + * + * EXPERIMENTAL + * + * WARNING: this function is experimental and may change the returned value + * at any time until labelled as non-experimental + * + * @param string $trigger name of trigger that should be used in method + * @return mixed data array on success, a MDB2 error on failure + * @access public + */ + function getTriggerDefinition($trigger) + { + $db =$this->getDBInstance(); + if (PEAR::isError($db)) { + return $db; + } + + $query = "SELECT name as trigger_name, + tbl_name AS table_name, + sql AS trigger_body, + NULL AS trigger_type, + NULL AS trigger_event, + NULL AS trigger_comment, + 1 AS trigger_enabled + FROM sqlite_master + WHERE type='trigger'"; + if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) { + $query.= ' AND LOWER(name)='.$db->quote(strtolower($trigger), 'text'); + } else { + $query.= ' AND name='.$db->quote($trigger, 'text'); + } + $types = array( + 'trigger_name' => 'text', + 'table_name' => 'text', + 'trigger_body' => 'text', + 'trigger_type' => 'text', + 'trigger_event' => 'text', + 'trigger_comment' => 'text', + 'trigger_enabled' => 'boolean', + ); + $def = $db->queryRow($query, $types, MDB2_FETCHMODE_ASSOC); + if (PEAR::isError($def)) { + return $def; + } + if (empty($def)) { + return $db->raiseError(MDB2_ERROR_NOT_FOUND, null, null, + 'it was not specified an existing trigger', __FUNCTION__); + } + if (preg_match("/^create\s+(?:temp|temporary)?trigger\s+(?:if\s+not\s+exists\s+)?.*(before|after)?\s+(insert|update|delete)/Uims", $def['trigger_body'], $tmp)) { + $def['trigger_type'] = strtoupper($tmp[1]); + $def['trigger_event'] = strtoupper($tmp[2]); + } + return $def; + } + + // }}} + // {{{ tableInfo() + + /** + * Returns information about a table + * + * @param string $result a string containing the name of a table + * @param int $mode a valid tableInfo mode + * + * @return array an associative array with the information requested. + * A MDB2_Error object on failure. + * + * @see MDB2_Driver_Common::tableInfo() + * @since Method available since Release 1.7.0 + */ + function tableInfo($result, $mode = null) + { + if (is_string($result)) { + return parent::tableInfo($result, $mode); + } + + $db =$this->getDBInstance(); + if (PEAR::isError($db)) { + return $db; + } + + return $db->raiseError(MDB2_ERROR_NOT_CAPABLE, null, null, + 'This DBMS can not obtain tableInfo from result sets', __FUNCTION__); + } +} + +?>
\ No newline at end of file diff --git a/lib/MDB2/Driver/sqlite3.php b/lib/MDB2/Driver/sqlite3.php new file mode 100644 index 00000000000..3b74afed146 --- /dev/null +++ b/lib/MDB2/Driver/sqlite3.php @@ -0,0 +1,1361 @@ +<?php +// vim: set et ts=4 sw=4 fdm=marker: +// +----------------------------------------------------------------------+ +// | PHP versions 5 | +// +----------------------------------------------------------------------+ +// | Copyright (c) 2011 Robin Appelman | +// | All rights reserved. | +// +----------------------------------------------------------------------+ +// | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB | +// | API as well as database abstraction for PHP applications. | +// | This LICENSE is in the BSD license style. | +// | | +// | Redistribution and use in source and binary forms, with or without | +// | modification, are permitted provided that the following conditions | +// | are met: | +// | | +// | Redistributions of source code must retain the above copyright | +// | notice, this list of conditions and the following disclaimer. | +// | | +// | Redistributions in binary form must reproduce the above copyright | +// | notice, this list of conditions and the following disclaimer in the | +// | documentation and/or other materials provided with the distribution. | +// | | +// | Neither the name of Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, | +// | Lukas Smith nor the names of his contributors may be used to endorse | +// | or promote products derived from this software without specific prior| +// | written permission. | +// | | +// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | +// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | +// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | +// | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE | +// | REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | +// | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | +// | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS| +// | OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED | +// | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | +// | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY| +// | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | +// | POSSIBILITY OF SUCH DAMAGE. | +// +----------------------------------------------------------------------+ +// | Author: Robin Appelman <icewind1991@gmail.com> | +// +----------------------------------------------------------------------+ +// +// + +/** + * MDB2 SQLite3 driver + * + * @package MDB2 + * @category Database + * @author Lukas Smith <smith@pooteeweet.org> + */ +class MDB2_Driver_sqlite3 extends MDB2_Driver_Common +{ + // {{{ properties + public $string_quoting = array('start' => "'", 'end' => "'", 'escape' => "'", 'escape_pattern' => false); + + public $identifier_quoting = array('start' => '"', 'end' => '"', 'escape' => '"'); + + public $_lasterror = ''; + + public $fix_assoc_fields_names = false; + + // }}} + // {{{ constructor + + /** + * Constructor + */ + function __construct() + { + parent::__construct(); + + $this->phptype = 'sqlite3'; + $this->dbsyntax = 'sqlite'; + + $this->supported['sequences'] = 'emulated'; + $this->supported['indexes'] = true; + $this->supported['affected_rows'] = true; + $this->supported['summary_functions'] = true; + $this->supported['order_by_text'] = true; + $this->supported['current_id'] = 'emulated'; + $this->supported['limit_queries'] = true; + $this->supported['LOBs'] = true; + $this->supported['replace'] = true; + $this->supported['transactions'] = false; + $this->supported['savepoints'] = false; + $this->supported['sub_selects'] = true; + $this->supported['triggers'] = true; + $this->supported['auto_increment'] = true; + $this->supported['primary_key'] = false; // requires alter table implementation + $this->supported['result_introspection'] = false; // not implemented + $this->supported['prepared_statements'] = true; + $this->supported['identifier_quoting'] = true; + $this->supported['pattern_escaping'] = false; + $this->supported['new_link'] = false; + + $this->options['DBA_username'] = false; + $this->options['DBA_password'] = false; + $this->options['base_transaction_name'] = '___php_MDB2_sqlite_auto_commit_off'; + $this->options['fixed_float'] = 0; + $this->options['database_path'] = ''; + $this->options['database_extension'] = ''; + $this->options['server_version'] = ''; + $this->options['max_identifiers_length'] = 128; //no real limit + } + + // }}} + // {{{ errorInfo() + + /** + * This method is used to collect information about an error + * + * @param integer $error + * @return array + * @access public + */ + function errorInfo($error = null) + { + $native_code = null; + if ($this->connection) { + $native_code = $this->connection->lastErrorCode(); + } + $native_msg = $this->_lasterror + ? html_entity_decode($this->_lasterror) : $this->connection->lastErrorMsg(); + + // PHP 5.2+ prepends the function name to $php_errormsg, so we need + // this hack to work around it, per bug #9599. + $native_msg = preg_replace('/^sqlite[a-z_]+\(\)[^:]*: /', '', $native_msg); + + if (is_null($error)) { + static $error_regexps; + if (empty($error_regexps)) { + $error_regexps = array( + '/^no such table:/' => MDB2_ERROR_NOSUCHTABLE, + '/^no such index:/' => MDB2_ERROR_NOT_FOUND, + '/^(table|index) .* already exists$/' => MDB2_ERROR_ALREADY_EXISTS, + '/PRIMARY KEY must be unique/i' => MDB2_ERROR_CONSTRAINT, + '/is not unique/' => MDB2_ERROR_CONSTRAINT, + '/columns .* are not unique/i' => MDB2_ERROR_CONSTRAINT, + '/uniqueness constraint failed/' => MDB2_ERROR_CONSTRAINT, + '/may not be NULL/' => MDB2_ERROR_CONSTRAINT_NOT_NULL, + '/^no such column:/' => MDB2_ERROR_NOSUCHFIELD, + '/no column named/' => MDB2_ERROR_NOSUCHFIELD, + '/column not present in both tables/i' => MDB2_ERROR_NOSUCHFIELD, + '/^near ".*": syntax error$/' => MDB2_ERROR_SYNTAX, + '/[0-9]+ values for [0-9]+ columns/i' => MDB2_ERROR_VALUE_COUNT_ON_ROW, + ); + } + foreach ($error_regexps as $regexp => $code) { + if (preg_match($regexp, $native_msg)) { + $error = $code; + break; + } + } + } + return array($error, $native_code, $native_msg); + } + + // }}} + // {{{ escape() + + /** + * Quotes a string so it can be safely used in a query. It will quote + * the text so it can safely be used within a query. + * + * @param string the input string to quote + * @param bool escape wildcards + * + * @return string quoted string + * + * @access public + */ + public function escape($text, $escape_wildcards = false) + { + if($this->connection){ + return $this->connection->escapeString($text); + }else{ + return str_replace("'","''",$text);//TODO; more + } + } + + // }}} + // {{{ beginTransaction() + + /** + * Start a transaction or set a savepoint. + * + * @param string name of a savepoint to set + * @return mixed MDB2_OK on success, a MDB2 error on failure + * + * @access public + */ + function beginTransaction($savepoint = null) + { + $this->debug('Starting transaction/savepoint', __FUNCTION__, array('is_manip' => true, 'savepoint' => $savepoint)); + if (!is_null($savepoint)) { + return $this->raiseError(MDB2_ERROR_UNSUPPORTED, null, null, + 'savepoints are not supported', __FUNCTION__); + } elseif ($this->in_transaction) { + return MDB2_OK; //nothing to do + } + if (!$this->destructor_registered && $this->opened_persistent) { + $this->destructor_registered = true; + register_shutdown_function('MDB2_closeOpenTransactions'); + } + $query = 'BEGIN TRANSACTION '.$this->options['base_transaction_name']; + $result =$this->_doQuery($query, true); + if (PEAR::isError($result)) { + return $result; + } + $this->in_transaction = true; + return MDB2_OK; + } + + // }}} + // {{{ commit() + + /** + * Commit the database changes done during a transaction that is in + * progress or release a savepoint. This function may only be called when + * auto-committing is disabled, otherwise it will fail. Therefore, a new + * transaction is implicitly started after committing the pending changes. + * + * @param string name of a savepoint to release + * @return mixed MDB2_OK on success, a MDB2 error on failure + * + * @access public + */ + function commit($savepoint = null) + { + $this->debug('Committing transaction/savepoint', __FUNCTION__, array('is_manip' => true, 'savepoint' => $savepoint)); + if (!$this->in_transaction) { + return $this->raiseError(MDB2_ERROR_INVALID, null, null, + 'commit/release savepoint cannot be done changes are auto committed', __FUNCTION__); + } + if (!is_null($savepoint)) { + return $this->raiseError(MDB2_ERROR_UNSUPPORTED, null, null, + 'savepoints are not supported', __FUNCTION__); + } + + $query = 'COMMIT TRANSACTION '.$this->options['base_transaction_name']; + $result =$this->_doQuery($query, true); + if (PEAR::isError($result)) { + return $result; + } + $this->in_transaction = false; + return MDB2_OK; + } + + // }}} + // {{{ + + /** + * Cancel any database changes done during a transaction or since a specific + * savepoint that is in progress. This function may only be called when + * auto-committing is disabled, otherwise it will fail. Therefore, a new + * transaction is implicitly started after canceling the pending changes. + * + * @param string name of a savepoint to rollback to + * @return mixed MDB2_OK on success, a MDB2 error on failure + * + * @access public + */ + function rollback($savepoint = null) + { + $this->debug('Rolling back transaction/savepoint', __FUNCTION__, array('is_manip' => true, 'savepoint' => $savepoint)); + if (!$this->in_transaction) { + return $this->raiseError(MDB2_ERROR_INVALID, null, null, + 'rollback cannot be done changes are auto committed', __FUNCTION__); + } + if (!is_null($savepoint)) { + return $this->raiseError(MDB2_ERROR_UNSUPPORTED, null, null, + 'savepoints are not supported', __FUNCTION__); + } + + $query = 'ROLLBACK TRANSACTION '.$this->options['base_transaction_name']; + $result =$this->_doQuery($query, true); + if (PEAR::isError($result)) { + return $result; + } + $this->in_transaction = false; + return MDB2_OK; + } + + // }}} + // {{{ function setTransactionIsolation() + + /** + * Set the transacton isolation level. + * + * @param string standard isolation level + * READ UNCOMMITTED (allows dirty reads) + * READ COMMITTED (prevents dirty reads) + * REPEATABLE READ (prevents nonrepeatable reads) + * SERIALIZABLE (prevents phantom reads) + * @return mixed MDB2_OK on success, a MDB2 error on failure + * + * @access public + * @since 2.1.1 + */ + static function setTransactionIsolation($isolation,$options=array()) + { + $this->debug('Setting transaction isolation level', __FUNCTION__, array('is_manip' => true)); + switch ($isolation) { + case 'READ UNCOMMITTED': + $isolation = 0; + break; + case 'READ COMMITTED': + case 'REPEATABLE READ': + case 'SERIALIZABLE': + $isolation = 1; + break; + default: + return $this->raiseError(MDB2_ERROR_UNSUPPORTED, null, null, + 'isolation level is not supported: '.$isolation, __FUNCTION__); + } + + $query = "PRAGMA read_uncommitted=$isolation"; + return $this->_doQuery($query, true); + } + + // }}} + // {{{ getDatabaseFile() + + /** + * Builds the string with path+dbname+extension + * + * @return string full database path+file + * @access protected + */ + function _getDatabaseFile($database_name) + { + if ($database_name === '' || $database_name === ':memory:') { + return $database_name; + } + return $this->options['database_path'].$database_name.$this->options['database_extension']; + } + + // }}} + // {{{ connect() + + /** + * Connect to the database + * + * @return true on success, MDB2 Error Object on failure + **/ + function connect() + { + if($this->connection instanceof SQLite3){ + return MDB2_OK; + } + global $SERVERROOT; + $datadir=OC_CONFIG::getValue( "datadirectory", "$SERVERROOT/data" ); + $database_file = $this->_getDatabaseFile($this->database_name); + if (is_resource($this->connection)) { + //if (count(array_diff($this->connected_dsn, $this->dsn)) == 0 + if (MDB2::areEquals($this->connected_dsn, $this->dsn) + && $this->connected_database_name == $database_file + && $this->opened_persistent == $this->options['persistent'] + ) { + return MDB2_OK; + } + $this->disconnect(false); + } + + if (!PEAR::loadExtension($this->phptype)) { + return $this->raiseError(MDB2_ERROR_NOT_FOUND, null, null, + 'extension '.$this->phptype.' is not compiled into PHP', __FUNCTION__); + } + + if (empty($this->database_name)) { + return $this->raiseError(MDB2_ERROR_CONNECT_FAILED, null, null, + 'unable to establish a connection', __FUNCTION__); + } + + if ($database_file !== ':memory:') { + if(!strpos($database_file,'.db')){ + $database_file="$datadir/$database_file.db"; + } + if (!file_exists($database_file)) { + if (!touch($database_file)) { + return $this->raiseError(MDB2_ERROR_NOT_FOUND, null, null, + 'Could not create database file', __FUNCTION__); + } + if (!isset($this->dsn['mode']) + || !is_numeric($this->dsn['mode']) + ) { + $mode = 0644; + } else { + $mode = octdec($this->dsn['mode']); + } + if (!chmod($database_file, $mode)) { + return $this->raiseError(MDB2_ERROR_NOT_FOUND, null, null, + 'Could not be chmodded database file', __FUNCTION__); + } + if (!file_exists($database_file)) { + return $this->raiseError(MDB2_ERROR_NOT_FOUND, null, null, + 'Could not be found database file', __FUNCTION__); + } + } + if (!is_file($database_file)) { + return $this->raiseError(MDB2_ERROR_INVALID, null, null, + 'Database is a directory name', __FUNCTION__); + } + if (!is_readable($database_file)) { + return $this->raiseError(MDB2_ERROR_ACCESS_VIOLATION, null, null, + 'Could not read database file', __FUNCTION__); + } + } + + $php_errormsg = ''; + $this->connection = new SQLite3($database_file); + if(is_callable(array($this->connection,'busyTimeout'))){//busy timout is only available in php>=5.3 + $this->connection->busyTimeout(100); + } + $this->_lasterror = $this->connection->lastErrorMsg(); + if (!$this->connection) { + return $this->raiseError(MDB2_ERROR_CONNECT_FAILED, null, null, + 'unable to establish a connection', __FUNCTION__); + } + + if ($this->fix_assoc_fields_names || + $this->options['portability'] & MDB2_PORTABILITY_FIX_ASSOC_FIELD_NAMES) + { + $this->connection->exec("PRAGMA short_column_names = 1"); + $this->fix_assoc_fields_names = true; + } + + $this->connected_dsn = $this->dsn; + $this->connected_database_name = $database_file; + $this->opened_persistent = $this->getoption('persistent'); + $this->dbsyntax = $this->dsn['dbsyntax'] ? $this->dsn['dbsyntax'] : $this->phptype; + + return MDB2_OK; + } + + // }}} + // {{{ databaseExists() + + /** + * check if given database name is exists? + * + * @param string $name name of the database that should be checked + * + * @return mixed true/false on success, a MDB2 error on failure + * @access public + */ + function databaseExists($name) + { + $database_file = $this->_getDatabaseFile($name); + $result = file_exists($database_file); + return $result; + } + + // }}} + // {{{ disconnect() + + /** + * Log out and disconnect from the database. + * + * @param boolean $force if the disconnect should be forced even if the + * connection is opened persistently + * @return mixed true on success, false if not connected and error + * object on error + * @access public + */ + function disconnect($force = true) + { + if ($this->connection instanceof SQLite3) { + if ($this->in_transaction) { + $dsn = $this->dsn; + $database_name = $this->database_name; + $persistent = $this->options['persistent']; + $this->dsn = $this->connected_dsn; + $this->database_name = $this->connected_database_name; + $this->options['persistent'] = $this->opened_persistent; + $this->rollback(); + $this->dsn = $dsn; + $this->database_name = $database_name; + $this->options['persistent'] = $persistent; + } + + if (!$this->opened_persistent || $force) { + $this->connection->close(); + } + } else { + return false; + } + return parent::disconnect($force); + } + + // }}} + // {{{ _doQuery() + + /** + * Execute a query + * @param string $query query + * @param boolean $is_manip if the query is a manipulation query + * @param resource $connection + * @param string $database_name + * @return result or error object + * @access protected + */ + function &_doQuery($query, $is_manip = false, $connection = null, $database_name = null) + { + $this->last_query = $query; + $result = $this->debug($query, 'query', array('is_manip' => $is_manip, 'when' => 'pre')); + if ($result) { + if (PEAR::isError($result)) { + return $result; + } + $query = $result; + } + if ($this->options['disable_query']) { + $result = $is_manip ? 0 : null; + return $result; + } + $result=$this->connection->query($query.';'); + $this->_lasterror = $this->connection->lastErrorMsg(); + + if (!$result) { + $err =$this->raiseError(null, null, null, + 'Could not execute statement', __FUNCTION__); + return $err; + } + + $this->debug($query, 'query', array('is_manip' => $is_manip, 'when' => 'post', 'result' => $result)); + return $result; + } + + // }}} + // {{{ _affectedRows() + + /** + * Returns the number of rows affected + * + * @param resource $result + * @param resource $connection + * @return mixed MDB2 Error Object or the number of rows affected + * @access private + */ + function _affectedRows($connection, $result = null) + { + return $this->connection->changes(); + } + + // }}} + // {{{ _modifyQuery() + + /** + * Changes a query string for various DBMS specific reasons + * + * @param string $query query to modify + * @param boolean $is_manip if it is a DML query + * @param integer $limit limit the number of rows + * @param integer $offset start reading from given offset + * @return string modified query + * @access protected + */ + function _modifyQuery($query, $is_manip, $limit, $offset) + { + if ($this->options['portability'] & MDB2_PORTABILITY_DELETE_COUNT) { + if (preg_match('/^\s*DELETE\s+FROM\s+(\S+)\s*$/i', $query)) { + $query = preg_replace('/^\s*DELETE\s+FROM\s+(\S+)\s*$/', + 'DELETE FROM \1 WHERE 1=1', $query); + } + } + if ($limit > 0 + && !preg_match('/LIMIT\s*\d(?:\s*(?:,|OFFSET)\s*\d+)?(?:[^\)]*)?$/i', $query) + ) { + $query = rtrim($query); + if (substr($query, -1) == ';') { + $query = substr($query, 0, -1); + } + if ($is_manip) { + $query.= " LIMIT $limit"; + } else { + $query.= " LIMIT $offset,$limit"; + } + } + return $query; + } + + // }}} + // {{{ getServerVersion() + + /** + * return version information about the server + * + * @param bool $native determines if the raw version string should be returned + * @return mixed array/string with version information or MDB2 error object + * @access public + */ + function getServerVersion($native = false) + { + $server_info = false; + if ($this->connected_server_info) { + $server_info = $this->connected_server_info; + } elseif ($this->options['server_version']) { + $server_info = $this->options['server_version']; + } elseif (function_exists('sqlite_libversion')) { + $server_info = @sqlite_libversion(); + } + if (!$server_info) { + return $this->raiseError(MDB2_ERROR_UNSUPPORTED, null, null, + 'Requires either the "server_version" option or the sqlite_libversion() function', __FUNCTION__); + } + // cache server_info + $this->connected_server_info = $server_info; + if (!$native) { + $tmp = explode('.', $server_info, 3); + $server_info = array( + 'major' => isset($tmp[0]) ? $tmp[0] : null, + 'minor' => isset($tmp[1]) ? $tmp[1] : null, + 'patch' => isset($tmp[2]) ? $tmp[2] : null, + 'extra' => null, + 'native' => $server_info, + ); + } + return $server_info; + } + + // }}} + // {{{ replace() + + /** + * Execute a SQL REPLACE query. A REPLACE query is identical to a INSERT + * query, except that if there is already a row in the table with the same + * key field values, the old row is deleted before the new row is inserted. + * + * The REPLACE type of query does not make part of the SQL standards. Since + * practically only SQLite implements it natively, this type of query is + * emulated through this method for other DBMS using standard types of + * queries inside a transaction to assure the atomicity of the operation. + * + * @access public + * + * @param string $table name of the table on which the REPLACE query will + * be executed. + * @param array $fields associative array that describes the fields and the + * values that will be inserted or updated in the specified table. The + * indexes of the array are the names of all the fields of the table. The + * values of the array are also associative arrays that describe the + * values and other properties of the table fields. + * + * Here follows a list of field properties that need to be specified: + * + * value: + * Value to be assigned to the specified field. This value may be + * of specified in database independent type format as this + * function can perform the necessary datatype conversions. + * + * Default: + * this property is required unless the Null property + * is set to 1. + * + * type + * Name of the type of the field. Currently, all types Metabase + * are supported except for clob and blob. + * + * Default: no type conversion + * + * null + * Boolean property that indicates that the value for this field + * should be set to null. + * + * The default value for fields missing in INSERT queries may be + * specified the definition of a table. Often, the default value + * is already null, but since the REPLACE may be emulated using + * an UPDATE query, make sure that all fields of the table are + * listed in this function argument array. + * + * Default: 0 + * + * key + * Boolean property that indicates that this field should be + * handled as a primary key or at least as part of the compound + * unique index of the table that will determine the row that will + * updated if it exists or inserted a new row otherwise. + * + * This function will fail if no key field is specified or if the + * value of a key field is set to null because fields that are + * part of unique index they may not be null. + * + * Default: 0 + * + * @return mixed MDB2_OK on success, a MDB2 error on failure + */ + function replace($table, $fields) + { + $count = count($fields); + $query = $values = ''; + $keys = $colnum = 0; + for (reset($fields); $colnum < $count; next($fields), $colnum++) { + $name = key($fields); + if ($colnum > 0) { + $query .= ','; + $values.= ','; + } + $query.= $this->quoteIdentifier($name, true); + if (isset($fields[$name]['null']) && $fields[$name]['null']) { + $value = 'NULL'; + } else { + $type = isset($fields[$name]['type']) ? $fields[$name]['type'] : null; + $value = $this->quote($fields[$name]['value'], $type); + if (PEAR::isError($value)) { + return $value; + } + } + $values.= $value; + if (isset($fields[$name]['key']) && $fields[$name]['key']) { + if ($value === 'NULL') { + return $this->raiseError(MDB2_ERROR_CANNOT_REPLACE, null, null, + 'key value '.$name.' may not be NULL', __FUNCTION__); + } + $keys++; + } + } + if ($keys == 0) { + return $this->raiseError(MDB2_ERROR_CANNOT_REPLACE, null, null, + 'not specified which fields are keys', __FUNCTION__); + } + + $connection = $this->getConnection(); + if (PEAR::isError($connection)) { + return $connection; + } + + $table = $this->quoteIdentifier($table, true); + $query = "REPLACE INTO $table ($query) VALUES ($values)"; + $result =$this->_doQuery($query, true, $connection); + if (PEAR::isError($result)) { + return $result; + } + return $this->_affectedRows($connection, $result); + } + + // }}} + // {{{ nextID() + + /** + * Returns the next free id of a sequence + * + * @param string $seq_name name of the sequence + * @param boolean $ondemand when true the sequence is + * automatic created, if it + * not exists + * + * @return mixed MDB2 Error Object or id + * @access public + */ + function nextID($seq_name, $ondemand = true) + { + $sequence_name = $this->quoteIdentifier($this->getSequenceName($seq_name), true); + $seqcol_name = $this->options['seqcol_name']; + $query = "INSERT INTO $sequence_name ($seqcol_name) VALUES (NULL)"; + $this->pushErrorHandling(PEAR_ERROR_RETURN); + $this->expectError(MDB2_ERROR_NOSUCHTABLE); + $result =$this->_doQuery($query, true); + $this->popExpect(); + $this->popErrorHandling(); + if (PEAR::isError($result)) { + if ($ondemand && $result->getCode() == MDB2_ERROR_NOSUCHTABLE) { + $this->loadModule('Manager', null, true); + $result = $this->manager->createSequence($seq_name); + if (PEAR::isError($result)) { + return $this->raiseError($result, null, null, + 'on demand sequence '.$seq_name.' could not be created', __FUNCTION__); + } else { + return $this->nextID($seq_name, false); + } + } + return $result; + } + $value = $this->lastInsertID(); + if (is_numeric($value)) { + $query = "DELETE FROM $sequence_name WHERE $seqcol_name < $value"; + $result =$this->_doQuery($query, true); + if (PEAR::isError($result)) { + $this->warnings[] = 'nextID: could not delete previous sequence table values from '.$seq_name; + } + } + return $value; + } + + // }}} + // {{{ lastInsertID() + + /** + * Returns the autoincrement ID if supported or $id or fetches the current + * ID in a sequence called: $table.(empty($field) ? '' : '_'.$field) + * + * @param string $table name of the table into which a new row was inserted + * @param string $field name of the field into which a new row was inserted + * @return mixed MDB2 Error Object or id + * @access public + */ + function lastInsertID($table = null, $field = null) + { + return $this->connection->lastInsertRowID(); + } + + // }}} + // {{{ currID() + + /** + * Returns the current id of a sequence + * + * @param string $seq_name name of the sequence + * @return mixed MDB2 Error Object or id + * @access public + */ + function currID($seq_name) + { + $sequence_name = $this->quoteIdentifier($this->getSequenceName($seq_name), true); + $seqcol_name = $this->quoteIdentifier($this->options['seqcol_name'], true); + $query = "SELECT MAX($seqcol_name) FROM $sequence_name"; + return $this->queryOne($query, 'integer'); + } + + /** + * Prepares a query for multiple execution with execute(). + * With some database backends, this is emulated. + * prepare() requires a generic query as string like + * 'INSERT INTO numbers VALUES(?,?)' or + * 'INSERT INTO numbers VALUES(:foo,:bar)'. + * The ? and :name and are placeholders which can be set using + * bindParam() and the query can be sent off using the execute() method. + * The allowed format for :name can be set with the 'bindname_format' option. + * + * @param string $query the query to prepare + * @param mixed $types array that contains the types of the placeholders + * @param mixed $result_types array that contains the types of the columns in + * the result set or MDB2_PREPARE_RESULT, if set to + * MDB2_PREPARE_MANIP the query is handled as a manipulation query + * @param mixed $lobs key (field) value (parameter) pair for all lob placeholders + * @return mixed resource handle for the prepared query on success, a MDB2 + * error on failure + * @access public + * @see bindParam, execute + */ + function &prepare($query, $types = null, $result_types = null, $lobs = array()) + { + if ($this->options['emulate_prepared'] + || $this->supported['prepared_statements'] !== true + ) { + $obj =& parent::prepare($query, $types, $result_types, $lobs); + return $obj; + } + $this->last_query = $query; + $is_manip = ($result_types === MDB2_PREPARE_MANIP); + $offset = $this->offset; + $limit = $this->limit; + $this->offset = $this->limit = 0; + $query = $this->_modifyQuery($query, $is_manip, $limit, $offset); + $result = $this->debug($query, __FUNCTION__, array('is_manip' => $is_manip, 'when' => 'pre')); + if ($result) { + if (PEAR::isError($result)) { + return $result; + } + $query = $result; + } + $placeholder_type_guess = $placeholder_type = null; + $question = '?'; + $colon = ':'; + $positions = array(); + $position = 0; + while ($position < strlen($query)) { + $q_position = strpos($query, $question, $position); + $c_position = strpos($query, $colon, $position); + if ($q_position && $c_position) { + $p_position = min($q_position, $c_position); + } elseif ($q_position) { + $p_position = $q_position; + } elseif ($c_position) { + $p_position = $c_position; + } else { + break; + } + if (is_null($placeholder_type)) { + $placeholder_type_guess = $query[$p_position]; + } + + $new_pos = $this->_skipDelimitedStrings($query, $position, $p_position); + if (PEAR::isError($new_pos)) { + return $new_pos; + } + if ($new_pos != $position) { + $position = $new_pos; + continue; //evaluate again starting from the new position + } + + + if ($query[$position] == $placeholder_type_guess) { + if (is_null($placeholder_type)) { + $placeholder_type = $query[$p_position]; + $question = $colon = $placeholder_type; + } + if ($placeholder_type == ':') { + $regexp = '/^.{'.($position+1).'}('.$this->options['bindname_format'].').*$/s'; + $parameter = preg_replace($regexp, '\\1', $query); + if ($parameter === '') { + $err =& $this->raiseError(MDB2_ERROR_SYNTAX, null, null, + 'named parameter name must match "bindname_format" option', __FUNCTION__); + return $err; + } + $positions[$p_position] = $parameter; + $query = substr_replace($query, '?', $position, strlen($parameter)+1); + } else { + $positions[$p_position] = count($positions); + } + $position = $p_position + 1; + } else { + $position = $p_position; + } + } + $connection = $this->getConnection(); + if (PEAR::isError($connection)) { + return $connection; + } + $statement =$this->connection->prepare($query); + if (!$statement) { + return $this->db->raiseError(MDB2_ERROR_NOT_FOUND, null, null, + 'unable to prepare statement: '.$query); + } + + $class_name = 'MDB2_Statement_'.$this->phptype; + $obj = new $class_name($this, $statement, $positions, $query, $types, $result_types, $is_manip, $limit, $offset); + $this->debug($query, __FUNCTION__, array('is_manip' => $is_manip, 'when' => 'post', 'result' => $obj)); + return $obj; + } +} + +/** + * MDB2 SQLite result driver + * + * @package MDB2 + * @category Database + * @author Lukas Smith <smith@pooteeweet.org> + */ +class MDB2_Result_sqlite3 extends MDB2_Result_Common +{ + // }}} + // {{{ fetchRow() + + /** + * Fetch a row and insert the data into an existing array. + * + * @param int $fetchmode how the array data should be indexed + * @param int $rownum number of the row where the data can be found + * @return int data array on success, a MDB2 error on failure + * @access public + */ + function &fetchRow($fetchmode = MDB2_FETCHMODE_DEFAULT, $rownum = null) + { + if (!is_null($rownum)) { + $seek = $this->seek($rownum); + if (PEAR::isError($seek)) { + return $seek; + } + } + if ($fetchmode == MDB2_FETCHMODE_DEFAULT) { + $fetchmode = $this->db->fetchmode; + } + if ($fetchmode & MDB2_FETCHMODE_ASSOC) { + //$row = @sqlite_fetch_array($this->result, SQLITE_ASSOC); + $row=$this->result->fetchArray(SQLITE3_ASSOC); + if (is_array($row) + && $this->db->options['portability'] & MDB2_PORTABILITY_FIX_CASE + ) { + $row = array_change_key_case($row, $this->db->options['field_case']); + } + } else { + $row=$this->result->fetchArray(SQLITE3_NUM); + } + if (!$row) { + if ($this->result === false) { + $err =$this->db->raiseError(MDB2_ERROR_NEED_MORE_DATA, null, null, + 'resultset has already been freed', __FUNCTION__); + return $err; + } + $null = null; + return $null; + } + $mode = $this->db->options['portability'] & MDB2_PORTABILITY_EMPTY_TO_NULL; + $rtrim = false; + if ($this->db->options['portability'] & MDB2_PORTABILITY_RTRIM) { + if (empty($this->types)) { + $mode += MDB2_PORTABILITY_RTRIM; + } else { + $rtrim = true; + } + } + if ($mode) { + $this->db->_fixResultArrayValues($row, $mode); + } + if (!empty($this->types)) { + $row = $this->db->datatype->convertResultRow($this->types, $row, $rtrim); + } + if (!empty($this->values)) { + $this->_assignBindColumns($row); + } + if ($fetchmode === MDB2_FETCHMODE_OBJECT) { + $object_class = $this->db->options['fetch_class']; + if ($object_class == 'stdClass') { + $row = (object) $row; + } else { + $row = new $object_class($row); + } + } + ++$this->rownum; + return $row; + } + + // }}} + // {{{ _getColumnNames() + + /** + * Retrieve the names of columns returned by the DBMS in a query result. + * + * @return mixed Array variable that holds the names of columns as keys + * or an MDB2 error on failure. + * Some DBMS may not return any columns when the result set + * does not contain any rows. + * @access private + */ + function _getColumnNames() + { + $columns = array(); + $numcols = $this->numCols(); + if (PEAR::isError($numcols)) { + return $numcols; + } + for ($column = 0; $column < $numcols; $column++) { + $column_name = $this->result->getColumnName($column); + $columns[$column_name] = $column; + } + if ($this->db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) { + $columns = array_change_key_case($columns, $this->db->options['field_case']); + } + return $columns; + } + + // }}} + // {{{ numCols() + + /** + * Count the number of columns returned by the DBMS in a query result. + * + * @access public + * @return mixed integer value with the number of columns, a MDB2 error + * on failure + */ + function numCols() + { + $this->result->numColumns(); + } +} + +/** + * MDB2 SQLite buffered result driver + * + * @package MDB2 + * @category Database + * @author Lukas Smith <smith@pooteeweet.org> + */ +class MDB2_BufferedResult_sqlite3 extends MDB2_Result_sqlite3 +{ + // {{{ seek() + + /** + * Seek to a specific row in a result set + * + * @param int $rownum number of the row where the data can be found + * @return mixed MDB2_OK on success, a MDB2 error on failure + * @access public + */ + function seek($rownum = 0) + { + $this->result->reset(); + for($i=0;$i<$rownum;$i++){ + $this->result->fetchArray(); + } + $this->rownum = $rownum - 1; + return MDB2_OK; + } + + // }}} + // {{{ valid() + + /** + * Check if the end of the result set has been reached + * + * @return mixed true or false on sucess, a MDB2 error on failure + * @access public + */ + function valid() + { + $numrows = $this->numRows(); + if (PEAR::isError($numrows)) { + return $numrows; + } + return $this->rownum < ($numrows - 1); + } + + // }}} + // {{{ numRows() + + /** + * Returns the number of rows in a result object + * + * @return mixed MDB2 Error Object or the number of rows + * @access public + */ + function numRows() + { + $rows = 0; + $this->result->reset(); + while($this->result->fetchArray()){ + $rows++; + } + $this->result->reset(); + return $rows; + } +} + +/** + * MDB2 SQLite statement driver + * + * @package MDB2 + * @category Database + * @author Lukas Smith <smith@pooteeweet.org> + */ +class MDB2_Statement_sqlite3 extends MDB2_Statement_Common +{ + // }}} + // {{{ function bindValue($parameter, &$value, $type = null) + + private function getParamType($type){ + switch(strtolower($type)){ + case 'text': + return SQLITE3_TEXT; + case 'boolean': + case 'integer': + return SQLITE3_INTEGER; + case 'float': + return SQLITE3_FLOAT; + case 'blob': + return SQLITE3_BLOB; + } + } + /** + * Set the value of a parameter of a prepared query. + * + * @param int the order number of the parameter in the query + * statement. The order number of the first parameter is 1. + * @param mixed value that is meant to be assigned to specified + * parameter. The type of the value depends on the $type argument. + * @param string specifies the type of the field + * + * @return mixed MDB2_OK on success, a MDB2 error on failure + * + * @access public + */ + function bindValue($parameter, $value, $type = null){ + if($type){ + $type=$this->getParamType($type); + $this->statement->bindValue($parameter,$value,$type); + }else{ + $this->statement->bindValue($parameter,$value); + } + return MDB2_OK; + } + + /** + * Bind a variable to a parameter of a prepared query. + * + * @param int the order number of the parameter in the query + * statement. The order number of the first parameter is 1. + * @param mixed variable that is meant to be bound to specified + * parameter. The type of the value depends on the $type argument. + * @param string specifies the type of the field + * + * @return mixed MDB2_OK on success, a MDB2 error on failure + * + * @access public + */ + function bindParam($parameter, &$value, $type = null){ + if($type){ + $type=$this->getParamType($type); + $this->statement->bindParam($parameter,$value,$type); + }else{ + $this->statement->bindParam($parameter,$value); + } + return MDB2_OK; + } + + /** + * Release resources allocated for the specified prepared query. + * + * @return mixed MDB2_OK on success, a MDB2 error on failure + * @access public + */ + function free() + { + $this->statement->close(); + } + + /** + * Execute a prepared query statement helper method. + * + * @param mixed $result_class string which specifies which result class to use + * @param mixed $result_wrap_class string which specifies which class to wrap results in + * + * @return mixed MDB2_Result or integer (affected rows) on success, + * a MDB2 error on failure + * @access private + */ + function &_execute($result_class = true, $result_wrap_class = false){ + if (is_null($this->statement)) { + $result =& parent::_execute($result_class, $result_wrap_class); + return $result; + } + $this->db->last_query = $this->query; + $this->db->debug($this->query, 'execute', array('is_manip' => $this->is_manip, 'when' => 'pre', 'parameters' => $this->values)); + if ($this->db->getOption('disable_query')) { + $result = $this->is_manip ? 0 : null; + return $result; + } + + $connection = $this->db->getConnection(); + if (PEAR::isError($connection)) { + return $connection; + } + + $result = $this->statement->execute(); + if ($result==false) { + $err =$this->db->raiseError(MDB2_ERROR_NEED_MORE_DATA, null, null, + 'cant execute statement', __FUNCTION__); + } + + if ($this->is_manip) { + $affected_rows = $this->db->_affectedRows($connection, $result); + return $affected_rows; + } + + $result =& $this->db->_wrapResult($result, $this->result_types, + $result_class, $result_wrap_class, $this->limit, $this->offset); + $this->db->debug($this->query, 'execute', array('is_manip' => $this->is_manip, 'when' => 'post', 'result' => $result)); + return $result; + } + + /** + * Set the values of multiple a parameter of a prepared query in bulk. + * + * @param array specifies all necessary information + * for bindValue() the array elements must use keys corresponding to + * the number of the position of the parameter. + * @param array specifies the types of the fields + * + * @return mixed MDB2_OK on success, a MDB2 error on failure + * + * @access public + * @see bindParam() + */ + function bindValueArray($values, $types = null) + { + $types = is_array($types) ? array_values($types) : array_fill(0, count($values), null); + $parameters = array_keys($values); + foreach ($parameters as $key => $parameter) { + $this->db->pushErrorHandling(PEAR_ERROR_RETURN); + $this->db->expectError(MDB2_ERROR_NOT_FOUND); + $err = $this->bindValue($parameter+1, $values[$parameter], $types[$key]); + $this->db->popExpect(); + $this->db->popErrorHandling(); + if (PEAR::isError($err)) { + if ($err->getCode() == MDB2_ERROR_NOT_FOUND) { + //ignore (extra value for missing placeholder) + continue; + } + return $err; + } + } + return MDB2_OK; + } + // }}} + // {{{ function bindParamArray(&$values, $types = null) + + /** + * Bind the variables of multiple a parameter of a prepared query in bulk. + * + * @param array specifies all necessary information + * for bindParam() the array elements must use keys corresponding to + * the number of the position of the parameter. + * @param array specifies the types of the fields + * + * @return mixed MDB2_OK on success, a MDB2 error on failure + * + * @access public + * @see bindParam() + */ + function bindParamArray(&$values, $types = null) + { + $types = is_array($types) ? array_values($types) : array_fill(0, count($values), null); + $parameters = array_keys($values); + foreach ($parameters as $key => $parameter) { + $err = $this->bindParam($parameter+1, $values[$parameter], $types[$key]); + if (PEAR::isError($err)) { + return $err; + } + } + return MDB2_OK; + } + + // }}} + // {{{ function &execute($values = null, $result_class = true, $result_wrap_class = false) + + /** + * Execute a prepared query statement. + * + * @param array specifies all necessary information + * for bindParam() the array elements must use keys corresponding + * to the number of the position of the parameter. + * @param mixed specifies which result class to use + * @param mixed specifies which class to wrap results in + * + * @return mixed MDB2_Result or integer (affected rows) on success, + * a MDB2 error on failure + * @access public + */ + function &execute($values = null, $result_class = true, $result_wrap_class = false) + { + if (is_null($this->positions)) { + return $this->db->raiseError(MDB2_ERROR, null, null, + 'Prepared statement has already been freed', __FUNCTION__); + } + $values = (array)$values; + if (!empty($values)) { + if(count($this->types)){ + $types=$this->types; + }else{ + $types=null; + } + $err = $this->bindValueArray($values,$types); + if (PEAR::isError($err)) { + return $this->db->raiseError(MDB2_ERROR, null, null, + 'Binding Values failed with message: ' . $err->getMessage(), __FUNCTION__); + } + } + $result =$this->_execute($result_class, $result_wrap_class); + return $result; + } + + function __destruct() { + $this->free(); + } +} + +?>
\ No newline at end of file diff --git a/lib/User/backend.php b/lib/User/backend.php index e99016a5214..1797d0c475a 100644 --- a/lib/User/backend.php +++ b/lib/User/backend.php @@ -4,7 +4,9 @@ * ownCloud * * @author Frank Karlitschek + * @author Dominik Schmidt * @copyright 2010 Frank Karlitschek karlitschek@kde.org + * @copyright 2011 Dominik Schmidt dev@dominik-schmidt.de * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE @@ -21,92 +23,64 @@ * */ +/** + * error code for functions not provided by the user backend + */ +define('OC_USER_BACKEND_NOT_IMPLEMENTED', -501); + +/** + * actions that user backends can define + */ +define('OC_USER_BACKEND_CREATE_USER', 0x000001); +define('OC_USER_BACKEND_DELETE_USER', 0x000010); +define('OC_USER_BACKEND_SET_PASSWORD', 0x000100); +define('OC_USER_BACKEND_CHECK_PASSWORD', 0x001000); +define('OC_USER_BACKEND_GET_USERS', 0x010000); +define('OC_USER_BACKEND_USER_EXISTS', 0x100000); /** * abstract base class for user management + * subclass this for your own backends and see OC_USER_EXAMPLE for descriptions */ abstract class OC_USER_BACKEND { - /** - * @brief Create a new user - * @param $uid The username of the user to create - * @param $password The password of the new user - * @returns true/false - * - * Creates a new user. Basic checking of username is done in OC_USER - * itself, not in its subclasses. - */ - public static function createUser($uid, $password){} - - /** - * @brief delete a user - * @param $uid The username of the user to delete - * @returns true/false - * - * Deletes a user - */ - public static function deleteUser( $uid ){} + protected $possibleActions = array( + OC_USER_BACKEND_CREATE_USER => 'createUser', + OC_USER_BACKEND_DELETE_USER => 'deleteUser', + OC_USER_BACKEND_SET_PASSWORD => 'setPassword', + OC_USER_BACKEND_CHECK_PASSWORD => 'checkPassword', + OC_USER_BACKEND_GET_USERS => 'getUsers', + OC_USER_BACKEND_USER_EXISTS => 'userExists' + ); /** - * @brief Try to login a user - * @param $uid The username of the user to log in - * @param $password The password of the user - * @returns true/false - * - * Log in a user - if the password is ok - */ - public static function login($uid, $password){} + * @brief Get all supported actions + * @returns bitwise-or'ed actions + * + * Returns the supported actions as int to be + * compared with OC_USER_BACKEND_CREATE_USER etc. + */ + public function getSupportedActions(){ + $actions = 0; + foreach($this->possibleActions AS $action => $methodName){ + if(method_exists($this, $methodName)) { + $actions |= $action; + } + } - /** - * @brief Kick the user - * @returns true - * - * Logout, destroys session - */ - public static function logout(){} - - /** - * @brief Check if the user is logged in - * @returns true/false - * - * Checks if the user is logged in - */ - public static function isLoggedIn(){} - - /** - * @brief Autogenerate a password - * @returns string - * - * generates a password - */ - public static function generatePassword(){} - - /** - * @brief Set password - * @param $uid The username - * @param $password The new password - * @returns true/false - * - * Change the password of a user - */ - public static function setPassword($uid, $password){} - - /** - * @brief Check if the password is correct - * @param $uid The username - * @param $password The password - * @returns true/false - * - * Check if the password is correct without logging in the user - */ - public static function checkPassword($uid, $password){} + return $actions; + } /** - * @brief Get a list of all users - * @returns array with all uids - * - * Get a list of all users. - */ - public static function getUsers(){} + * @brief Check if backend implements actions + * @param $actions bitwise-or'ed actions + * @returns boolean + * + * Returns the supported actions as int to be + * compared with OC_USER_BACKEND_CREATE_USER etc. + */ + public function implementsActions($actions){ + return (bool)($this->getSupportedActions() & $actions); + } } diff --git a/lib/User/database.php b/lib/User/database.php index eeabb592c22..0396ac30958 100644 --- a/lib/User/database.php +++ b/lib/User/database.php @@ -50,12 +50,8 @@ class OC_USER_DATABASE extends OC_USER_BACKEND { * Creates a new user. Basic checking of username is done in OC_USER * itself, not in its subclasses. */ - public static function createUser( $uid, $password ){ - // Check if the user already exists - $query = OC_DB::prepare( "SELECT * FROM `*PREFIX*users` WHERE uid = ?" ); - $result = $query->execute( array( $uid )); - - if ( $result->numRows() > 0 ){ + public function createUser( $uid, $password ){ + if( $this->userExists($uid) ){ return false; } else{ @@ -73,7 +69,7 @@ class OC_USER_DATABASE extends OC_USER_BACKEND { * * Deletes a user */ - public static function deleteUser( $uid ){ + public function deleteUser( $uid ){ // Delete user-group-relation $query = OC_DB::prepare( "DELETE FROM `*PREFIX*users` WHERE uid = ?" ); $result = $query->execute( array( $uid )); @@ -81,69 +77,6 @@ class OC_USER_DATABASE extends OC_USER_BACKEND { } /** - * @brief Try to login a user - * @param $uid The username of the user to log in - * @param $password The password of the user - * @returns true/false - * - * Log in a user - if the password is ok - */ - public static function login( $uid, $password ){ - // Query - $query = OC_DB::prepare( "SELECT uid FROM *PREFIX*users WHERE uid = ? AND password = ?" ); - $result = $query->execute( array( $uid, sha1( $password ))); - - if( $result->numRows() > 0 ){ - // Set username if name and password are known - $row = $result->fetchRow(); - $_SESSION['user_id'] = $row["uid"]; - OC_LOG::add( "core", $_SESSION['user_id'], "login" ); - return true; - } - else{ - return false; - } - } - - /** - * @brief Kick the user - * @returns true - * - * Logout, destroys session - */ - public static function logout(){ - OC_LOG::add( "core", $_SESSION['user_id'], "logout" ); - $_SESSION['user_id'] = false; - - return true; - } - - /** - * @brief Check if the user is logged in - * @returns true/false - * - * Checks if the user is logged in - */ - public static function isLoggedIn() { - if( isset($_SESSION['user_id']) AND $_SESSION['user_id'] ){ - return true; - } - else{ - return false; - } - } - - /** - * @brief Autogenerate a password - * @returns string - * - * generates a password - */ - public static function generatePassword(){ - return uniqId(); - } - - /** * @brief Set password * @param $uid The username * @param $password The new password @@ -151,12 +84,8 @@ class OC_USER_DATABASE extends OC_USER_BACKEND { * * Change the password of a user */ - public static function setPassword( $uid, $password ){ - // Check if the user already exists - $query = OC_DB::prepare( "SELECT * FROM `*PREFIX*users` WHERE uid = ?" ); - $result = $query->execute( array( $uid )); - - if( $result->numRows() > 0 ){ + public function setPassword( $uid, $password ){ + if( $this->userExists($uid) ){ $query = OC_DB::prepare( "UPDATE *PREFIX*users SET password = ? WHERE uid = ?" ); $result = $query->execute( array( sha1( $password ), $uid )); @@ -175,7 +104,7 @@ class OC_USER_DATABASE extends OC_USER_BACKEND { * * Check if the password is correct without logging in the user */ - public static function checkPassword( $uid, $password ){ + public function checkPassword( $uid, $password ){ $query = OC_DB::prepare( "SELECT uid FROM *PREFIX*users WHERE uid = ? AND password = ?" ); $result = $query->execute( array( $uid, sha1( $password ))); @@ -193,7 +122,7 @@ class OC_USER_DATABASE extends OC_USER_BACKEND { * * Get a list of all users. */ - public static function getUsers(){ + public function getUsers(){ $query = OC_DB::prepare( "SELECT uid FROM *PREFIX*users" ); $result = $query->execute(); @@ -203,4 +132,16 @@ class OC_USER_DATABASE extends OC_USER_BACKEND { } return $users; } + + /** + * @brief check if a user exists + * @param string $uid the username + * @return boolean + */ + public function userExists($uid){ + $query = OC_DB::prepare( "SELECT * FROM `*PREFIX*users` WHERE uid = ?" ); + $result = $query->execute( array( $uid )); + + return $result->numRows() > 0; + } } diff --git a/lib/User/example.php b/lib/User/example.php new file mode 100644 index 00000000000..4abc1b3d49c --- /dev/null +++ b/lib/User/example.php @@ -0,0 +1,97 @@ +<?php + +/** + * ownCloud + * + * @author Frank Karlitschek + * @copyright 2010 Frank Karlitschek karlitschek@kde.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/>. + * + */ + +require_once('User/backend.php'); + +/** + * abstract reference class for user management + * this class should only be used as a reference for method signatures and their descriptions + */ +abstract class OC_USER_EXAMPLE extends OC_USER_BACKEND { + /** + * @brief Create a new user + * @param $uid The username of the user to create + * @param $password The password of the new user + * @returns true/false + * + * Creates a new user. Basic checking of username is done in OC_USER + * itself, not in its subclasses. + */ + public function createUser($uid, $password){ + return OC_USER_BACKEND_NOT_IMPLEMENTED; + } + + /** + * @brief delete a user + * @param $uid The username of the user to delete + * @returns true/false + * + * Deletes a user + */ + public function deleteUser( $uid ){ + return OC_USER_BACKEND_NOT_IMPLEMENTED; + } + + /** + * @brief Set password + * @param $uid The username + * @param $password The new password + * @returns true/false + * + * Change the password of a user + */ + public function setPassword($uid, $password){ + return OC_USER_BACKEND_NOT_IMPLEMENTED; + } + + /** + * @brief Check if the password is correct + * @param $uid The username + * @param $password The password + * @returns true/false + * + * Check if the password is correct without logging in the user + */ + public function checkPassword($uid, $password){ + return OC_USER_BACKEND_NOT_IMPLEMENTED; + } + + /** + * @brief Get a list of all users + * @returns array with all uids + * + * Get a list of all users. + */ + public function getUsers(){ + return OC_USER_BACKEND_NOT_IMPLEMENTED; + } + + /** + * @brief check if a user exists + * @param string $uid the username + * @return boolean + */ + public function userExists($uid){ + return OC_USER_BACKEND_NOT_IMPLEMENTED; + } +} diff --git a/lib/app.php b/lib/app.php index a56e0c2f9e6..64704f09bbd 100644 --- a/lib/app.php +++ b/lib/app.php @@ -29,7 +29,7 @@ class OC_APP{ static private $init = false; static private $apps = array(); - static private $activeapp = ""; + static private $activeapp = ''; static private $adminpages = array(); static private $settingspages = array(); static private $navigation = array(); @@ -52,33 +52,19 @@ class OC_APP{ } // Our very own core apps are hardcoded - foreach( array( "admin", "files", "log", "help", "settings" ) as $app ){ - require( "$app/appinfo/app.php" ); + foreach( array( 'admin', 'files', 'log', 'help', 'settings' ) as $app ){ + require( $app.'/appinfo/app.php' ); } // The rest comes here - $dir = opendir( "$SERVERROOT/apps" ); - while( false !== ( $filename = readdir( $dir ))){ - if( substr( $filename, 0, 1 ) != '.' ){ - if( file_exists( "$SERVERROOT/apps/$filename/appinfo/app.php" )){ - if(OC_APPCONFIG::getValue($filename,'installed_version',0)==0){ //check if the plugin is fully installed - //install the database - if(is_file("$SERVERROOT/apps/$filename/appinfo/database.xml")){ - OC_DB::createDbFromStructure("$SERVERROOT/apps/$filename/appinfo/database.xml"); - } - - //run appinfo/install.php - if(is_file("$SERVERROOT/apps/$filename/appinfo/install.php")){ - include("$SERVERROOT/apps/$filename/appinfo/install.php"); - } - $info=self::getAppInfo("$SERVERROOT/apps/$filename/appinfo/info.xml"); - OC_APPCONFIG::setValue($filename,'installed_version',$info['version']); - } - require( "apps/$filename/appinfo/app.php" ); + $apps = OC_APPCONFIG::getApps(); + foreach( $apps as $app ){ + if( self::isEnabled( $app )){ + if(is_file($SERVERROOT.'/apps/'.$app.'/appinfo/app.php')){ + require( 'apps/'.$app.'/appinfo/app.php' ); } } } - closedir( $dir ); self::$init = true; @@ -87,14 +73,51 @@ class OC_APP{ } /** + * @brief checks whether or not an app is enabled + * @param $app app + * @returns true/false + * + * This function checks whether or not an app is enabled. + */ + public static function isEnabled( $app ){ + if( 'yes' == OC_APPCONFIG::getValue( $app, 'enabled' )){ + return true; + } + + return false; + } + + /** + * @brief enables an app + * @param $app app + * @returns true/false + * + * This function set an app as enabled in appconfig. + */ + public static function enable( $app ){ + OC_APPCONFIG::setValue( $app, 'enabled', 'yes' ); + } + + /** + * @brief enables an app + * @param $app app + * @returns true/false + * + * This function set an app as enabled in appconfig. + */ + public static function disable( $app ){ + OC_APPCONFIG::setValue( $app, 'enabled', 'no' ); + } + + /** * @brief makes owncloud aware of this app * @param $data array with all information * @returns true/false * * This function registers the application. $data is an associative array. * The following keys are required: - * - id: id of the application, has to be unique ("addressbook") - * - name: Human readable name ("Addressbook") + * - id: id of the application, has to be unique ('addressbook') + * - name: Human readable name ('Addressbook') * - version: array with Version (major, minor, bugfix) ( array(1, 0, 2)) * * The following keys are optional: @@ -125,9 +148,9 @@ class OC_APP{ * This function adds a new entry to the navigation visible to users. $data * is an associative array. * The following keys are required: - * - id: unique id for this entry ("addressbook_index") + * - id: unique id for this entry ('addressbook_index') * - href: link to the page - * - name: Human readable name ("Addressbook") + * - name: Human readable name ('Addressbook') * * The following keys are optional: * - icon: path to the icon of the app @@ -151,9 +174,9 @@ class OC_APP{ * as being active (see activateNavigationEntry()). $data is an associative * array. * The following keys are required: - * - id: unique id for this entry ("addressbook_index") + * - id: unique id for this entry ('addressbook_index') * - href: link to the page - * - name: Human readable name ("Addressbook") + * - name: Human readable name ('Addressbook') * * The following keys are optional: * - icon: path to the icon of the app @@ -173,7 +196,7 @@ class OC_APP{ * @param $id id of the entry * @returns true/false * - * This function sets a navigation entry as active and removes the "active" + * This function sets a navigation entry as active and removes the 'active' * property from all other entries. The templates can use this for * highlighting the current position of the user. */ @@ -201,9 +224,9 @@ class OC_APP{ * This function registers a admin page that will be shown in the admin * menu. $data is an associative array. * The following keys are required: - * - id: unique id for this entry ("files_admin") + * - id: unique id for this entry ('files_admin') * - href: link to the admin page - * - name: Human readable name ("Files Administration") + * - name: Human readable name ('Files Administration') * * The following keys are optional: * - order: integer, that influences the position of your application in @@ -222,16 +245,16 @@ class OC_APP{ * * This function registers a settings page. $data is an associative array. * The following keys are required: - * - app: app the settings belong to ("files") - * - id: unique id for this entry ("files_public") + * - app: app the settings belong to ('files') + * - id: unique id for this entry ('files_public') * - href: link to the admin page - * - name: Human readable name ("Public files") + * - name: Human readable name ('Public files') * * The following keys are optional: * - order: integer, that influences the position of your application in * the list. Lower values come first. * - * For the main settings page of an app, the keys "app" and "id" have to be + * For the main settings page of an app, the keys 'app' and 'id' have to be * the same. */ public static function addSettingsPage( $data = array()){ @@ -245,11 +268,11 @@ class OC_APP{ * @returns associative array * * This function returns an array containing all entries added. The - * entries are sorted by the key "order" ascending. Additional to the keys + * entries are sorted by the key 'order' ascending. Additional to the keys * given for each app the following keys exist: * - active: boolean, signals if the user is on this navigation entry - * - children: array that is empty if the key "active" is false or - * contains the subentries if the key "active" is true + * - children: array that is empty if the key 'active' is false or + * contains the subentries if the key 'active' is true */ public static function getNavigation(){ $navigation = self::proceedNavigation( self::$navigation ); @@ -262,7 +285,7 @@ class OC_APP{ * @returns associative array * * This function returns an array containing all settings pages added. The - * entries are sorted by the key "order" ascending. + * entries are sorted by the key 'order' ascending. */ public static function getSettingsNavigation(){ $navigation = self::proceedNavigation( self::$settingspages ); @@ -276,7 +299,7 @@ class OC_APP{ * @returns associative array * * This function returns an array containing all admin pages added. The - * entries are sorted by the key "order" ascending. + * entries are sorted by the key 'order' ascending. */ public static function getAdminNavigation(){ $navigation = self::proceedNavigation( self::$adminpages ); @@ -290,38 +313,47 @@ class OC_APP{ $found = false; foreach( self::$subnavigation as $parent => $selection ){ foreach( $selection as $subentry ){ - if( $subentry["id"] == self::$activeapp ){ + if( $subentry['id'] == self::$activeapp ){ foreach( $list as &$naventry ){ - if( $naventry["id"] == $parent ){ - $naventry["active"] = true; - $naventry["subnavigation"] = $selection; + if( $naventry['id'] == $parent ){ + $naventry['active'] = true; + $naventry['subnavigation'] = $selection; } else{ - $naventry["active"] = false; + $naventry['active'] = false; } - } + } unset( $naventry ); $found = true; } } } + // Mark subentry as active + foreach( $list as &$naventry ){ + if( $naventry['active'] ){ + foreach( $naventry['subnavigation'] as &$subnaventry ){ + $subnaventry['active'] = $subnaventry['id'] == self::$activeapp? true : false; + } unset( $subnaventry ); + } + } unset( $naventry ); + return $list; } /// This is private as well. It simply works, so don't ask for more details private static function proceedNavigation( $list ){ foreach( $list as &$naventry ){ - $naventry["subnavigation"] = array(); - if( $naventry["id"] == self::$activeapp ){ - $naventry["active"] = true; - if( array_key_exists( $naventry["id"], self::$subnavigation )){ - $naventry["subnavigation"] = self::$subnavigation[$naventry["id"]]; + $naventry['subnavigation'] = array(); + if( $naventry['id'] == self::$activeapp ){ + $naventry['active'] = true; + if( array_key_exists( $naventry['id'], self::$subnavigation )){ + $naventry['subnavigation'] = self::$subnavigation[$naventry['id']]; } } else{ - $naventry["active"] = false; + $naventry['active'] = false; } - } + } unset( $naventry ); usort( $list, create_function( '$a, $b', 'if( $a["order"] == $b["order"] ){return 0;}elseif( $a["order"] < $b["order"] ){return -1;}else{return 1;}' )); diff --git a/lib/base.php b/lib/base.php index e5b6656c2a9..e821d78fd8c 100644 --- a/lib/base.php +++ b/lib/base.php @@ -35,7 +35,11 @@ $SERVERROOT=substr(__FILE__,0,-13); $DOCUMENTROOT=realpath($_SERVER['DOCUMENT_ROOT']); $SERVERROOT=str_replace("\\",'/',$SERVERROOT); $SUBURI=substr(realpath($_SERVER["SCRIPT_FILENAME"]),strlen($SERVERROOT)); -$WEBROOT=substr($_SERVER["SCRIPT_NAME"],0,strlen($_SERVER["SCRIPT_NAME"])-strlen($SUBURI)); +$scriptName=$_SERVER["SCRIPT_NAME"]; +if(substr($scriptName,-1)=='/'){//if the script isn't a file assume index.php + $scriptName.='index.php'; +} +$WEBROOT=substr($scriptName,0,strlen($scriptName)-strlen($SUBURI)); @@ -80,7 +84,12 @@ require_once('appconfig.php'); require_once('files.php'); require_once('filesystem.php'); require_once('filestorage.php'); +<<<<<<< HEAD require_once('apps/files_sharing/sharedstorage.php'); +======= +require_once('l10n.php'); +require_once('preferences.php'); +>>>>>>> master require_once('log.php'); require_once('user.php'); require_once('group.php'); @@ -92,7 +101,7 @@ require_once('search.php'); $error=(count(OC_UTIL::checkServer())>0); -OC_USER::setBackend( OC_CONFIG::getValue( "userbackend", "database" )); +OC_USER::useBackend( OC_CONFIG::getValue( "userbackend", "database" )); OC_GROUP::setBackend( OC_CONFIG::getValue( "groupbackend", "database" )); // Set up file system unless forbidden @@ -119,6 +128,7 @@ if(!$error and !$RUNTIME_NOAPPS ){ class OC_UTIL { public static $scripts=array(); public static $styles=array(); + public static $headers=array(); private static $fsSetup=false; // Can be set up @@ -141,12 +151,12 @@ class OC_UTIL { // If we are not forced to load a specific user we load the one that is logged in if( $user == "" && OC_USER::isLoggedIn()){ - $user = $_SESSION['user_id']; + $user = OC_USER::getUser(); } if( $user != "" ){ //if we aren't logged in, there is no use to set up the filesystem //first set up the local "root" storage and the backupstorage if needed - $rootStorage=OC_FILESYSTEM::createStorage('local',array('datadir'=>$CONFIG_DATADIRECTORY)); + $rootStorage=OC_FILESYSTEM::createStorage('local',array('datadir'=>$CONFIG_DATADIRECTORY_ROOT)); // if( OC_CONFIG::getValue( "enablebackup", false )){ // // This creates the Directorys recursively // if(!is_dir( "$CONFIG_BACKUPDIRECTORY/$user/$root" )){ @@ -187,6 +197,11 @@ class OC_UTIL { } } + public static function tearDownFS(){ + OC_FILESYSTEM::tearDown(); + self::$fsSetup=false; + } + /** * get the current installed version of ownCloud * @return array @@ -229,6 +244,16 @@ class OC_UTIL { } } + /** + * @brief Add a custom element to the header + * @param string tag tag name of the element + * @param array $attributes array of attrobutes for the element + * @param string $text the text content for the element + */ + public static function addHeader( $tag, $attributes, $text=''){ + self::$headers[]=array('tag'=>$tag,'attributes'=>$attributes,'text'=>$text); + } + /** * formats a timestamp in the "right" way * diff --git a/lib/config.php b/lib/config.php index 6af9fcbe5ad..cd18ddd499c 100644 --- a/lib/config.php +++ b/lib/config.php @@ -139,7 +139,7 @@ class OC_CONFIG{ // Include the file, save the data from $CONFIG include( "$SERVERROOT/config/config.php" ); - if( isset( $CONFIG ) || is_array( $CONFIG )){ + if( isset( $CONFIG ) && is_array( $CONFIG )){ self::$cache = $CONFIG; } @@ -169,9 +169,6 @@ class OC_CONFIG{ $value = $value ? 'true' : 'false'; $content .= "\"$key\" => $value,\n"; } - elseif( is_numeric( $value )){ - $content .= "\"$key\" => $value,\n"; - } else{ $value = str_replace( "'", "\\'", $value ); $content .= "\"$key\" => '$value',\n"; diff --git a/lib/database.php b/lib/database.php index 728e7359040..8d7c76756c1 100644 --- a/lib/database.php +++ b/lib/database.php @@ -60,10 +60,10 @@ class OC_DB { 'quote_identifier' => true ); // Add the dsn according to the database type - if( $CONFIG_DBTYPE == 'sqlite' ){ + if( $CONFIG_DBTYPE == 'sqlite' or $CONFIG_DBTYPE == 'sqlite3' ){ // sqlite $dsn = array( - 'phptype' => 'sqlite', + 'phptype' => $CONFIG_DBTYPE, 'database' => "$datadir/$CONFIG_DBNAME.db", 'mode' => '0644' ); } @@ -100,6 +100,9 @@ class OC_DB { // We always, really always want associative arrays self::$DBConnection->setFetchMode(MDB2_FETCHMODE_ASSOC); + + //we need to function module for query pre-procesing + self::$DBConnection->loadModule('Function'); } // we are done. great! @@ -297,15 +300,14 @@ class OC_DB { * and replaces the ` woth ' or " according to the database driver. */ private static function processQuery( $query ){ + self::connect(); // We need Database type and table prefix $CONFIG_DBTYPE = OC_CONFIG::getValue( "dbtype", "sqlite" ); $CONFIG_DBTABLEPREFIX = OC_CONFIG::getValue( "dbtableprefix", "oc_" ); // differences is getting the current timestamp - if( $CONFIG_DBTYPE == 'sqlite' ){ - $query = str_replace( 'NOW()', "strftime('%s', 'now')", $query ); - $query = str_replace( 'now()', "strftime('%s', 'now')", $query ); - } + $query = str_replace( 'NOW()', self::$DBConnection->now(), $query ); + $query = str_replace( 'now()', self::$DBConnection->now(), $query ); // differences in escaping of table names (` for mysql) // Problem: what if there is a ` in the value we want to insert? @@ -321,5 +323,43 @@ class OC_DB { return $query; } + + /** + * @brief drop a table + * @param string $tableNamme the table to drop + */ + public static function dropTable($tableName){ + self::connect(); + self::$DBConnection->loadModule('Manager'); + self::$DBConnection->dropTable($tableName); + } + + /** + * remove all tables defined in a database structure xml file + * @param string $file the xml file describing the tables + */ + public static function removeDBStructure($file){ + $CONFIG_DBNAME = OC_CONFIG::getValue( "dbname", "owncloud" ); + $CONFIG_DBTABLEPREFIX = OC_CONFIG::getValue( "dbtableprefix", "oc_" ); + self::connectScheme(); + + // read file + $content = file_get_contents( $file ); + + // Make changes and save them to a temporary file + $file2 = tempnam( sys_get_temp_dir(), 'oc_db_scheme_' ); + $content = str_replace( '*dbname*', $CONFIG_DBNAME, $content ); + $content = str_replace( '*dbprefix*', $CONFIG_DBTABLEPREFIX, $content ); + file_put_contents( $file2, $content ); + + // get the tables + $definition = self::$schema->parseDatabaseDefinitionFile( $file2 ); + + // Delete our temporary file + unlink( $file2 ); + foreach($definition['tables'] as $name=>$table){ + self::dropTable($name); + } + } } ?>
\ No newline at end of file diff --git a/lib/files.php b/lib/files.php index 9e66f9dab82..d8133667954 100644 --- a/lib/files.php +++ b/lib/files.php @@ -30,15 +30,6 @@ require_once("log.php"); */ class OC_FILES { static $tmpFiles=array(); - /** - * show a web GUI filebrowser - * - * @param basedir $basedir - * @param dir $dir - */ - public static function showBrowser($basedir,$dir){ - echo '<div id="content"></div>'; - } /** * get the content of a directory @@ -101,7 +92,7 @@ class OC_FILES { if(strpos($files,';')){ $files=explode(';',$files); } - echo 't'; + if(is_array($files)){ $zip = new ZipArchive(); $filename = sys_get_temp_dir()."/ownCloud.zip"; @@ -300,13 +291,13 @@ class OC_FILES { global $SERVERROOT; global $WEBROOT; $size=OC_HELPER::humanFileSize($size); - echo $size; $size=substr($size,0,-1);//strip the B $size=str_replace(' ','',$size); //remove the space between the size and the postfix - $content = "ErrorDocument 404 /$WEBROOT/templates/404.php\n";//custom 404 error page + $content = "ErrorDocument 404 /$WEBROOT/core/templates/404.php\n";//custom 404 error page $content.= "php_value upload_max_filesize $size\n";//upload limit $content.= "php_value post_max_size $size\n"; $content.= "SetEnv htaccessWorking true\n"; + $content.= "Options -Indexes\n"; @file_put_contents($SERVERROOT.'/.htaccess', $content); //supress errors in case we don't have permissions for it } } diff --git a/lib/filestorage.php b/lib/filestorage.php index 157e44ff298..819ad2e60b3 100644 --- a/lib/filestorage.php +++ b/lib/filestorage.php @@ -377,7 +377,7 @@ class OC_FILESTORAGE_LOCAL extends OC_FILESTORAGE{ if ($item == '.' || $item == '..') continue; if(is_file($dir.'/'.$item)){ if(unlink($dir.'/'.$item)){ - $this->clearFolderSizeCache($path); + $this->clearFolderSizeCache($dir); } }elseif(is_dir($dir.'/'.$item)){ if (!$this->delTree($dirRelative. "/" . $item)){ diff --git a/lib/filesystem.php b/lib/filesystem.php index a13363f832d..4116cb93164 100644 --- a/lib/filesystem.php +++ b/lib/filesystem.php @@ -29,10 +29,18 @@ * * Hooks provided: * read(path) - * write(path) - * create(path) (when a file is created both, write and create will be emited) - * delete(path) - * rename(oldpath,newpath) + * write(path, &run) + * post_write(path) + * create(path, &run) (when a file is created, both create and write will be emited in that order) + * post_create(path) + * delete(path, &run) + * post_delete(path) + * rename(oldpath,newpath, &run) + * post_rename(oldpath,newpath) + * copy(oldpath,newpath, &run) (if the newpath doesn't exists yes, copy, create and write will be emited in that order) + * post_rename(oldpath,newpath) + * + * the &run parameter can be set to false to prevent the operation from occuring */ class OC_FILESYSTEM{ static private $storages=array(); @@ -68,6 +76,16 @@ class OC_FILESYSTEM{ } /** + * tear down the filesystem, removing all storage providers + */ + static public function tearDown(){ + foreach(self::$storages as $mountpoint=>$storage){ + unset(self::$storages[$mountpoint]); + } + $fakeRoot=''; + } + + /** * create a new storage of a specific type * @param string type * @param array arguments @@ -91,8 +109,10 @@ class OC_FILESYSTEM{ * @return bool */ static public function chroot($fakeRoot){ - if($fakeRoot[0]!=='/'){ - $fakeRoot='/'.$fakeRoot; + if(!$fakeRoot==''){ + if($fakeRoot[0]!=='/'){ + $fakeRoot='/'.$fakeRoot; + } } self::$fakeRoot=$fakeRoot; } @@ -210,14 +230,28 @@ class OC_FILESYSTEM{ static public function mkdir($path){ $parent=substr($path,0,strrpos($path,'/')); if(self::canWrite($parent) and $storage=self::getStorage($path)){ - OC_HOOK::emit( 'OC_FILESYSTEM', 'create', array( 'path' => $path)); - return $storage->mkdir(self::getInternalPath($path)); + $run=true; + OC_HOOK::emit( 'OC_FILESYSTEM', 'create', array( 'path' => $path, 'run' => &$run)); + if($run){ + OC_HOOK::emit( 'OC_FILESYSTEM', 'write', array( 'path' => $path, 'run' => &$run)); + } + if($run){ + $result=$storage->mkdir(self::getInternalPath($path)); + OC_HOOK::emit( 'OC_FILESYSTEM', 'post_create', array( 'path' => $path)); + OC_HOOK::emit( 'OC_FILESYSTEM', 'post_write', array( 'path' => $path)); + return $result; + } } } static public function rmdir($path){ if(self::canWrite($path) and $storage=self::getStorage($path)){ - OC_HOOK::emit( 'OC_FILESYSTEM', 'delete', array( 'path' => $path)); - return $storage->rmdir(self::getInternalPath($path)); + $run=true; + OC_HOOK::emit( 'OC_FILESYSTEM', 'delete', array( 'path' => $path, 'run' => &$run)); + if($run){ + $result=$storage->rmdir(self::getInternalPath($path)); + OC_HOOK::emit( 'OC_FILESYSTEM', 'post_delete', array( 'path' => $path)); + return $result; + } } } static public function opendir($path){ @@ -307,55 +341,94 @@ class OC_FILESYSTEM{ } static public function file_put_contents($path,$data){ if(self::canWrite($path) and $storage=self::getStorage($path)){ - OC_HOOK::emit( 'OC_FILESYSTEM', 'write', array( 'path' => $path)); - if(!self::file_exists($path)){ - OC_HOOK::emit( 'OC_FILESYSTEM', 'create', array( 'path' => $path)); + $run=true; + $exists=self::file_exists($path); + if(!$exists){ + OC_HOOK::emit( 'OC_FILESYSTEM', 'create', array( 'path' => $path, 'run' => &$run)); + } + if($run){ + OC_HOOK::emit( 'OC_FILESYSTEM', 'write', array( 'path' => $path, 'run' => &$run)); + } + if($run){ + $result=$storage->file_put_contents(self::getInternalPath($path),$data); + if(!$exists){ + OC_HOOK::emit( 'OC_FILESYSTEM', 'post_create', array( 'path' => $path)); + } + OC_HOOK::emit( 'OC_FILESYSTEM', 'post_write', array( 'path' => $path)); + return $result; } - return $storage->file_put_contents(self::getInternalPath($path),$data); } } static public function unlink($path){ if(self::canWrite($path) and $storage=self::getStorage($path)){ - OC_HOOK::emit( 'OC_FILESYSTEM', 'delete', array( 'path' => $path)); - return $storage->unlink(self::getInternalPath($path)); + $run=true; + OC_HOOK::emit( 'OC_FILESYSTEM', 'delete', array( 'path' => $path, 'run' => &$run)); + if($run){ + $result=$storage->unlink(self::getInternalPath($path)); + OC_HOOK::emit( 'OC_FILESYSTEM', 'post_delete', array( 'path' => $path)); + return $result; + } } } static public function rename($path1,$path2){ if(self::canWrite($path1) and self::canWrite($path2)){ - $mp1=self::getMountPoint($path1); - $mp2=self::getMountPoint($path2); - if($mp1==$mp2){ - if($storage=self::getStorage($path1)){ - return $storage->rename(self::getInternalPath($path1),self::getInternalPath($path2)); + $run=true; + OC_HOOK::emit( 'OC_FILESYSTEM', 'rename', array( 'oldpath' => $path1 ,'newpath'=>$path2, 'run' => &$run)); + if($run){ + $mp1=self::getMountPoint($path1); + $mp2=self::getMountPoint($path2); + if($mp1==$mp2){ + if($storage=self::getStorage($path1)){ + $result=$storage->rename(self::getInternalPath($path1),self::getInternalPath($path2)); + } + }elseif($storage1=self::getStorage($path1) and $storage2=self::getStorage($path2)){ + $tmpFile=$storage1->toTmpFile(self::getInternalPath($path1)); + $result=$storage2->fromTmpFile(self::getInternalPath($path2)); + $storage1->unlink(self::getInternalPath($path1)); } - }elseif($storage1=self::getStorage($path1) and $storage2=self::getStorage($path2)){ - $tmpFile=$storage1->toTmpFile(self::getInternalPath($path1)); - $result=$storage2->fromTmpFile(self::getInternalPath($path2)); - $storage1->unlink(self::getInternalPath($path1)); + OC_HOOK::emit( 'OC_FILESYSTEM', 'post_rename', array( 'oldpath' => $path1, 'newpath'=>$path2)); return $result; } - OC_HOOK::emit( 'OC_FILESYSTEM', 'rename', array( 'oldpath' => $path1 ,'newpath'=>$path2)); } } static public function copy($path1,$path2){ if(self::canRead($path1) and self::canWrite($path2)){ - $mp1=self::getMountPoint($path1); - $mp2=self::getMountPoint($path2); - if($mp1==$mp2){ - if($storage=self::getStorage($path1)){ - return $storage->copy(self::getInternalPath($path1),self::getInternalPath($path2)); + $run=true; + OC_HOOK::emit( 'OC_FILESYSTEM', 'copy', array( 'oldpath' => $path1 ,'newpath'=>$path2, 'run' => &$run)); + $exists=self::file_exists($path2); + if($run and !$exists){ + OC_HOOK::emit( 'OC_FILESYSTEM', 'create', array( 'path' => $path2, 'run' => &$run)); + } + if($run){ + OC_HOOK::emit( 'OC_FILESYSTEM', 'write', array( 'path' => $path2, 'run' => &$run)); + } + if($run){ + $mp1=self::getMountPoint($path1); + $mp2=self::getMountPoint($path2); + if($mp1==$mp2){ + if($storage=self::getStorage($path1)){ + $result=$storage->copy(self::getInternalPath($path1),self::getInternalPath($path2)); + } + }elseif($storage1=self::getStorage($path1) and $storage2=self::getStorage($path2)){ + $tmpFile=$storage1->toTmpFile(self::getInternalPath($path1)); + $result=$storage2->fromTmpFile(self::getInternalPath($path2)); + } + OC_HOOK::emit( 'OC_FILESYSTEM', 'post_copy', array( 'oldpath' => $path1 ,'newpath'=>$path2)); + if(!$exists){ + OC_HOOK::emit( 'OC_FILESYSTEM', 'post_create', array( 'path' => $path)); } - }elseif($storage1=self::getStorage($path1) and $storage2=self::getStorage($path2)){ - $tmpFile=$storage1->toTmpFile(self::getInternalPath($path1)); - return $storage2->fromTmpFile(self::getInternalPath($path2)); + OC_HOOK::emit( 'OC_FILESYSTEM', 'post_write', array( 'path' => $path)); + return $result; } - OC_HOOK::emit( 'OC_FILESYSTEM', 'create', array( 'path' => $path2)); } } static public function fopen($path,$mode){ $allowed=((strpos($path,'r')===false and strpos($path,'r+')!==false and self::canRead) or self::canWrite($path)); if($allowed){ if($storage=self::getStorage($path)){ + $run=true; + $exists=self::file_exists($path); + $write=false; switch($mode){ case 'r': OC_HOOK::emit( 'OC_FILESYSTEM', 'read', array( 'path' => $path)); @@ -365,21 +438,34 @@ class OC_FILESYSTEM{ case 'x+': case 'a+': OC_HOOK::emit( 'OC_FILESYSTEM', 'read', array( 'path' => $path)); - OC_HOOK::emit( 'OC_FILESYSTEM', 'write', array( 'path' => $path)); - if(!self::file_exists($path)){ - OC_HOOK::emit( 'OC_FILESYSTEM', 'create', array( 'path' => $path)); - } + $write=true; break; case 'w': case 'x': case 'a': - OC_HOOK::emit( 'OC_FILESYSTEM', 'write', array( 'path' => $path)); - if(!self::file_exists($path)){ - OC_HOOK::emit( 'OC_FILESYSTEM', 'create', array( 'path' => $path)); - } + $write=true; break; } - return $storage->fopen(self::getInternalPath($path),$mode); + if($write){ + if(!$exists){ + OC_HOOK::emit( 'OC_FILESYSTEM', 'create', array( 'path' => $path)); + } + if($run){ + OC_HOOK::emit( 'OC_FILESYSTEM', 'write', array( 'path' => $path, 'run' => &$run)); + } + } + if($run){ + $result=$storage->fopen(self::getInternalPath($path),$mode); + if($write){ + if(!$exists){ + OC_HOOK::emit( 'OC_FILESYSTEM', 'post_create', array( 'path' => $path)); + } + if($run){ + OC_HOOK::emit( 'OC_FILESYSTEM', 'post_write', array( 'path' => $path)); + } + } + return $result; + } } } } @@ -391,20 +477,44 @@ class OC_FILESYSTEM{ } static public function fromTmpFile($tmpFile,$path){ if(self::canWrite($path) and $storage=self::getStorage($path)){ - OC_HOOK::emit( 'OC_FILESYSTEM', 'write', array( 'path' => $path)); - if(!self::file_exists($path)){ - OC_HOOK::emit( 'OC_FILESYSTEM', 'create', array( 'path' => $path)); + $run=true; + $exists=self::file_exists($path); + if(!$exists){ + OC_HOOK::emit( 'OC_FILESYSTEM', 'create', array( 'path' => $path, 'run' => &$run)); + } + if($run){ + OC_HOOK::emit( 'OC_FILESYSTEM', 'write', array( 'path' => $path, 'run' => &$run)); + } + if($run){ + $result=$storage->fromTmpFile($tmpFile,self::getInternalPath($path)); + if(!$exists){ + OC_HOOK::emit( 'OC_FILESYSTEM', 'post_create', array( 'path' => $path)); + } + OC_HOOK::emit( 'OC_FILESYSTEM', 'post_write', array( 'path' => $path)); + return $result; } - return $storage->fromTmpFile($tmpFile,self::getInternalPath($path)); } } static public function fromUploadedFile($tmpFile,$path){ + error_log('upload'); if(self::canWrite($path) and $storage=self::getStorage($path)){ - OC_HOOK::emit( 'OC_FILESYSTEM', 'write', array( 'path' => $path)); - if(!self::file_exists($path)){ - OC_HOOK::emit( 'OC_FILESYSTEM', 'create', array( 'path' => $path)); + $run=true; + $exists=self::file_exists($path); + if(!$exists){ + OC_HOOK::emit( 'OC_FILESYSTEM', 'create', array( 'path' => $path, 'run' => &$run)); + } + if($run){ + OC_HOOK::emit( 'OC_FILESYSTEM', 'write', array( 'path' => $path, 'run' => &$run)); + } + error_log('upload2'); + if($run){ + $result=$storage->fromUploadedFile($tmpFile,self::getInternalPath($path)); + if(!$exists){ + OC_HOOK::emit( 'OC_FILESYSTEM', 'post_create', array( 'path' => $path)); + } + OC_HOOK::emit( 'OC_FILESYSTEM', 'post_write', array( 'path' => $path)); + return $result; } - return $storage->fromUploadedFile($tmpFile,self::getInternalPath($path)); } } static public function getMimeType($path){ @@ -414,8 +524,11 @@ class OC_FILESYSTEM{ } static public function delTree($path){ if(self::canWrite($path) and $storage=self::getStorage($path)){ - OC_HOOK::emit( 'OC_FILESYSTEM', 'delete', array( 'path' => $path)); - return $storage->delTree(self::getInternalPath($path)); + $run=true; + OC_HOOK::emit( 'OC_FILESYSTEM', 'delete', array( 'path' => $path, 'run' => &$run)); + if($run){ + return $storage->delTree(self::getInternalPath($path)); + } } } static public function find($path){ @@ -463,10 +576,12 @@ class OC_FILESYSTEM{ $fakeRootLength=strlen(self::$fakeRoot); foreach(self::$storages as $mountpoint=>$storage){ $results=$storage->search($query); - foreach($results as $result){ - $file=str_replace('//','/',$mountpoint.$result); - $file=substr($file,$fakeRootLength); - $files[]=$file; + if(is_array($results)){ + foreach($results as $result){ + $file=str_replace('//','/',$mountpoint.$result); + $file=substr($file,$fakeRootLength); + $files[]=$file; + } } } return $files; diff --git a/lib/helper.php b/lib/helper.php index 072607f742b..96d5bfad826 100644..100755 --- a/lib/helper.php +++ b/lib/helper.php @@ -29,22 +29,39 @@ class OC_HELPER { * @brief Creates an url * @param $app app * @param $file file + * @param $redirect_url redirect_url variable is appended to the URL * @returns the url * * Returns a url to the given app and file. */ - public static function linkTo( $app, $file ){ + public static function linkTo( $app, $file , $redirect_url=NULL ){ global $WEBROOT; global $SERVERROOT; - if(!empty($app)) { + if( $app != '' ){ $app .= '/'; // Check if the app is in the app folder - if( file_exists( $SERVERROOT . '/apps/'. $app )){ - return $WEBROOT . '/apps/' . $app . $file; + if( file_exists( $SERVERROOT . '/apps/'. $app.$file )){ + $urlLinkTo = $WEBROOT . '/apps/' . $app . $file; + } + else{ + $urlLinkTo = $WEBROOT . '/' . $app . $file; + } + } + else{ + if( file_exists( $SERVERROOT . '/core/'. $file )){ + $urlLinkTo = $WEBROOT . '/core/'.$file; + } + else{ + $urlLinkTo = $WEBROOT . '/'.$file; } } - return $WEBROOT . '/' . $app . $file; + + if($redirect_url) + return $urlLinkTo.'?redirect_url='.$redirect_url; + else + return $urlLinkTo; + } /** @@ -58,14 +75,16 @@ class OC_HELPER { public static function imagePath( $app, $image ){ global $SERVERROOT; global $WEBROOT; + // Check if the app is in the app folder if( file_exists( "$SERVERROOT/apps/$app/img/$image" )){ return "$WEBROOT/apps/$app/img/$image"; } - if( !empty( $app )){ + elseif( !empty( $app )){ return "$WEBROOT/$app/img/$image"; - }else{ - return "$WEBROOT/img/$image"; + } + else{ + return "$WEBROOT/core/img/$image"; } } @@ -84,15 +103,15 @@ class OC_HELPER { // Is it a dir? if( $mimetype == "dir" ){ - return "$WEBROOT/img/places/folder.png"; + return "$WEBROOT/core/img/places/folder.png"; } // Icon exists? - if( file_exists( "$SERVERROOT/img/mimetypes/$mimetype.png" )){ - return "$WEBROOT/img/mimetypes/$mimetype.png"; + if( file_exists( "$SERVERROOT/core/img/mimetypes/$mimetype.png" )){ + return "$WEBROOT/core/img/mimetypes/$mimetype.png"; } else{ - return "$WEBROOT/img/mimetypes/file.png"; + return "$WEBROOT/core/img/mimetypes/file.png"; } } diff --git a/lib/installer.php b/lib/installer.php index 7ab07bf5077..a237caa0983 100644 --- a/lib/installer.php +++ b/lib/installer.php @@ -59,7 +59,7 @@ class OC_INSTALLER{ if(!isset($data['source'])){ error_log("No source specified when installing app"); - return; + return false; } //download the file if necesary @@ -67,13 +67,13 @@ class OC_INSTALLER{ $path=tempnam(sys_get_temp_dir(),'oc_installer_'); if(!isset($data['href'])){ error_log("No href specified when installing app from http"); - return; + return false; } copy($data['href'],$path); }else{ if(!isset($data['path'])){ error_log("No path specified when installing app from local file"); - return; + return false; } $path=$data['path']; } @@ -92,7 +92,7 @@ class OC_INSTALLER{ if($data['source']=='http'){ unlink($path); } - return; + return false; } //load the info.xml file of the app @@ -102,23 +102,33 @@ class OC_INSTALLER{ if($data['source']=='http'){ unlink($path); } - return; + return false; } $info=OC_APP::getAppInfo($extractDir.'/appinfo/info.xml'); $basedir=$SERVERROOT.'/apps/'.$info['id']; //check if an app with the same id is already installed - if(is_dir($basedir)){ + if(self::isInstalled( $info['id'] )){ error_log("App already installed"); OC_HELPER::rmdirr($extractDir); if($data['source']=='http'){ unlink($path); } - return; + return false; + } + + //check if the destination directory already exists + if(is_dir($basedir)){ + error_log("App's directory already exists"); + OC_HELPER::rmdirr($extractDir); + if($data['source']=='http'){ + unlink($path); + } + return false; } if(isset($data['pretent']) and $data['pretent']==true){ - return; + return false; } //copy the app to the correct place @@ -128,7 +138,7 @@ class OC_INSTALLER{ if($data['source']=='http'){ unlink($path); } - return; + return false; } OC_HELPER::copyr($extractDir,$basedir); @@ -150,6 +160,23 @@ class OC_INSTALLER{ //set the installed version OC_APPCONFIG::setValue($info['id'],'installed_version',$info['version']); + OC_APPCONFIG::setValue($info['id'],'enabled','no'); + return true; + } + + /** + * @brief checks whether or not an app is installed + * @param $app app + * @returns true/false + * + * Checks whether or not an app is installed, i.e. registered in apps table. + */ + public static function isInstalled( $app ){ + + if( null == OC_APPCONFIG::getValue( $app, "installed_version" )){ + return false; + } + return true; } @@ -209,4 +236,42 @@ class OC_INSTALLER{ // TODO: write function return true; } + + /** + * @brief Installs shipped apps + * @param $enabled + * + * This function installs all apps found in the 'apps' directory; + * If $enabled is true, apps are installed as enabled. + * If $enabled is false, apps are installed as disabled. + */ + public static function installShippedApps( $enabled ){ + global $SERVERROOT; + $dir = opendir( "$SERVERROOT/apps" ); + while( false !== ( $filename = readdir( $dir ))){ + if( substr( $filename, 0, 1 ) != '.' and is_dir("$SERVERROOT/apps/$filename") ){ + if( file_exists( "$SERVERROOT/apps/$filename/appinfo/app.php" )){ + if(!OC_INSTALLER::isInstalled($filename)){ + //install the database + if(is_file("$SERVERROOT/apps/$filename/appinfo/database.xml")){ + OC_DB::createDbFromStructure("$SERVERROOT/apps/$filename/appinfo/database.xml"); + } + + //run appinfo/install.php + if(is_file("$SERVERROOT/apps/$filename/appinfo/install.php")){ + include("$SERVERROOT/apps/$filename/appinfo/install.php"); + } + $info=OC_APP::getAppInfo("$SERVERROOT/apps/$filename/appinfo/info.xml"); + OC_APPCONFIG::setValue($filename,'installed_version',$info['version']); + if( $enabled ){ + OC_APPCONFIG::setValue($filename,'enabled','yes'); + }else{ + OC_APPCONFIG::setValue($filename,'enabled','no'); + } + } + } + } + } + closedir( $dir ); + } } diff --git a/lib/l10n.php b/lib/l10n.php new file mode 100644 index 00000000000..053c6fbc10e --- /dev/null +++ b/lib/l10n.php @@ -0,0 +1,269 @@ +<?php +/** + * ownCloud + * + * @author Jakob Sack + * @copyright 2010 Frank Karlitschek karlitschek@kde.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 is for i18n and l10n + */ +class OC_L10N{ + /** + * cache + */ + protected static $cache = array(); + + /** + * The best language + */ + protected static $language = ''; + + /** + * Translations + */ + private $translations = array(); + + /** + * Localization + */ + private $localizations = array( + 'date' => 'd.m.Y', + 'datetime' => 'd.m.Y H:i:s', + 'time' => 'H:i:s' ); + + /** + * @brief The constructor + * @param $app the app requesting l10n + * @param $lang default: null Language + * @returns OC_L10N-Object + * + * If language is not set, the constructor tries to find the right + * language. + */ + public function __construct( $app, $lang = null ){ + global $SERVERROOT; + // Find the right language + if( is_null( $lang )){ + $lang = self::findLanguage( $app ); + } + + // Use cache if possible + if(array_key_exists($app.'::'.$lang, self::$cache )){ + + $this->translations = self::$cache[$app.'::'.$lang]['t']; + $this->localizations = self::$cache[$app.'::'.$lang]['l']; + } + else{ + $i18ndir = self::findI18nDir( $app ); + // Localization is in /l10n, Texts are in $i18ndir + // (Just no need to define date/time format etc. twice) + if( file_exists( $i18ndir.$lang.'.php' )){ + // Include the file, save the data from $CONFIG + include( $i18ndir.$lang.'.php' ); + if( isset( $TRANSLATIONS ) && is_array( $TRANSLATIONS )){ + $this->translations = $TRANSLATIONS; + } + } + + if( file_exists( $SERVERROOT.'/core/l10n/l10n-'.$lang.'.php' )){ + // Include the file, save the data from $CONFIG + include( $SERVERROOT.'/core/l10n/l10n-'.$lang.'.php' ); + if( isset( $LOCALIZATIONS ) && is_array( $LOCALIZATIONS )){ + $this->localizations = array_merge( $this->localizations, $LOCALIZATIONS ); + } + } + + self::$cache[$app.'::'.$lang]['t'] = $this->translations; + self::$cache[$app.'::'.$lang]['l'] = $this->localizations; + } + } + + /** + * @brief Translating + * @param $text The text we need a translation for + * @returns Translation or the same text + * + * Returns the translation. If no translation is found, $text will be + * returned. + */ + public function t($text){ + if(array_key_exists($text, $this->translations)){ + return $this->translations[$text]; + } + return $text; + } + + /** + * @brief getTranslations + * @returns Fetch all translations + * + * Returns an associative array with all translations + */ + public function getTranslations(){ + return $this->translations; + } + + /** + * @brief Localization + * @param $type Type of localization + * @param $params parameters for this localization + * @returns String or false + * + * Returns the localized data. + * + * Implemented types: + * - date + * - Creates a date + * - l10n-field: date + * - params: timestamp (int/string) + * - datetime + * - Creates date and time + * - l10n-field: datetime + * - params: timestamp (int/string) + * - time + * - Creates a time + * - l10n-field: time + * - params: timestamp (int/string) + */ + public function l($type, $data){ + switch($type){ + // If you add something don't forget to add it to $localizations + // at the top of the page + case 'date': + if( is_string( $data )) $data = strtotime( $data ); + return date( $this->localizations['date'], $data ); + break; + case 'datetime': + if( is_string( $data )) $data = strtotime( $data ); + return date( $this->localizations['datetime'], $data ); + break; + case 'time': + if( is_string( $data )) $data = strtotime( $data ); + return date( $this->localizations['time'], $data ); + break; + default: + return false; + } + } + + /** + * @brief Choose a language + * @param $texts Associative Array with possible strings + * @returns String + * + * $text is an array 'de' => 'hallo welt', 'en' => 'hello world', ... + * + * This function is useful to avoid loading thousands of files if only one + * simple string is needed, for example in appinfo.php + */ + public static function selectLanguage( $text ){ + $lang = self::findLanguage( array_keys( $text )); + return $text[$lang]; + } + + /** + * @brief find the best language + * @param $app Array or string, details below + * @returns language + * + * If $app is an array, ownCloud assumes that these are the available + * languages. Otherwise ownCloud tries to find the files in the l10n + * folder. + * + * If nothing works it returns 'en' + */ + public static function findLanguage( $app = null ){ + if( !is_array( $app) && self::$language != '' ){ + return self::$language; + } + + $available = array(); + if( is_array( $app )){ + $available = $app; + } + else{ + $available=self::findAvailableLanguages( $app ); + } + if( OC_USER::getUser() && OC_PREFERENCES::getValue( OC_USER::getUser(), 'core', 'lang' )){ + $lang = OC_PREFERENCES::getValue( OC_USER::getUser(), 'core', 'lang' ); + self::$language = $lang; + if( array_search( $lang, $available ) !== false ){ + return $lang; + } + } + + if( isset( $_SERVER['HTTP_ACCEPT_LANGUAGE'] )){ + $accepted_languages = preg_split( '/,\s*/', $_SERVER['HTTP_ACCEPT_LANGUAGE'] ); + foreach( $accepted_languages as $i ){ + $temp = explode( ';', $i ); + if( array_search( $temp[0], $available ) !== false ){ + return $temp[0]; + } + } + } + + // Last try: English + return 'en'; + } + + /** + * @brief find the l10n directory + * @param $app App that needs to be translated + * @returns directory + */ + protected static function findI18nDir( $app ){ + global $SERVERROOT; + + // find the i18n dir + $i18ndir = $SERVERROOT.'/core/l10n/'; + if( $app != '' ){ + // Check if the app is in the app folder + if( file_exists( $SERVERROOT.'/apps/'.$app.'/l10n/' )){ + $i18ndir = $SERVERROOT.'/apps/'.$app.'/l10n/'; + } + else{ + $i18ndir = $SERVERROOT.'/'.$app.'/l10n/'; + } + } + return $i18ndir; + } + + /** + * @brief find all available languages for an app + * @param $app App that needs to be translated + * @returns array an array of available languages + */ + public static function findAvailableLanguages( $app=null ){ + $available=array('en');//english is always available + $dir = self::findI18nDir( $app ); + if( file_exists($dir)){ + $dh = opendir($dir); + while(( $file = readdir( $dh )) !== false ){ + if( substr( $file, -4, 4 ) == '.php' and strlen($file)==6 ){ + $i = substr( $file, 0, -4 ); + if( $i != '' ){ + $available[] = $i; + } + } + } + closedir($dh); + } + return $available; + } +}
\ No newline at end of file diff --git a/lib/log.php b/lib/log.php index aebeba7d4b3..894575ef059 100644 --- a/lib/log.php +++ b/lib/log.php @@ -79,7 +79,7 @@ class OC_LOG { * - app: only entries for this app */ public static function get( $filter = array()){ - $queryString='SELECT * FROM *PREFIX*log WHERE 1=1 '; + $queryString='SELECT * FROM *PREFIX*log WHERE 1=1 ORDER BY moment DESC'; $params=array(); if(isset($filter['from'])){ $queryString.='AND moment>? '; @@ -120,6 +120,18 @@ class OC_LOG { $query->execute(array($date)); return true; } + + /** + * @brief removes all log entries + * @returns true/false + * + * This function deletes all log entries. + */ + public static function deleteAll(){ + $query=OC_DB::prepare("DELETE FROM *PREFIX*log"); + $query->execute(); + return true; + } /** * @brief filter an array of log entries on action diff --git a/lib/ocsclient.php b/lib/ocsclient.php index a3c4659c6e4..cfd529b2ec4 100644 --- a/lib/ocsclient.php +++ b/lib/ocsclient.php @@ -37,7 +37,10 @@ class OC_OCSCLIENT{ public static function getCategories(){ $url='http://api.apps.owncloud.com/v1/content/categories'; - $xml=file_get_contents($url); + $xml=@file_get_contents($url); + if($xml==FALSE){ + return NULL; + } $data=simplexml_load_string($xml); $tmp=$data->data; @@ -61,16 +64,19 @@ class OC_OCSCLIENT{ * This function returns a list of all the applications on the OCS server */ public static function getApplications($categories){ - if(is_array($categories)) { + if(is_array($categories)) { $categoriesstring=implode('x',$categories); }else{ $categoriesstring=$categories; } $url='http://api.apps.owncloud.com/v1/content/data?categories='.urlencode($categoriesstring).'&sortmode=new&page=0&pagesize=10'; $apps=array(); - $xml=file_get_contents($url); + $xml=@file_get_contents($url); + if($xml==FALSE){ + return NULL; + } $data=simplexml_load_string($xml); - + $tmp=$data->data->content; for($i = 0; $i < count($tmp); $i++) { $app=array(); @@ -90,60 +96,66 @@ class OC_OCSCLIENT{ } - /** - * @brief Get an the applications from the OCS server - * @returns array with application data - * - * This function returns an applications from the OCS server - */ - public static function getApplication($id){ - $url='http://api.apps.owncloud.com/v1/content/data/'.urlencode($id); - - $xml=file_get_contents($url); - $data=simplexml_load_string($xml); - - $tmp=$data->data->content; - $app=array(); - $app['id']=$tmp->id; - $app['name']=$tmp->name; - $app['type']=$tmp->typeid; - $app['typename']=$tmp->typename; - $app['personid']=$tmp->personid; - $app['detailpage']=$tmp->detailpage; - $app['preview1']=$tmp->smallpreviewpic1; - $app['preview2']=$tmp->smallpreviewpic2; - $app['preview3']=$tmp->smallpreviewpic3; - $app['changed']=strtotime($tmp->changed); - $app['description']=$tmp->description; - - return $app; - } - - /** - * @brief Get all the knowledgebase entries from the OCS server - * @returns array with q and a data - * - * This function returns a list of all the knowledgebase entries from the OCS server - */ - public static function getKnownledgebaseEntries(){ - $url='http://api.apps.owncloud.com/v1/knowledgebase/data?type=150&page=0&pagesize=10'; - - $kbe=array(); - $xml=file_get_contents($url); - $data=simplexml_load_string($xml); - - $tmp=$data->data->content; - for($i = 0; $i < count($tmp); $i++) { - $kb=array(); - $kb['id']=$tmp[$i]->id; - $kb['name']=$tmp[$i]->name; - $kb['description']=$tmp[$i]->description; - $kb['answer']=$tmp[$i]->answer; - $kb['preview1']=$tmp[$i]->smallpreviewpic1; - $kbe[]=$kb; - } - return $kbe; - } + /** + * @brief Get an the applications from the OCS server + * @returns array with application data + * + * This function returns an applications from the OCS server + */ + public static function getApplication($id){ + $url='http://api.apps.owncloud.com/v1/content/data/'.urlencode($id); + + $xml=@file_get_contents($url); + if($xml==FALSE){ + return NULL; + } + $data=simplexml_load_string($xml); + + $tmp=$data->data->content; + $app=array(); + $app['id']=$tmp->id; + $app['name']=$tmp->name; + $app['type']=$tmp->typeid; + $app['typename']=$tmp->typename; + $app['personid']=$tmp->personid; + $app['detailpage']=$tmp->detailpage; + $app['preview1']=$tmp->smallpreviewpic1; + $app['preview2']=$tmp->smallpreviewpic2; + $app['preview3']=$tmp->smallpreviewpic3; + $app['changed']=strtotime($tmp->changed); + $app['description']=$tmp->description; + + return $app; + } + + /** + * @brief Get all the knowledgebase entries from the OCS server + * @returns array with q and a data + * + * This function returns a list of all the knowledgebase entries from the OCS server + */ + public static function getKnownledgebaseEntries(){ + $url='http://api.apps.owncloud.com/v1/knowledgebase/data?type=150&page=0&pagesize=10'; + + $kbe=array(); + $xml=@file_get_contents($url); + if($xml==FALSE){ + return NULL; + } + $data=simplexml_load_string($xml); + + $tmp=$data->data->content; + for($i = 0; $i < count($tmp); $i++) { + $kb=array(); + $kb['id']=$tmp[$i]->id; + $kb['name']=$tmp[$i]->name; + $kb['description']=$tmp[$i]->description; + $kb['answer']=$tmp[$i]->answer; + $kb['preview1']=$tmp[$i]->smallpreviewpic1; + $kbe[]=$kb; + } + return $kbe; + } diff --git a/lib/preferences.php b/lib/preferences.php index 5a9ed395085..0f4636f6832 100644 --- a/lib/preferences.php +++ b/lib/preferences.php @@ -139,10 +139,12 @@ class OC_PREFERENCES{ */ public static function setValue( $user, $app, $key, $value ){ // Check if the key does exist - $exists = self::getValue( $user, $app, $key, null ); + $query = OC_DB::prepare( 'SELECT configvalue FROM *PREFIX*preferences WHERE userid = ? AND appid = ? AND configkey = ?' ); + $values=$query->execute(array($user,$app,$key))->fetchAll(); + error_log(print_r($values,true)); + $exists=(count($values)>0); - // null: does not exist. Insert. - if( is_null( $exists )){ + if( !$exists ){ $query = OC_DB::prepare( 'INSERT INTO *PREFIX*preferences ( userid, appid, configkey, configvalue ) VALUES( ?, ?, ?, ? )' ); $query->execute( array( $user, $app, $key, $value )); } diff --git a/lib/setup.php b/lib/setup.php index 72507f221b9..1be4dea286d 100644 --- a/lib/setup.php +++ b/lib/setup.php @@ -1,6 +1,8 @@ <?php -$hasSQLite = is_callable('sqlite_open'); +include_once( 'installer.php' ); + +$hasSQLite = (is_callable('sqlite_open') or class_exists('SQLite3')); $hasMySQL = is_callable('mysql_connect'); $datadir = OC_CONFIG::getValue('datadir', $SERVERROOT.'/data'); $opts = array( @@ -21,7 +23,7 @@ if(isset($_POST['install']) AND $_POST['install']=='true') { OC_TEMPLATE::printGuestPage("", "installation", $options); } else { - header("Location: $WEBROOT"); + header("Location: ".$WEBROOT.'/'); exit(); } } @@ -65,10 +67,15 @@ class OC_SETUP { $username = htmlspecialchars_decode($options['adminlogin']); $password = htmlspecialchars_decode($options['adminpass']); $datadir = htmlspecialchars_decode($options['directory']); + + //use sqlite3 when available, otherise sqlite2 will be used. + if($dbtype=='sqlite' and class_exists('SQLite3')){ + $dbtype='sqlite3'; + } //write the config file OC_CONFIG::setValue('datadirectory', $datadir); - OC_CONFIG::setValue('dbtype', $dbtype); + OC_CONFIG::setValue('dbtype', $dbtype); if($dbtype == 'mysql') { $dbuser = $options['dbuser']; $dbpass = $options['dbpass']; @@ -90,13 +97,20 @@ class OC_SETUP { else { $query="SELECT user FROM mysql.user WHERE user='$dbuser'"; //this should be enough to check for admin rights in mysql if(mysql_query($query, $connection)) { - self::createDBUser($username, $password, $connection); //use the admin login data for the new database user - OC_CONFIG::setValue('dbuser', $username); - OC_CONFIG::setValue('dbpassword', $password); + + //add prefix to the mysql user name to prevent collissions + $dbusername='oc_mysql_'.$username; + //hash the password so we don't need to store the admin config in the config file + $dbpassowrd=md5(time().$password); + + self::createDBUser($dbusername, $dbpassowrd, $connection); + + OC_CONFIG::setValue('dbuser', $dbusername); + OC_CONFIG::setValue('dbpassword', $dbpassowrd); //create the database - self::createDatabase($dbname, $username, $connection); + self::createDatabase($dbname, $dbusername, $connection); } else { OC_CONFIG::setValue('dbuser', $dbuser); @@ -128,6 +142,9 @@ class OC_SETUP { OC_GROUP::createGroup('admin'); OC_GROUP::addToGroup($username, 'admin'); + //guess what this does + OC_INSTALLER::installShippedApps(true); + //create htaccess files for apache hosts self::createHtaccess(); //TODO detect if apache is used @@ -167,10 +184,11 @@ class OC_SETUP { private static function createHtaccess() { global $SERVERROOT; global $WEBROOT; - $content = "ErrorDocument 404 /$WEBROOT/templates/404.php\n";//custom 404 error page + $content = "ErrorDocument 404 /$WEBROOT/core/templates/404.php\n";//custom 404 error page $content.= "php_value upload_max_filesize 20M\n";//upload limit $content.= "php_value post_max_size 20M\n"; $content.= "SetEnv htaccessWorking true\n"; + $content.= "Options -Indexes\n"; @file_put_contents($SERVERROOT.'/.htaccess', $content); //supress errors in case we don't have permissions for it $content = "deny from all"; @@ -178,4 +196,4 @@ class OC_SETUP { } } -?>
\ No newline at end of file +?> diff --git a/lib/template.php b/lib/template.php index 0d6776aa26d..9393fe6908e 100644 --- a/lib/template.php +++ b/lib/template.php @@ -73,8 +73,10 @@ function human_file_size( $bytes ){ class OC_TEMPLATE{ private $renderas; // Create a full page? private $application; // template Application - private $vars; // The smarty object - private $template; // The smarty object + private $vars; // Vars + private $template; // The path to the template + private $l10n; // The l10n-Object + private $headers=array(); //custom headers /** * @brief Constructor @@ -94,8 +96,8 @@ class OC_TEMPLATE{ global $SERVERROOT; // Get the right template folder - $template = "$SERVERROOT/templates/"; - if( $app != "core" && $app != "" ){ + $template = "$SERVERROOT/core/templates/"; + if( $app != "" ){ // Check if the app is in the app folder if( file_exists( "$SERVERROOT/apps/$app/templates/" )){ $template = "$SERVERROOT/apps/$app/templates/"; @@ -113,6 +115,7 @@ class OC_TEMPLATE{ $this->application = $app; $this->template = $template; $this->vars = array(); + $this->l10n = new OC_L10N($app); } /** @@ -149,6 +152,16 @@ class OC_TEMPLATE{ $this->vars[$key] = array( $value ); } } + + /** + * @brief Add a custom element to the header + * @param string tag tag name of the element + * @param array $attributes array of attrobutes for the element + * @param string $text the text content for the element + */ + public function addHeader( $tag, $attributes, $text=''){ + $this->headers[]=array('tag'=>$tag,'attributes'=>$attributes,'text'=>$text); + } /** * @brief Prints the proceeded template @@ -193,7 +206,6 @@ class OC_TEMPLATE{ $search=new OC_TEMPLATE( 'core', 'part.searchbox'); $search->assign('searchurl',OC_HELPER::linkTo( 'search', 'index.php' )); $page->assign('searchbox', $search->fetchPage()); - // Add menu data // Add navigation entry $page->assign( "navigation", OC_APP::getNavigation()); @@ -204,34 +216,48 @@ class OC_TEMPLATE{ $search=new OC_TEMPLATE( 'core', 'part.searchbox'); $search->assign('searchurl',OC_HELPER::linkTo( 'search', 'index.php' )); $page->assign('searchbox', $search->fetchPage()); + // Add menu data if( OC_GROUP::inGroup( $_SESSION["user_id"], "admin" )){ - $page->assign( "settingsnavigation", OC_APP::getSettingsNavigation()); + $page->assign( "adminnavigation", OC_APP::getAdminNavigation()); } - $page->assign( "adminnavigation", OC_APP::getAdminNavigation()); + $page->assign( "settingsnavigation", OC_APP::getSettingsNavigation()); } else { $page = new OC_TEMPLATE( "core", "layout.guest" ); - // Add data if required } // Add the css and js files foreach(OC_UTIL::$scripts as $script){ if(is_file("$SERVERROOT/apps/$script.js" )){ $page->append( "jsfiles", "$WEBROOT/apps/$script.js" ); - }else{ + } + elseif(is_file("$SERVERROOT/$script.js" )){ $page->append( "jsfiles", "$WEBROOT/$script.js" ); } + else{ + $page->append( "jsfiles", "$WEBROOT/core/$script.js" ); + } } foreach(OC_UTIL::$styles as $style){ if(is_file("$SERVERROOT/apps/$style.css" )){ $page->append( "cssfiles", "$WEBROOT/apps/$style.css" ); - }else{ + } + elseif(is_file("$SERVERROOT/$style.css" )){ $page->append( "cssfiles", "$WEBROOT/$style.css" ); } + else{ + $page->append( "cssfiles", "$WEBROOT/core/$style.css" ); + } } - + + // Add custom headers + $page->assign('headers',$this->headers); + foreach(OC_UTIL::$headers as $header){ + $page->append('headers',$header); + } + // Add css files and js files $page->assign( "content", $data ); return $page->fetchPage(); @@ -251,6 +277,7 @@ class OC_TEMPLATE{ private function _fetch(){ // Register the variables $_ = $this->vars; + $l = $this->l10n; // Execute the template ob_start(); diff --git a/lib/testcase.php b/lib/testcase.php new file mode 100644 index 00000000000..19494dc2f19 --- /dev/null +++ b/lib/testcase.php @@ -0,0 +1,93 @@ +<?php + +/** +* ownCloud +* +* @author Robin Appelman +* @copyright 2010 Robin Appelman icewind1991@gmailc.om +* +* 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/>. +* +*/ + + +/** + * base class for unit tests + */ +class OC_TestCase{ + private $tests; //array of all tests in this test case + + public function __construct(){ + $this->tests=array(); + $this->results=array(); + $functions=get_class_methods(get_class($this)); + $exclude=get_class_methods('OC_TestCase'); + foreach($functions as $function){ + if(array_search($function,$exclude)===false){ + $this->tests[]=$function; + } + } + } + + public function getTests(){ + return $this->tests; + } + + /** + * function that gets called before each test + */ + private function setup(){ + } + + /** + * function that gets called after each test + */ + private function tearDown(){ + } + + /** + * check if the result equals the expected result + * @param mixed $expected the expected result + * @param mixed $result the actual result + * @param string $error (optional) the error message to display if the result isn't expected + */ + protected function assertEquals($expected,$result,$error=''){ + if($expected!==$result){ + if($expected===true){ + $expected='true'; + } + if($expected===false){ + $expected='false'; + } + if($result===true){ + $result='true'; + } + if($result===false){ + $result='false'; + } + if($error==''){ + $error="Unexpected result, expected '$expected' but was '$result'"; + } + throw new Exception($error); + } + } + + /** + * fail the test + * @param string $error the error message + */ + protected function fail($error){ + throw new Exception($error); + } +}
\ No newline at end of file diff --git a/lib/user.php b/lib/user.php index 09501e59c58..25f555b47b1 100644 --- a/lib/user.php +++ b/lib/user.php @@ -40,7 +40,7 @@ if( !OC_CONFIG::getValue( "installed", false )){ */ class OC_USER { // The backend used for user management - private static $_backend = null; + private static $_usedBackends = array(); // Backends available (except database) private static $_backends = array(); @@ -68,13 +68,23 @@ class OC_USER { } /** - * @brief Sets the backend + * @brief gets used backends + * @returns array of backends + * + * Returns the names of all used backends. + */ + public static function getUsedBackends(){ + return array_keys(self::$_usedBackends); + } + + /** + * @brief Adds the backend to the list of used backends * @param $backend default: database The backend to use for user managment * @returns true/false * * Set the User Authentication Module */ - public static function setBackend( $backend = 'database' ){ + public static function useBackend( $backend = 'database' ){ // You'll never know what happens if( null === $backend OR !is_string( $backend )){ $backend = 'database'; @@ -86,11 +96,11 @@ class OC_USER { case 'mysql': case 'sqlite': require_once('User/database.php'); - self::$_backend = new OC_USER_DATABASE(); + self::$_usedBackends[$backend] = new OC_USER_DATABASE(); break; default: $className = 'OC_USER_' . strToUpper($backend); - self::$_backend = new $className(); + self::$_usedBackends[$backend] = new $className(); break; } @@ -119,7 +129,7 @@ class OC_USER { return false; } // Check if user already exists - if( in_array( $uid, self::getUsers())){ + if( self::userExists($uid) ){ return false; } @@ -127,13 +137,19 @@ class OC_USER { $run = true; OC_HOOK::emit( "OC_USER", "pre_createUser", array( "run" => &$run, "uid" => $uid, "password" => $password )); - if( $run && self::$_backend->createUser( $uid, $password )){ - OC_HOOK::emit( "OC_USER", "post_createUser", array( "uid" => $uid, "password" => $password )); - return true; - } - else{ - return false; + if( $run ){ + //create the user in the first backend that supports creating users + foreach(self::$_usedBackends as $backend){ + if(!$backend->implementsActions(OC_USER_BACKEND_CREATE_USER)) + continue; + + $backend->createUser($uid,$password); + OC_HOOK::emit( "OC_USER", "post_createUser", array( "uid" => $uid, "password" => $password )); + + return true; + } } + return false; } /** @@ -147,7 +163,13 @@ class OC_USER { $run = true; OC_HOOK::emit( "OC_USER", "pre_deleteUser", array( "run" => &$run, "uid" => $uid )); - if( $run && self::$_backend->deleteUser( $uid )){ + if( $run ){ + //delete the user from all backends + foreach(self::$_usedBackends as $backend){ + if($backend->implementsActions(OC_USER_BACKEND_DELETE_USER)){ + $backend->deleteUser($uid); + } + } // We have to delete the user from all groups foreach( OC_GROUP::getUserGroups( $uid ) as $i ){ OC_GROUP::removeFromGroup( $uid, $i ); @@ -174,7 +196,9 @@ class OC_USER { $run = true; OC_HOOK::emit( "OC_USER", "pre_login", array( "run" => &$run, "uid" => $uid )); - if( $run && self::$_backend->login( $uid, $password )){ + if( $run && self::checkPassword( $uid, $password )){ + $_SESSION['user_id'] = $uid; + OC_LOG::add( "core", $_SESSION['user_id'], "login" ); OC_HOOK::emit( "OC_USER", "post_login", array( "uid" => $uid )); return true; } @@ -191,7 +215,9 @@ class OC_USER { */ public static function logout(){ OC_HOOK::emit( "OC_USER", "logout", array()); - return self::$_backend->logout(); + OC_LOG::add( "core", $_SESSION['user_id'], "logout" ); + $_SESSION['user_id'] = false; + return true; } /** @@ -201,7 +227,25 @@ class OC_USER { * Checks if the user is logged in */ public static function isLoggedIn(){ - return self::$_backend->isLoggedIn(); + if( isset($_SESSION['user_id']) AND $_SESSION['user_id'] ){ + return true; + } + else{ + return false; + } + } + + /** + * @brief get the user idea of the user currently logged in. + * @return string uid or false + */ + public static function getUser(){ + if( isset($_SESSION['user_id']) AND $_SESSION['user_id'] ){ + return $_SESSION['user_id']; + } + else{ + return false; + } } /** @@ -211,7 +255,7 @@ class OC_USER { * generates a password */ public static function generatePassword(){ - return substr( md5( uniqId().time()), 0, 10 ); + return uniqId(); } /** @@ -226,7 +270,14 @@ class OC_USER { $run = true; OC_HOOK::emit( "OC_USER", "pre_setPassword", array( "run" => &$run, "uid" => $uid, "password" => $password )); - if( $run && self::$_backend->setPassword( $uid, $password )){ + if( $run ){ + foreach(self::$_usedBackends as $backend){ + if($backend->implementsActions(OC_USER_BACKEND_SET_PASSWORD)){ + if($backend->userExists($uid)){ + $backend->setPassword($uid,$password); + } + } + } OC_HOOK::emit( "OC_USER", "post_setPassword", array( "uid" => $uid, "password" => $password )); return true; } @@ -244,7 +295,14 @@ class OC_USER { * Check if the password is correct without logging in the user */ public static function checkPassword( $uid, $password ){ - return self::$_backend->checkPassword( $uid, $password ); + foreach(self::$_usedBackends as $backend){ + if($backend->implementsActions(OC_USER_BACKEND_CHECK_PASSWORD)){ + $result=$backend->checkPassword( $uid, $password ); + if($result===true){ + return true; + } + } + } } /** @@ -254,6 +312,29 @@ class OC_USER { * Get a list of all users. */ public static function getUsers(){ - return self::$_backend->getUsers(); + $users=array(); + foreach(self::$_usedBackends as $backend){ + if($backend->implementsActions(OC_USER_BACKEND_GET_USERS)){ + $users=array_merge($users,$backend->getUsers()); + } + } + return $users; + } + + /** + * @brief check if a user exists + * @param string $uid the username + * @return boolean + */ + public static function userExists($uid){ + foreach(self::$_usedBackends as $backend){ + if($backend->implementsActions(OC_USER_BACKEND_USER_EXISTS)){ + $result=$backend->userExists($uid); + if($result===true){ + return true; + } + } + } + return false; } } diff --git a/log/index.php b/log/index.php index 675396a4d10..4986526e007 100644 --- a/log/index.php +++ b/log/index.php @@ -21,15 +21,13 @@ * */ - //require_once('../../config/config.php'); require_once('../lib/base.php'); -require( 'template.php' ); -require( 'preferences.php' ); +require_once( 'template.php' ); if( !OC_USER::isLoggedIn()){ - header( 'Location: '.OC_HELPER::linkTo( 'index.php' )); - exit(); + header( 'Location: '.OC_HELPER::linkTo( 'index.php' )); + exit(); } //load the script @@ -37,25 +35,37 @@ OC_UTIL::addScript( "log", "log" ); $allActions=array('login','logout','read','write','create','delete'); -//check for a submited config -if(isset($_POST['size'])){ +//check for a submitted config +if(isset($_POST['save'])){ $selectedActions=array(); foreach($allActions as $action){ if(isset($_POST[$action]) and $_POST[$action]=='on'){ $selectedActions[]=$action; } } - OC_PREFERENCES::setValue($_SESSION['user_id'],'log','actions',implode(',',$selectedActions)); - OC_PREFERENCES::setValue($_SESSION['user_id'],'log','pagesize',$_POST['size']); + OC_PREFERENCES::setValue(OC_USER::getUser(),'log','actions',implode(',',$selectedActions)); + OC_PREFERENCES::setValue(OC_USER::getUser(),'log','pagesize',$_POST['size']); +} +//clear log entries +elseif(isset($_POST['clear'])){ + $removeBeforeDate=(isset($_POST['removeBeforeDate']))?$_POST['removeBeforeDate']:0; + if($removeBeforeDate!==0){ + $removeBeforeDate=strtotime($removeBeforeDate); + OC_LOG::deleteBefore($removeBeforeDate); + } +} +elseif(isset($_POST['clearall'])){ + OC_LOG::deleteAll(); } OC_APP::setActiveNavigationEntry( 'log' ); $logs=OC_LOG::get(); -$selectedActions=explode(',',OC_PREFERENCES::getValue($_SESSION['user_id'],'log','actions',implode(',',$allActions))); + +$selectedActions=explode(',',OC_PREFERENCES::getValue(OC_USER::getUser(),'log','actions',implode(',',$allActions))); $logs=OC_LOG::filterAction($logs,$selectedActions); -$pageSize=OC_PREFERENCES::getValue($_SESSION['user_id'],'log','pagesize',20); +$pageSize=OC_PREFERENCES::getValue(OC_USER::getUser(),'log','pagesize',20); $pageCount=ceil(count($logs)/$pageSize); $page=isset($_GET['page'])?$_GET['page']:0; if($page>=$pageCount){ @@ -72,7 +82,8 @@ $url=OC_HELPER::linkTo( 'log', 'index.php' ).'?page='; $pager=OC_UTIL::getPageNavi($pageCount,$page,$url); if($pager){ $pagerHTML=$pager->fetchPage(); -}else{ +} +else{ $pagerHTML=''; } @@ -80,7 +91,8 @@ $showActions=array(); foreach($allActions as $action){ if(array_search($action,$selectedActions)!==false){ $showActions[$action]='checked="checked"'; - }else{ + } + else{ $showActions[$action]=''; } } diff --git a/log/js/log.js b/log/js/log.js index 47c20b3e860..42ae1b4c852 100644 --- a/log/js/log.js +++ b/log/js/log.js @@ -18,4 +18,8 @@ $(document).ready(function() { } } }); -});
\ No newline at end of file + $('#removeBeforeDate').datepicker({ + dateFormat:'MM d, yy', + }); +}); + diff --git a/log/l10n/da.php b/log/l10n/da.php new file mode 100644 index 00000000000..8fbfae67a6d --- /dev/null +++ b/log/l10n/da.php @@ -0,0 +1,14 @@ +<?php $TRANSLATIONS = array( +"Filter:" => "Filter:", +"Logins" => "Logins", +"Logouts" => "Logouts", +"Downloads" => "Downloads", +"Uploads" => "Uploads", +"Creations" => "Oprettelser", +"Deletions" => "Sletninger", +"Show:" => "Vis:", +"entries per page." => "poster pr side.", +"What" => "Hvilket", +"When" => "Hvornår", +"Clear log entries before" => "Slet log poster før" +); diff --git a/log/l10n/de.php b/log/l10n/de.php new file mode 100644 index 00000000000..9cf804d6cf8 --- /dev/null +++ b/log/l10n/de.php @@ -0,0 +1,14 @@ +<?php $TRANSLATIONS = array( +"Filter:" => "Filter:", +"Logins" => "Anmeldungen", +"Logouts" => "Abmeldungen", +"Downloads" => "Downloads", +"Uploads" => "Uploads", +"Creations" => "Erstellungen", +"Deletions" => "Löschungen", +"Show:" => "Zeige", +"entries per page." => "Einträge pro Seite", +"What" => "Was", +"When" => "Wann", +"Clear log entries before" => "Lösche Einträge vor dem" +); diff --git a/log/l10n/nl.php b/log/l10n/nl.php new file mode 100644 index 00000000000..f381619b5fd --- /dev/null +++ b/log/l10n/nl.php @@ -0,0 +1,14 @@ +<?php $TRANSLATIONS = array( +"Filter:" => "Filter:", +"Logins" => "Aanmeldingen", +"Logouts" => "Afmeldingen", +"Downloads" => "Downloads", +"Uploads" => "Uploads", +"Creations" => "Creaties", +"Deletions" => "Verwijderingen", +"Show:" => "Laat", +"entries per page." => "resulaten per pagina zien", +"What" => "Wat", +"When" => "Wanneer", +"Clear log entries before" => "Verwijder logboekitem ouder dan" +); diff --git a/log/l10n/pl.php b/log/l10n/pl.php new file mode 100644 index 00000000000..322e5df1add --- /dev/null +++ b/log/l10n/pl.php @@ -0,0 +1,14 @@ +<?php $TRANSLATIONS = array( +"Filter:" => "Filtr:", +"Logins" => "Zalogowania", +"Logouts" => "Wylogowani", +"Downloads" => "Pobrania", +"Uploads" => "Wgrania", +"Creations" => "Utworzenia", +"Deletions" => "Usunięcia", +"Show:" => "Pokaż:", +"entries per page." => "wpisów na stronę.", +"What" => "Co", +"When" => "Kiedy", +"Clear log entries before" => "Wyczyść spisy dziennika sprzed" +); diff --git a/log/l10n/xgettextfiles b/log/l10n/xgettextfiles new file mode 100644 index 00000000000..a24bcc89a85 --- /dev/null +++ b/log/l10n/xgettextfiles @@ -0,0 +1 @@ +../templates/index.php diff --git a/log/templates/index.php b/log/templates/index.php index 1e294091e3f..2756332f519 100644 --- a/log/templates/index.php +++ b/log/templates/index.php @@ -1,20 +1,20 @@ <div class="controls"> <form id="logs_options" method='post'> <p> - <span>Filter :</span> + <span><?php echo $l->t( 'Filter:' ); ?></span> <input type="checkbox" checked="" name="all" id="all" /> <label for="all">All</label> - <input type="checkbox" class='action' <?php echo $_['showActions']['login']?> name="login" id="logins" /> <label for="logins">Logins</label> - <input type="checkbox" class='action' <?php echo $_['showActions']['logout']?> name="logout" id="logouts" /> <label for="logouts">Logouts</label> - <input type="checkbox" class='action' <?php echo $_['showActions']['read']?> name="read" id="downloads" /> <label for="downloads">Downloads</label> - <input type="checkbox" class='action' <?php echo $_['showActions']['write']?> name="write" id="uploads" /> <label for="uploads">Uploads</label> - <input type="checkbox" class='action' <?php echo $_['showActions']['create']?> name="create" id="creations" /> <label for="creations">Creations</label> - <input type="checkbox" class='action' <?php echo $_['showActions']['delete']?> name="delete" id="deletions" /> <label for="deletions">Deletions</label> + <input type="checkbox" class='action' <?php echo $_['showActions']['login']?> name="login" id="logins" /> <label for="logins"><?php echo $l->t( 'Logins' ); ?></label> + <input type="checkbox" class='action' <?php echo $_['showActions']['logout']?> name="logout" id="logouts" /> <label for="logouts"><?php echo $l->t( 'Logouts' ); ?></label> + <input type="checkbox" class='action' <?php echo $_['showActions']['read']?> name="read" id="downloads" /> <label for="downloads"><?php echo $l->t( 'Downloads' ); ?></label> + <input type="checkbox" class='action' <?php echo $_['showActions']['write']?> name="write" id="uploads" /> <label for="uploads"><?php echo $l->t( 'Uploads' ); ?></label> + <input type="checkbox" class='action' <?php echo $_['showActions']['create']?> name="create" id="creations" /> <label for="creations"><?php echo $l->t( 'Creations' ); ?></label> + <input type="checkbox" class='action' <?php echo $_['showActions']['delete']?> name="delete" id="deletions" /> <label for="deletions"><?php echo $l->t( 'Deletions' ); ?></label> </p> <p> - <span>Show :</span> - <input type="text" maxlength="3" size="3" value="<?php echo $_['size']?>" name='size'/> entries per page. - <input class="prettybutton" type="submit" value="Save" /> + <span><?php echo $l->t( 'Show:' ); ?></span> + <input type="text" maxlength="3" size="3" value="<?php echo $_['size']?>" name='size'/> <?php echo $l->t( 'entries per page.' ); ?> + <input class="prettybutton" type="submit" name="save" value="Save" /> </p> </form> @@ -23,18 +23,32 @@ <table cellspacing="0"> <thead> <tr> - <th>What</th> - <th>When</th> + <th><?php echo $l->t( 'What' ); ?></th> + <th><?php echo $l->t( 'When' ); ?></th> </tr> </thead> <tbody> <?php foreach($_["logs"] as $entry): ?> <tr> <td class="<?php echo $entry["action"]; ?>"><em><?php echo $entry["action"]; ?> <?php echo $entry["user"]; ?></em> <?php echo $entry["info"]; ?></td> - <td class="date"><?php echo $entry["date"]; ?></td> + <td class="date"><?php echo $l->l('datetime', $entry["date"] ); ?></td> </tr> <?php endforeach; ?> </tbody> </table> <?php echo $_['pager'];?> + +<div class="controls"> + <form id="logs_options" method='post'> + <p> + <span><?php echo $l->t( 'Clear log entries before' ); ?> </span> + <input type="date" id="removeBeforeDate" name="removeBeforeDate"/> + <input class="prettybutton nofloat" type="submit" name="clear" value="Clear" /> + <input class="prettybutton" type="submit" name="clearall" value="Clear All" /> + + </p> + </form> +</div> + + diff --git a/search/index.php b/search/index.php index e6f41528ea3..b348b22387f 100644 --- a/search/index.php +++ b/search/index.php @@ -38,6 +38,9 @@ OC_UTIL::addStyle( 'search', 'search' ); $query=(isset($_POST['query']))?$_POST['query']:''; if($query){ $results=OC_SEARCH::search($query); +}else{ + header("Location: ".$WEBROOT.'/'.OC_APPCONFIG::getValue("core", "defaultpage", "files/index.php")); + exit(); } $resultTypes=array(); diff --git a/settings/ajax/changepassword.php b/settings/ajax/changepassword.php index 1a9ad73610e..f568d3ef876 100644 --- a/settings/ajax/changepassword.php +++ b/settings/ajax/changepassword.php @@ -3,33 +3,35 @@ // Init owncloud require_once('../../lib/base.php'); +$l=new OC_L10N('settings'); + // We send json data header( "Content-Type: application/jsonrequest" ); // Check if we are a user if( !OC_USER::isLoggedIn()){ - echo json_encode( array( "status" => "error", "data" => array( "message" => "Authentication error" ))); + echo json_encode( array( "status" => "error", "data" => array( "message" => $l->t( "Authentication error" ) ))); exit(); } // Get data if( !isset( $_POST["password"] ) && !isset( $_POST["oldpassword"] )){ - echo json_encode( array( "status" => "error", "data" => array( "message" => "You have to enter the old and the new password!" ))); + echo json_encode( array( "status" => "error", "data" => array( "message" => $l->t( "You have to enter the old and the new password!" ) ))); exit(); } // Check if the old password is correct if( !OC_USER::checkPassword( $_SESSION["user_id"], $_POST["oldpassword"] )){ - echo json_encode( array( "status" => "error", "data" => array( "message" => "Your old password is wrong!" ))); + echo json_encode( array( "status" => "error", "data" => array( "message" => $l->t("Your old password is wrong!") ))); exit(); } // Change password if( OC_USER::setPassword( $_SESSION["user_id"], $_POST["password"] )){ - echo json_encode( array( "status" => "success", "data" => array( "message" => "Password changed" ))); + echo json_encode( array( "status" => "success", "data" => array( "message" => $l->t("Password changed") ))); } else{ - echo json_encode( array( "status" => "error", "data" => array( "message" => "Unable to change password" ))); + echo json_encode( array( "status" => "error", "data" => array( "message" => $l->t("Unable to change password") ))); } ?> diff --git a/settings/ajax/setlanguage.php b/settings/ajax/setlanguage.php new file mode 100644 index 00000000000..bc467fb9004 --- /dev/null +++ b/settings/ajax/setlanguage.php @@ -0,0 +1,26 @@ +<?php + +// Init owncloud +require_once('../../lib/base.php'); + +$l=new OC_L10N('settings'); + +// We send json data +header( "Content-Type: application/jsonrequest" ); + +// Check if we are a user +if( !OC_USER::isLoggedIn()){ + echo json_encode( array( "status" => "error", "data" => array( "message" => $l->t("Authentication error") ))); + exit(); +} + +// Get data +if( isset( $_POST['lang'] ) ){ + $lang=$_POST['lang']; + OC_PREFERENCES::setValue( OC_USER::getUser(), 'core', 'lang', $lang ); + echo json_encode( array( "status" => "success", "data" => array( "message" => $l->t("Language changed") ))); +}else{ + echo json_encode( array( "status" => "error", "data" => array( "message" => $l->t("Invalid request") ))); +} + +?> diff --git a/settings/index.php b/settings/index.php index 1a442eca811..07adba142d6 100644 --- a/settings/index.php +++ b/settings/index.php @@ -18,11 +18,18 @@ $free=OC_FILESYSTEM::free_space(); $total=$free+$used; $relative=round(($used/$total)*100); +$lang=OC_PREFERENCES::getValue( OC_USER::getUser(), 'core', 'lang', 'en' ); +$languages=OC_L10N::findAvailableLanguages(); +//put the current language in the front +unset($languages[array_search($lang,$languages)]); +array_unshift($languages,$lang); + // Return template $tmpl = new OC_TEMPLATE( "settings", "index", "admin"); $tmpl->assign('usage',OC_HELPER::humanFileSize($used)); $tmpl->assign('total_space',OC_HELPER::humanFileSize($total)); $tmpl->assign('usage_relative',$relative); +$tmpl->assign('languages',$languages); $tmpl->printPage(); ?> diff --git a/settings/js/main.js b/settings/js/main.js index e05fc68743c..010225bcb27 100644 --- a/settings/js/main.js +++ b/settings/js/main.js @@ -18,4 +18,18 @@ $(document).ready(function(){ }); return false; }); + + $("#languageinput").change( function(){ + // Serialize the data + var post = $( "#languageinput" ).serialize(); + // Ajax foo + $.post( 'ajax/setlanguage.php', post, function(data){ + if( data.status == "success" ){ + } + else{ + $('#passworderror').html( data.data.message ); + } + }); + return false; + }); } ); diff --git a/settings/l10n/da.php b/settings/l10n/da.php new file mode 100644 index 00000000000..37a56f2f64c --- /dev/null +++ b/settings/l10n/da.php @@ -0,0 +1,19 @@ +<?php $TRANSLATIONS = array( +"Account information" => "Konto information", +"You're currently using" => "Du udnytter i øjeblikket", +"of your" => "af din", +"space" => "plads", +"Change Password" => "Ændre adgangskode", +"Your password got changed" => "Din adgangskode er ændret", +"Old password:" => "Gamle adgangskode", +"New password" => "Nye adgangskode", +"Show new password" => "Vis den nye adgangskode", +"Language" => "Sprog", +"Authentication error" => "Godkendelsesfejl", +"You have to enter the old and the new password!" => "Du skal indtaste din gamle og nye adganskode", +"Your old password is wrong!" => "Din gamle adgangskode er forkert!", +"Password changed" => "Adgangskoden er ændret", +"Unable to change password" => "Kan ikke ændre din adgangskode", +"Language changed" => "Sprog ændret", +"Invalid request" => "Invalid forespørgsel" +); diff --git a/settings/l10n/de.php b/settings/l10n/de.php new file mode 100644 index 00000000000..e3be20de33e --- /dev/null +++ b/settings/l10n/de.php @@ -0,0 +1,19 @@ +<?php $TRANSLATIONS = array( +"Account information" => "Konto-Information", +"You're currently using" => "Du benutzt gerade", +"of your" => "von deinem", +"space" => "Speicherplatz", +"Change Password" => "Passwort ändern", +"Your password got changed" => "Dein Passwort wurde geändert.", +"Old password:" => "Aktuelles Passwort:", +"New password" => "Neues Passwort:", +"Show new password" => "Neues Passwort anzeigen", +"Language" => "Sprache", +"Authentication error" => "Berechtigungsfehler", +"You have to enter the old and the new password!" => "Du musst das aktuelle und ein neues Passwort angeben!", +"Your old password is wrong!" => "Du hast dein aktuelles Passwort falsch eingegeben!", +"Password changed" => "Passwort geändert", +"Unable to change password" => "Passwort konnte nicht geändert werden", +"Language changed" => "Sprache geändert", +"Invalid request" => "Ungültige Anfrage" +); diff --git a/settings/l10n/nl.php b/settings/l10n/nl.php new file mode 100644 index 00000000000..3c2f3dbd271 --- /dev/null +++ b/settings/l10n/nl.php @@ -0,0 +1,19 @@ +<?php $TRANSLATIONS = array( +"Account information" => "Gebruikersgegevens", +"You're currently using" => "U gebruikt momenteel", +"of your" => "van de", +"space" => "beschikbare ruimte.", +"Change Password" => "Wachtwoord aanpassen", +"Your password got changed" => "Uw wachtwoord is aangepast", +"Old password:" => "Oud wachtwoord:", +"New password" => "Nieuw wachtwoord", +"Show new password" => "Toon nieuw wachtwoord", +"Language" => "Taal", +"Authentication error" => "Authenticatiefout.", +"You have to enter the old and the new password!" => "U moet het oude en nieuwe wachtwoord invullen.", +"Your old password is wrong!" => "Het oude wachtwoord is verkeerd.", +"Password changed" => "Wachtwoord aangepast", +"Unable to change password" => "Wachtwoord aanpassen is niet mogelijk", +"Language changed" => "Taal aangepast", +"Invalid request" => "Ongeldig verzoek" +); diff --git a/settings/l10n/pl.php b/settings/l10n/pl.php new file mode 100644 index 00000000000..b65fdd15b4d --- /dev/null +++ b/settings/l10n/pl.php @@ -0,0 +1,19 @@ +<?php $TRANSLATIONS = array( +"Account information" => "Dane konta", +"You're currently using" => "Obecnie używasz", +"of your" => "ze swoich", +"space" => "przestrzeni", +"Change Password" => "Zmień hasło", +"Your password got changed" => "Twoje hasło zostało zmienione", +"Old password:" => "Stare hasło", +"New password" => "Nowe hasło", +"Show new password" => "Pokaż nowe hasło", +"Language" => "Język", +"Authentication error" => "Błąd uwierzytelniania", +"You have to enter the old and the new password!" => "Musisz wprowadzić zarówno stare, jak i nowe hasło!", +"Your old password is wrong!" => "Twoje stare hasło jest błędne!", +"Password changed" => "Hasło zmienione", +"Unable to change password" => "NIe można zmienić hasła", +"Language changed" => "Język zmieniony", +"Invalid request" => "Nieprawidłowe żądanie" +); diff --git a/settings/l10n/xgettextfiles b/settings/l10n/xgettextfiles new file mode 100644 index 00000000000..8a2f185f230 --- /dev/null +++ b/settings/l10n/xgettextfiles @@ -0,0 +1,3 @@ +../templates/index.php +../ajax/changepassword.php +../ajax/setlanguage.php
\ No newline at end of file diff --git a/settings/templates/index.php b/settings/templates/index.php index 2d5e9d9140f..761289acefa 100644 --- a/settings/templates/index.php +++ b/settings/templates/index.php @@ -1,30 +1,42 @@ <form id="quota"> <fieldset> - <legend>Account information</legend> + <legend><?php echo $l->t( 'Account information' );?></legend> <div id="quota_indicator"><div style="width:<?php echo $_['usage_relative'] ?>%;"> </div></div> - <p>You're currently using <?php echo $_['usage_relative'] ?>% (<?php echo $_['usage'] ?>) of your <?php echo $_['total_space'] ?> space.</p> + <p><?php echo $l->t( 'You\'re currently using' );?> <?php echo $_['usage_relative'] ?>% (<?php echo $_['usage'] ?>) <?php echo $l->t( 'of your' );?> <?php echo $_['total_space'] ?> <?php echo $l->t( 'space' );?>.</p> </fieldset> </form> <form id="passwordform"> <fieldset> - <legend>Change Password</legend> - <div id="passwordchanged">You're password got changed</div> - <div id="passworderror"></div> - <p> - <label for="pass1">Old password:</label> - <input type="password" id="pass1" name="oldpassword" /> - </p> - <p> - <label for="pass2">New password :</label> - <input type="password" id="pass2" name="password" /> - </p> - <p> - <input type="checkbox" id="show" name="show" /> - <label for="show">Show new password</label> - </p> - <p class="form_footer"> - <input id="passwordbutton" class="prettybutton" type="submit" value="Save" /> - </p> + <legend><?php echo $l->t( 'Change Password' );?></legend> + <div id="passwordchanged"><?php echo $l->t( 'Your password got changed');?></div> + <div id="passworderror"></div> + <p> + <label for="pass1"><?php echo $l->t( 'Old password:' );?></label> + <input type="password" id="pass1" name="oldpassword" /> + </p> + <p> + <label for="pass2"><?php echo $l->t( 'New password' );?></label> + <input type="password" id="pass2" name="password" /> + </p> + <p> + <input type="checkbox" id="show" name="show" /> + <label for="show"><?php echo $l->t( 'Show new password' );?></label> + </p> + <p class="form_footer"> + <input id="passwordbutton" class="prettybutton" type="submit" value="Save" /> + </p> + </fieldset> +</form> + +<form id="languageform"> + <fieldset> + <legend><?php echo $l->t( 'Language' );?></legend> + <label for=''></label> + <select id="languageinput" name='lang'> + <?php foreach($_['languages'] as $language):?> + <option value='<?php echo $language;?>'><?php echo $language;?></option> + <?php endforeach;?> + </select> </fieldset> </form> diff --git a/templates/installation.php b/templates/installation.php deleted file mode 100644 index 880beb9a89e..00000000000 --- a/templates/installation.php +++ /dev/null @@ -1,70 +0,0 @@ -<div id="login"> - <img src="<?php echo image_path('', 'owncloud-logo-medium-white.png'); ?>" alt="ownCloud" /> - <form action="index.php" method="post" id="setup_form"> - <input type="hidden" name="install" value="true" /> - <p class="intro"> - Welcome to <strong>ownCloud</strong>, your personnal cloud.<br /> - To finish the installation, please follow the steps below. - </p> - - <?php if(count($_['errors']) > 0): ?> - <ul class="errors"> - <?php foreach($_['errors'] as $err): ?> - <li> - <?php if(is_array($err)):?> - <?php print $err['error']; ?> - <p class='hint'><?php print $err['hint']; ?></p> - <?php else: ?> - <?php print $err; ?> - <?php endif; ?> - </li> - <?php endforeach; ?> - </ul> - <?php endif; ?> - - <fieldset> - <legend>Create an <strong>admin account.</strong></legend> - <p><label for="adminlogin">Login :</label><input type="text" name="adminlogin" id="adminlogin" value="<?php print OC_HELPER::init_var('adminlogin'); ?>" /></p> - <p><label for="adminpass">Password :</label><input type="password" name="adminpass" id="adminpass" value="<?php print OC_HELPER::init_var('adminpass'); ?>" /></p> - </fieldset> - - <a id='showAdvanced'>Advanced <img src='<?php echo OC_HELPER::imagePath('','drop-arrow.png'); ?>'></img></a> - - <fieldset id='datadirField'> - <legend>Set where to store the data.</legend> - <p><label for="directory">Data directory :</label><input type="text" name="directory" id="directory" value="<?php print OC_HELPER::init_var('directory', $_['directory']); ?>" /></p> - </fieldset> - - <fieldset id='databaseField'> - <legend>Configure your database.</legend> - <?php if($_['hasSQLite']): ?> - <input type='hidden' id='hasSQLite' value='true'/> - <?php if(!$_['hasMySQL']): ?> - <p>I will use a SQLite database. You have nothing to do !</p> - <input type="hidden" id="dbtype" name="dbtype" value="sqlite" /> - <?php else: ?> - <p><label class="sqlite" for="sqlite">SQLite </label><input type="radio" name="dbtype" value='sqlite' id="sqlite" <?php OC_HELPER::init_radio('dbtype', 'sqlite', 'sqlite'); ?>/></p> - <?php endif; ?> - <?php endif; ?> - - <?php if($_['hasMySQL']): ?> - <input type='hidden' id='hasMySQL' value='true'/> - <?php if(!$_['hasSQLite']): ?> - <p>I will use a MySQL database.</p> - <input type="hidden" id="dbtype" name="dbtype" value="mysql" /> - <?php else: ?> - <p><label class="mysql" for="mysql">MySQL </label><input type="radio" name="dbtype" value='mysql' id="mysql" <?php OC_HELPER::init_radio('dbtype', 'mysql', 'sqlite'); ?>/></p> - <?php endif; ?> - <div id="use_mysql"> - <p><label for="dbhost">Host :</label><input type="text" name="dbhost" id="dbhost" value="<?php print OC_HELPER::init_var('dbhost', 'localhost'); ?>" /></p> - <p><label for="dbname">Database name :</label><input type="text" name="dbname" id="dbname" value="<?php print OC_HELPER::init_var('dbname'); ?>" /></p> - <p><label for="dbtableprefix">Table prefix :</label><input type="text" name="dbtableprefix" id="dbtableprefix" value="<?php print OC_HELPER::init_var('dbtableprefix', 'oc_'); ?>" /></p> - <p><label for="dbuser">MySQL user login :</label><input type="text" name="dbuser" id="dbuser" value="<?php print OC_HELPER::init_var('dbuser'); ?>" /></p> - <p><label for="dbpass">MySQL user password :</label><input type="password" name="dbpass" id="dbpass" value="<?php print OC_HELPER::init_var('dbpass'); ?>" /></p> - </div> - <?php endif; ?> - </fieldset> - - <p class="submit"><input type="submit" value="Finish setup" /></p> - </form> -</div> diff --git a/templates/logout.php b/templates/logout.php deleted file mode 100644 index 4a15998a5c0..00000000000 --- a/templates/logout.php +++ /dev/null @@ -1 +0,0 @@ -You are logged out. diff --git a/tests/index.php b/tests/index.php new file mode 100644 index 00000000000..30ebde11235 --- /dev/null +++ b/tests/index.php @@ -0,0 +1,79 @@ +<?php +/** +* ownCloud +* +* @author Robin Appelman +* @copyright 2010 Robin Appelman icewind1991@gmailc.om +* +* 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/>. +* +*/ + + +/** + * run all test cases + */ + $RUNTIME_NOSETUPFS=true; +require_once('../lib/base.php'); +require_once('testcase.php'); +require_once('template.php'); + +$testCases=loadFiles(__DIR__,array('index.php','templates')); +ob_end_clean(); +$testResults=array(); +foreach($testCases as $testCaseClass){ + $testCase=new $testCaseClass(); + $results=array(); + foreach($testCase->getTests() as $test){ + $testCase->setup(); + try{ + $testCase->$test(); + $results[$test]='Ok'; + }catch(Exception $e){ + $results[$test]=$e->getMessage(); + } + $testCase->tearDown(); + } + $testResults[$testCaseClass]=$results; +} + +$tmpl = new OC_TEMPLATE( 'tests', 'index'); +$tmpl->assign('tests',$testResults); +$tmpl->printPage(); + +/** + * recursively load all files in a folder + * @param string $path + * @param array $exclude list of files to exclude + */ +function loadFiles($path,$exclude=false){ + $results=array(); + if(!$exclude){ + $exclude=array(); + } + $dh=opendir($path); + while($file=readdir($dh)){ + if($file!='.' && $file!='..' && array_search($file,$exclude)===false){ + if(is_file($path.'/'.$file) and substr($file,-3)=='php'){ + $result=require_once($path.'/'.$file); + $results[]=$result; + }elseif(is_dir($path.'/'.$file)){ + $subResults=loadFiles($path.'/'.$file); + $results=array_merge($results,$subResults); + } + } + } + return $results; +} +?>
\ No newline at end of file diff --git a/tests/lib/filesystem.php b/tests/lib/filesystem.php new file mode 100644 index 00000000000..1b1703a06d7 --- /dev/null +++ b/tests/lib/filesystem.php @@ -0,0 +1,222 @@ +<?php +class OC_FILEYSYSTEM_Test extends OC_TestCase +{ + public function setup(){ + OC_UTIL::setupFS('testuser','testcase'); + } + public function tearDown(){ + OC_FILESYSTEM::chroot(''); + OC_FILESYSTEM::delTree('/testuser'); + OC_UTIL::tearDownFS(); + } + + public function isDir(){ + $this->assertEquals(true, OC_FILESYSTEM::is_dir('/'),'Root is not a directory'); + } + + public function fileExists(){ + $this->assertEquals(false, OC_FILESYSTEM::file_exists('/dummy'),'Unexpected result with non-existing file'); + OC_FILESYSTEM::file_put_contents('/dummy','foo'); + $this->assertEquals(true, OC_FILESYSTEM::file_exists('/dummy'),'Unexpected result with existing file'); + } + + public function mkdir(){ + OC_FILESYSTEM::mkdir('/dummy'); + $this->assertEquals(true, OC_FILESYSTEM::file_exists('/dummy'),'No such file or directory after creating folder'); + $this->assertEquals(true, OC_FILESYSTEM::is_dir('/dummy'),'File created instead of filder'); + } + + public function rmdir(){ + OC_FILESYSTEM::mkdir('/dummy'); + OC_FILESYSTEM::rmdir('/dummy'); + $this->assertEquals(false, OC_FILESYSTEM::file_exists('/dummy'),'Folder still exists after removing'); + } + + public function isFile(){ + $this->assertEquals(false, OC_FILESYSTEM::is_file('/'),'Root is a file'); + OC_FILESYSTEM::file_put_contents('/dummy','foo'); + $this->assertEquals(true, OC_FILESYSTEM::is_file('/dummy'),'Created file is not said to be a file'); + } + + public function opendir(){ + OC_FILESYSTEM::file_put_contents('/dummy1','foo'); + OC_FILESYSTEM::file_put_contents('/dummy2','foo'); + $dh=OC_FILESYSTEM::opendir('/'); + if(!$dh){ + $this->fail('Failed to open root'); + } + $dummy1Found=false; + $dummy2Found=false; + while($file=readdir($dh)){ + if($file=='dummy1'){ + $dummy1Found=true; + }elseif($file=='dummy2'){ + $dummy2Found=true; + }elseif($file!='.' and $file!='..'){ + $this->fail('Unexpected filename when reading opened dir'); + } + } + $this->assertEquals(true,$dummy1Found,'Not all files found when reading opened dir'); + $this->assertEquals(true,$dummy2Found,'Not all files found when reading opened dir'); + } + + public function filesize(){ + OC_FILESYSTEM::file_put_contents('/dummy','1234567890'); + $this->assertEquals(10, OC_FILESYSTEM::filesize('/dummy'),'Unexpected filesize'); + } + + public function stat(){ + OC_FILESYSTEM::file_put_contents('/dummy','foo'); + $time=time(); + $stat=OC_FILESYSTEM::stat('/dummy'); + $this->assertEquals(true,abs($time-$stat['atime'])<1,'Unexpected access time');//there can be small difference between those values due to running time + $this->assertEquals(true,abs($time-$stat['ctime'])<1,'Unexpected creation time'); + $this->assertEquals(true,abs($time-$stat['mtime'])<1,'Unexpected modified time'); + $this->assertEquals(3,$stat['size'],'Unexpected filesize'); + } + + public function filetype(){ + OC_FILESYSTEM::file_put_contents('/dummyFile','foo'); + OC_FILESYSTEM::mkdir('/dummyFolder'); + $this->assertEquals('file', OC_FILESYSTEM::filetype('/dummyFile'),'Unexpected filetype of file'); + $this->assertEquals('dir', OC_FILESYSTEM::filetype('/dummyFolder'),'Unexpected filetype of folder'); + } + + public function readfile(){ + OC_FILESYSTEM::file_put_contents('/dummy','foo'); + ob_start(); + OC_FILESYSTEM::readfile('/dummy'); + $this->assertEquals('foo', ob_get_contents(),'Unexpected output of readfile'); + ob_end_clean(); + } + + public function isReadable(){ + OC_FILESYSTEM::file_put_contents('/dummy','foo'); + $this->assertEquals(true, OC_FILESYSTEM::is_readable('/dummy'),'Can\'t read created file'); + } + + public function isWritable(){ + OC_FILESYSTEM::file_put_contents('/dummy','foo'); + $this->assertEquals(true, OC_FILESYSTEM::is_writeable('/dummy'),'Can\'t write created file'); + } + + public function fileatime(){ + OC_FILESYSTEM::file_put_contents('/dummy','foo'); + $time=time(); + $this->assertEquals(true,abs($time-OC_FILESYSTEM::fileatime('/dummy'))<1,'Unexpected access time');//there can be small difference between those values due to running time + } + + public function filectime(){ + OC_FILESYSTEM::file_put_contents('/dummy','foo'); + $time=time(); + $this->assertEquals(true,abs($time-OC_FILESYSTEM::filectime('/dummy'))<1,'Unexpected creation time');//there can be small difference between those values due to running time + } + + public function filemtime(){ + OC_FILESYSTEM::file_put_contents('/dummy','foo'); + $time=time(); + $this->assertEquals(true,abs($time-OC_FILESYSTEM::filemtime('/dummy'))<1,'Unexpected modified time');//there can be small difference between those values due to running time + } + + public function fileGetContents(){ + OC_FILESYSTEM::file_put_contents('/dummy','foo'); + $this->assertEquals('foo', OC_FILESYSTEM::file_get_contents('/dummy'),'Unexpected content of file'); + } + + public function unlink(){ + OC_FILESYSTEM::file_put_contents('/dummy','foo'); + OC_FILESYSTEM::unlink('/dummy'); + $this->assertEquals(false, OC_FILESYSTEM::file_exists('/dummy'),'File still exists after deletion'); + } + + public function rename(){ + OC_FILESYSTEM::file_put_contents('/dummy','foo'); + OC_FILESYSTEM::rename('/dummy','/bar'); + $this->assertEquals(true, OC_FILESYSTEM::file_exists('/bar'),'New file doesnt exists after moving'); + $this->assertEquals(false, OC_FILESYSTEM::file_exists('/dummy'),'Old file still exists after moving'); + $this->assertEquals('foo', OC_FILESYSTEM::file_get_contents('/bar'),'Unexpected content of file after moving'); + } + + public function copy(){ + OC_FILESYSTEM::file_put_contents('/dummy','foo'); + OC_FILESYSTEM::copy('/dummy','/bar'); + $this->assertEquals(true, OC_FILESYSTEM::file_exists('/bar'),'New file doesnt exists after copying'); + $this->assertEquals(true, OC_FILESYSTEM::file_exists('/dummy'),'Old file doesnt exists after copying'); + $this->assertEquals('foo', OC_FILESYSTEM::file_get_contents('/bar'),'Unexpected content of file after copying'); + } + + public function fopen(){ + OC_FILESYSTEM::file_put_contents('/dummy','foo'); + $fh=OC_FILESYSTEM::fopen('/dummy','r'); + if(!$fh){ + $this->fail('Cant open file for reading'); + } + $content=fread($fh,3); + $this->assertEquals('foo', $content,'Unexpected content of file'); + fclose($fh); + $fh=OC_FILESYSTEM::fopen('/dummy','a'); + fwrite($fh,'bar',3); + fclose($fh); + $this->assertEquals('foobar', OC_FILESYSTEM::file_get_contents('/dummy'),'Unexpected content of file after appending'); + $fh=OC_FILESYSTEM::fopen('/dummy','w'); + fwrite($fh,'bar',3); + fclose($fh); + $this->assertEquals('bar', OC_FILESYSTEM::file_get_contents('/dummy'),'Unexpected content of file after writing'); + } + + public function toTmpFile(){ + OC_FILESYSTEM::file_put_contents('/dummy','foo'); + $tmp=OC_FILESYSTEM::toTmpFile('/dummy'); + $this->assertEquals('foo', file_get_contents($tmp),'Unexpected content of temporary file'); + unlink($tmp); + } + + public function fromTmpFile(){ + OC_FILESYSTEM::file_put_contents('/dummy','foo'); + $tmp=OC_FILESYSTEM::toTmpFile('/dummy'); + OC_FILESYSTEM::fromTmpFile($tmp,'/bar'); + $this->assertEquals('foo', OC_FILESYSTEM::file_get_contents('/bar'),'Unexpected content of new file'); + $this->assertEquals(false, file_exists($tmp),'Temporary file still exists'); + } + + public function getMimeType(){ + OC_FILESYSTEM::file_put_contents('/dummy','some plain text'); + $this->assertEquals('text/plain', OC_FILESYSTEM::getMimeType('/dummy'),'Unexpected mimetype of pain text file'); + OC_FILESYSTEM::file_put_contents('/dummy',"<?xml version='1.0'?>\n</dummy>"); + $this->assertEquals('application/xml', OC_FILESYSTEM::getMimeType('/dummy'),'Unexpected mimetype of xml file'); + } + + public function delTree(){ + OC_FILESYSTEM::mkdir('/dummy'); + OC_FILESYSTEM::file_put_contents('/dummy/bar','foo'); + OC_FILESYSTEM::delTree('/dummy'); + $this->assertEquals(false, OC_FILESYSTEM::file_exists('/dummy/bar'),'File in deleted folder still exists'); + $this->assertEquals(false, OC_FILESYSTEM::file_exists('/dummy'),'Deleted folder still exists'); + } + + public function getTree(){ + OC_FILESYSTEM::mkdir('/dummy'); + OC_FILESYSTEM::file_put_contents('/dummy/bar','foo'); + $expected=array('/dummy','/dummy/bar'); + $this->assertEquals($expected, OC_FILESYSTEM::getTree('/dummy'),'Unexpected filelist returned'); + } + + public function hash(){ + OC_FILESYSTEM::file_put_contents('/dummy','foo'); + $this->assertEquals(md5('foo'), OC_FILESYSTEM::hash('md5','/dummy'),'Unexpected md5 hash of file'); + } + + public function freeSpace(){ + $oldSpace=OC_FILESYSTEM::free_space('/'); + OC_FILESYSTEM::file_put_contents('/dummy','foo'); + $newSpace=OC_FILESYSTEM::free_space('/'); + $this->assertEquals(true, $newSpace<$oldSpace,'free space not smaller after creating a non empty file'); + } + + public function search(){ + OC_FILESYSTEM::file_put_contents('/dummy','foo'); + $this->assertEquals(array('/dummy'),OC_FILESYSTEM::search('my'),'unexpected file list after search'); + } +} +return 'OC_FILEYSYSTEM_Test'; +?>
\ No newline at end of file diff --git a/tests/templates/index.php b/tests/templates/index.php new file mode 100644 index 00000000000..b8d3dac0666 --- /dev/null +++ b/tests/templates/index.php @@ -0,0 +1,11 @@ +<?php foreach($_['tests'] as $name=>$results):?> + <h2><?php echo $name;?></h2> + <ul> + <?php foreach($results as $test=>$result):?> + <li> + <b><?php echo $test;?></b> + <?php echo $result;?> + </il> + <?php endforeach ?> + </ul> +<?php endforeach ?>
\ No newline at end of file |