summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Gapczynski <GapczynskiM@gmail.com>2011-07-04 16:36:30 -0400
committerMichael Gapczynski <GapczynskiM@gmail.com>2011-07-04 16:36:30 -0400
commit05389827fd8bc70b1092dc2bae1ed0335536cf4c (patch)
tree84dea83406b3b5d5cc0cf270a4e95875f3956300
parente24e2d0e16a360753cc0430f2ba75f903c669b14 (diff)
parent53ae56097de2098a2ffd1a8dd1076825bc93305d (diff)
downloadnextcloud-server-05389827fd8bc70b1092dc2bae1ed0335536cf4c.tar.gz
nextcloud-server-05389827fd8bc70b1092dc2bae1ed0335536cf4c.zip
Merge branch 'master' into sharing
Conflicts: .gitignore lib/base.php
-rw-r--r--.gitignore11
-rw-r--r--.htaccess3
-rw-r--r--3dparty/MDB2.php10
-rw-r--r--3dparty/MDB2/Schema/Parser.php9
-rw-r--r--3dparty/MDB2/Schema/Validate.php5
-rw-r--r--3dparty/PEAR.php12
-rw-r--r--admin/ajax/changepassword.php2
-rw-r--r--admin/ajax/creategroup.php2
-rw-r--r--admin/ajax/createuser.php2
-rw-r--r--admin/ajax/disableapp.php9
-rw-r--r--admin/ajax/enableapp.php9
-rw-r--r--admin/ajax/removegroup.php2
-rw-r--r--admin/ajax/removeuser.php2
-rw-r--r--admin/ajax/togglegroups.php2
-rw-r--r--admin/appinfo/app.php3
-rw-r--r--admin/apps.php98
-rw-r--r--admin/css/apps.css19
-rw-r--r--admin/js/apps.js18
-rw-r--r--admin/l10n/da.php20
-rw-r--r--admin/l10n/de.php20
-rw-r--r--admin/l10n/nl.php20
-rw-r--r--admin/l10n/pl.php21
-rw-r--r--admin/l10n/xgettextfiles5
-rw-r--r--admin/plugins.php52
-rw-r--r--admin/system.php2
-rw-r--r--admin/templates/app.php6
-rw-r--r--admin/templates/app_noconn.php7
-rw-r--r--admin/templates/apps.php8
-rw-r--r--admin/templates/appsinst.php27
-rw-r--r--admin/templates/plugins.php28
-rw-r--r--admin/templates/system.php4
-rw-r--r--admin/templates/users.php40
-rw-r--r--admin/users.php2
-rw-r--r--apps/files_publiclink/admin.php2
-rw-r--r--apps/files_publiclink/appinfo/database.xml2
-rw-r--r--apps/files_publiclink/js/admin.js6
-rw-r--r--apps/files_publiclink/lib_public.php6
-rw-r--r--apps/files_publiclink/templates/admin.php10
-rw-r--r--apps/files_publiclink/templates/index.php6
-rw-r--r--apps/user_ldap/appinfo/app.php39
-rw-r--r--apps/user_ldap/appinfo/info.xml10
-rw-r--r--apps/user_ldap/settings.php52
-rw-r--r--apps/user_ldap/templates/settings.php27
-rw-r--r--apps/user_ldap/user_ldap.php114
-rw-r--r--apps/user_openid/appinfo/app.php47
-rw-r--r--apps/user_openid/appinfo/info.xml10
-rw-r--r--apps/user_openid/class.openid.v3.php328
-rw-r--r--apps/user_openid/phpmyid.php1740
-rw-r--r--apps/user_openid/settings.php24
-rw-r--r--apps/user_openid/templates/nomode.php28
-rw-r--r--apps/user_openid/templates/settings.php7
-rw-r--r--apps/user_openid/user.php47
-rw-r--r--apps/user_openid/user_openid.php71
-rwxr-xr-x[-rw-r--r--]config/.gitignore0
-rw-r--r--core/ajax/translations.php34
-rw-r--r--core/css/images/no.png (renamed from css/images/no.png)bin1300 -> 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)bin251 -> 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)bin181 -> 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)bin119 -> 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)bin131 -> 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)bin124 -> 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)bin103 -> 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)bin118 -> 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)bin104 -> 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)bin153 -> 153 bytes
-rw-r--r--core/css/images/ui-icons_2694e8_256x240.png (renamed from css/images/ui-icons_2694e8_256x240.png)bin5355 -> 5355 bytes
-rw-r--r--core/css/images/ui-icons_2e83ff_256x240.png (renamed from css/images/ui-icons_2e83ff_256x240.png)bin4369 -> 4369 bytes
-rw-r--r--core/css/images/ui-icons_3d80b3_256x240.png (renamed from css/images/ui-icons_3d80b3_256x240.png)bin5355 -> 5355 bytes
-rw-r--r--core/css/images/ui-icons_72a7cf_256x240.png (renamed from css/images/ui-icons_72a7cf_256x240.png)bin4369 -> 4369 bytes
-rw-r--r--core/css/images/ui-icons_ffffff_256x240.png (renamed from css/images/ui-icons_ffffff_256x240.png)bin4369 -> 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)bin525 -> 525 bytes
-rw-r--r--core/img/actions/arrow-left.png (renamed from img/actions/arrow-left.png)bin512 -> 512 bytes
-rw-r--r--core/img/actions/arrow-right.png (renamed from img/actions/arrow-right.png)bin527 -> 527 bytes
-rw-r--r--core/img/actions/arrow-up.png (renamed from img/actions/arrow-up.png)bin484 -> 484 bytes
-rw-r--r--core/img/actions/go-home.png (renamed from img/actions/go-home.png)bin397 -> 397 bytes
-rw-r--r--core/img/body_background.jpg (renamed from img/body_background.jpg)bin305 -> 305 bytes
-rw-r--r--core/img/drop-arrow.png (renamed from img/drop-arrow.png)bin2899 -> 2899 bytes
-rw-r--r--core/img/favicon-touch.png (renamed from img/favicon-touch.png)bin7272 -> 7272 bytes
-rw-r--r--core/img/favicon.png (renamed from img/favicon.png)bin565 -> 565 bytes
-rw-r--r--core/img/header-a.png (renamed from img/header-a.png)bin2951 -> 2951 bytes
-rw-r--r--core/img/header-login.png (renamed from img/header-login.png)bin2402 -> 2402 bytes
-rw-r--r--core/img/header-settings-a.png (renamed from img/header-settings-a.png)bin2885 -> 2885 bytes
-rw-r--r--core/img/header-settings.png (renamed from img/header-settings.png)bin2887 -> 2887 bytes
-rw-r--r--core/img/header.png (renamed from img/header.png)bin2953 -> 2953 bytes
-rw-r--r--core/img/layout/back.png (renamed from img/layout/back.png)bin396 -> 396 bytes
-rw-r--r--core/img/layout/logout.png (renamed from img/layout/logout.png)bin657 -> 657 bytes
-rw-r--r--core/img/layout/settings.png (renamed from img/layout/settings.png)bin695 -> 695 bytes
-rw-r--r--core/img/mimetypes/file.png (renamed from img/mimetypes/file.png)bin391 -> 391 bytes
-rw-r--r--core/img/owncloud-logo-medium-white.png (renamed from img/owncloud-logo-medium-white.png)bin15478 -> 15478 bytes
-rw-r--r--core/img/owncloud-logo-small-white.png (renamed from img/owncloud-logo-small-white.png)bin5444 -> 5444 bytes
-rw-r--r--core/img/places/folder.png (renamed from img/places/folder.png)bin386 -> 386 bytes
-rw-r--r--core/img/weather-clear.png (renamed from img/weather-clear.png)bin21917 -> 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.js23
-rw-r--r--core/js/setup.js (renamed from js/js.js)10
-rw-r--r--core/l10n/da.php27
-rw-r--r--core/l10n/de.php27
-rw-r--r--core/l10n/l10n-de.php5
-rw-r--r--core/l10n/nl.php27
-rw-r--r--core/l10n/pl.php27
-rw-r--r--core/l10n/xgettextfiles7
-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.php70
-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.php1
-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.xml10
-rw-r--r--docs/createtranslation.pl29
-rw-r--r--docs/getstrings.pl18
-rw-r--r--files/admin.php2
-rw-r--r--files/appinfo/app.php2
-rw-r--r--files/css/files.css2
-rw-r--r--files/img/drop-arrow.pngbin0 -> 2899 bytes
-rw-r--r--files/js/fileactions.js13
-rw-r--r--files/js/filelist.js8
-rw-r--r--files/js/files.js3
-rw-r--r--files/templates/admin.php30
-rw-r--r--files/templates/index.php14
-rw-r--r--help/l10n/da.php4
-rw-r--r--help/l10n/de.php4
-rw-r--r--help/l10n/nl.php4
-rw-r--r--help/l10n/pl.php4
-rw-r--r--help/l10n/xgettextfiles1
-rw-r--r--help/templates/index.php4
-rw-r--r--index.php4
-rw-r--r--l10n/da/admin.po96
-rw-r--r--l10n/da/core.po118
-rw-r--r--l10n/da/help.po26
-rw-r--r--l10n/da/log.po66
-rw-r--r--l10n/da/settings.po87
-rw-r--r--l10n/de/admin.po91
-rw-r--r--l10n/de/core.po122
-rw-r--r--l10n/de/help.po26
-rw-r--r--l10n/de/log.po67
-rw-r--r--l10n/de/settings.po86
-rw-r--r--l10n/l10n.pl102
-rw-r--r--l10n/nl/admin.po92
-rw-r--r--l10n/nl/core.po122
-rw-r--r--l10n/nl/help.po27
-rw-r--r--l10n/nl/log.po67
-rw-r--r--l10n/nl/settings.po86
-rw-r--r--l10n/pl/admin.po96
-rw-r--r--l10n/pl/core.po123
-rw-r--r--l10n/pl/help.po28
-rw-r--r--l10n/pl/log.po68
-rw-r--r--l10n/pl/settings.po88
-rw-r--r--l10n/templates/admin.pot95
-rw-r--r--l10n/templates/core.pot120
-rw-r--r--l10n/templates/help.pot26
-rw-r--r--l10n/templates/log.pot66
-rw-r--r--l10n/templates/settings.pot86
-rw-r--r--lib/HTTP/WebDAV/Server/Filesystem.php7
-rw-r--r--lib/MDB2/Driver/Datatype/sqlite3.php412
-rw-r--r--lib/MDB2/Driver/Function/sqlite3.php161
-rw-r--r--lib/MDB2/Driver/Manager/sqlite3.php1364
-rw-r--r--lib/MDB2/Driver/Native/sqlite3.php58
-rw-r--r--lib/MDB2/Driver/Reverse/sqlite3.php607
-rw-r--r--lib/MDB2/Driver/sqlite3.php1361
-rw-r--r--lib/User/backend.php126
-rw-r--r--lib/User/database.php97
-rw-r--r--lib/User/example.php97
-rw-r--r--lib/app.php138
-rw-r--r--lib/base.php33
-rw-r--r--lib/config.php5
-rw-r--r--lib/database.php52
-rw-r--r--lib/files.php15
-rw-r--r--lib/filestorage.php2
-rw-r--r--lib/filesystem.php231
-rwxr-xr-x[-rw-r--r--]lib/helper.php43
-rw-r--r--lib/installer.php83
-rw-r--r--lib/l10n.php269
-rw-r--r--lib/log.php14
-rw-r--r--lib/ocsclient.php128
-rw-r--r--lib/preferences.php8
-rw-r--r--lib/setup.php36
-rw-r--r--lib/template.php49
-rw-r--r--lib/testcase.php93
-rw-r--r--lib/user.php121
-rw-r--r--log/index.php38
-rw-r--r--log/js/log.js6
-rw-r--r--log/l10n/da.php14
-rw-r--r--log/l10n/de.php14
-rw-r--r--log/l10n/nl.php14
-rw-r--r--log/l10n/pl.php14
-rw-r--r--log/l10n/xgettextfiles1
-rw-r--r--log/templates/index.php40
-rw-r--r--search/index.php3
-rw-r--r--settings/ajax/changepassword.php12
-rw-r--r--settings/ajax/setlanguage.php26
-rw-r--r--settings/index.php7
-rw-r--r--settings/js/main.js14
-rw-r--r--settings/l10n/da.php19
-rw-r--r--settings/l10n/de.php19
-rw-r--r--settings/l10n/nl.php19
-rw-r--r--settings/l10n/pl.php19
-rw-r--r--settings/l10n/xgettextfiles3
-rw-r--r--settings/templates/index.php52
-rw-r--r--templates/installation.php70
-rw-r--r--templates/logout.php1
-rw-r--r--tests/index.php79
-rw-r--r--tests/lib/filesystem.php222
-rw-r--r--tests/templates/index.php11
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&parameters=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>&nbsp;</td>
<td>&nbsp;</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 "&nbsp";} ?></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: ?>
&nbsp;
<?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
index fdc0f421255..fdc0f421255 100644
--- a/css/images/no.png
+++ b/core/css/images/no.png
Binary files differ
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
index 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
Binary files differ
diff --git a/css/images/ui-bg_flat_15_cd0a0a_40x100.png b/core/css/images/ui-bg_flat_15_cd0a0a_40x100.png
index 7680b5437cf..7680b5437cf 100644
--- a/css/images/ui-bg_flat_15_cd0a0a_40x100.png
+++ b/core/css/images/ui-bg_flat_15_cd0a0a_40x100.png
Binary files differ
diff --git a/css/images/ui-bg_glass_100_e4f1fb_1x400.png b/core/css/images/ui-bg_glass_100_e4f1fb_1x400.png
index 705a32ea35d..705a32ea35d 100644
--- a/css/images/ui-bg_glass_100_e4f1fb_1x400.png
+++ b/core/css/images/ui-bg_glass_100_e4f1fb_1x400.png
Binary files differ
diff --git a/css/images/ui-bg_glass_50_3baae3_1x400.png b/core/css/images/ui-bg_glass_50_3baae3_1x400.png
index baabca6baaf..baabca6baaf 100644
--- a/css/images/ui-bg_glass_50_3baae3_1x400.png
+++ b/core/css/images/ui-bg_glass_50_3baae3_1x400.png
Binary files differ
diff --git a/css/images/ui-bg_glass_80_d7ebf9_1x400.png b/core/css/images/ui-bg_glass_80_d7ebf9_1x400.png
index d9387e9507e..d9387e9507e 100644
--- a/css/images/ui-bg_glass_80_d7ebf9_1x400.png
+++ b/core/css/images/ui-bg_glass_80_d7ebf9_1x400.png
Binary files differ
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
index 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
Binary files differ
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
index 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
Binary files differ
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
index 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
Binary files differ
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
index 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
Binary files differ
diff --git a/css/images/ui-icons_2694e8_256x240.png b/core/css/images/ui-icons_2694e8_256x240.png
index 9d192c2f659..9d192c2f659 100644
--- a/css/images/ui-icons_2694e8_256x240.png
+++ b/core/css/images/ui-icons_2694e8_256x240.png
Binary files differ
diff --git a/css/images/ui-icons_2e83ff_256x240.png b/core/css/images/ui-icons_2e83ff_256x240.png
index 09d1cdc856c..09d1cdc856c 100644
--- a/css/images/ui-icons_2e83ff_256x240.png
+++ b/core/css/images/ui-icons_2e83ff_256x240.png
Binary files differ
diff --git a/css/images/ui-icons_3d80b3_256x240.png b/core/css/images/ui-icons_3d80b3_256x240.png
index f13b206645b..f13b206645b 100644
--- a/css/images/ui-icons_3d80b3_256x240.png
+++ b/core/css/images/ui-icons_3d80b3_256x240.png
Binary files differ
diff --git a/css/images/ui-icons_72a7cf_256x240.png b/core/css/images/ui-icons_72a7cf_256x240.png
index 0d20b730833..0d20b730833 100644
--- a/css/images/ui-icons_72a7cf_256x240.png
+++ b/core/css/images/ui-icons_72a7cf_256x240.png
Binary files differ
diff --git a/css/images/ui-icons_ffffff_256x240.png b/core/css/images/ui-icons_ffffff_256x240.png
index 42f8f992c72..42f8f992c72 100644
--- a/css/images/ui-icons_ffffff_256x240.png
+++ b/core/css/images/ui-icons_ffffff_256x240.png
Binary files differ
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
index 03f201428ad..03f201428ad 100644
--- a/img/actions/arrow-down.png
+++ b/core/img/actions/arrow-down.png
Binary files differ
diff --git a/img/actions/arrow-left.png b/core/img/actions/arrow-left.png
index b56cfee03df..b56cfee03df 100644
--- a/img/actions/arrow-left.png
+++ b/core/img/actions/arrow-left.png
Binary files differ
diff --git a/img/actions/arrow-right.png b/core/img/actions/arrow-right.png
index 0acee70bcdd..0acee70bcdd 100644
--- a/img/actions/arrow-right.png
+++ b/core/img/actions/arrow-right.png
Binary files differ
diff --git a/img/actions/arrow-up.png b/core/img/actions/arrow-up.png
index 5e423213fbd..5e423213fbd 100644
--- a/img/actions/arrow-up.png
+++ b/core/img/actions/arrow-up.png
Binary files differ
diff --git a/img/actions/go-home.png b/core/img/actions/go-home.png
index 3802c98fc46..3802c98fc46 100644
--- a/img/actions/go-home.png
+++ b/core/img/actions/go-home.png
Binary files differ
diff --git a/img/body_background.jpg b/core/img/body_background.jpg
index c3d0102f711..c3d0102f711 100644
--- a/img/body_background.jpg
+++ b/core/img/body_background.jpg
Binary files differ
diff --git a/img/drop-arrow.png b/core/img/drop-arrow.png
index 315395d5d42..315395d5d42 100644
--- a/img/drop-arrow.png
+++ b/core/img/drop-arrow.png
Binary files differ
diff --git a/img/favicon-touch.png b/core/img/favicon-touch.png
index 20af826523c..20af826523c 100644
--- a/img/favicon-touch.png
+++ b/core/img/favicon-touch.png
Binary files differ
diff --git a/img/favicon.png b/core/img/favicon.png
index a7ee766dfa8..a7ee766dfa8 100644
--- a/img/favicon.png
+++ b/core/img/favicon.png
Binary files differ
diff --git a/img/header-a.png b/core/img/header-a.png
index 46fb0977ee2..46fb0977ee2 100644
--- a/img/header-a.png
+++ b/core/img/header-a.png
Binary files differ
diff --git a/img/header-login.png b/core/img/header-login.png
index b0160e02d1f..b0160e02d1f 100644
--- a/img/header-login.png
+++ b/core/img/header-login.png
Binary files differ
diff --git a/img/header-settings-a.png b/core/img/header-settings-a.png
index a72271be6a4..a72271be6a4 100644
--- a/img/header-settings-a.png
+++ b/core/img/header-settings-a.png
Binary files differ
diff --git a/img/header-settings.png b/core/img/header-settings.png
index 7e6b70b5903..7e6b70b5903 100644
--- a/img/header-settings.png
+++ b/core/img/header-settings.png
Binary files differ
diff --git a/img/header.png b/core/img/header.png
index d377f65186d..d377f65186d 100644
--- a/img/header.png
+++ b/core/img/header.png
Binary files differ
diff --git a/img/layout/back.png b/core/img/layout/back.png
index 86abbe0cabe..86abbe0cabe 100644
--- a/img/layout/back.png
+++ b/core/img/layout/back.png
Binary files differ
diff --git a/img/layout/logout.png b/core/img/layout/logout.png
index 74dcd33bee7..74dcd33bee7 100644
--- a/img/layout/logout.png
+++ b/core/img/layout/logout.png
Binary files differ
diff --git a/img/layout/settings.png b/core/img/layout/settings.png
index ff650ecb0b0..ff650ecb0b0 100644
--- a/img/layout/settings.png
+++ b/core/img/layout/settings.png
Binary files differ
diff --git a/img/mimetypes/file.png b/core/img/mimetypes/file.png
index 49790448897..49790448897 100644
--- a/img/mimetypes/file.png
+++ b/core/img/mimetypes/file.png
Binary files differ
diff --git a/img/owncloud-logo-medium-white.png b/core/img/owncloud-logo-medium-white.png
index d4d06fdd62d..d4d06fdd62d 100644
--- a/img/owncloud-logo-medium-white.png
+++ b/core/img/owncloud-logo-medium-white.png
Binary files differ
diff --git a/img/owncloud-logo-small-white.png b/core/img/owncloud-logo-small-white.png
index 397ddf91341..397ddf91341 100644
--- a/img/owncloud-logo-small-white.png
+++ b/core/img/owncloud-logo-small-white.png
Binary files differ
diff --git a/img/places/folder.png b/core/img/places/folder.png
index 3edbe257a34..3edbe257a34 100644
--- a/img/places/folder.png
+++ b/core/img/places/folder.png
Binary files differ
diff --git a/img/weather-clear.png b/core/img/weather-clear.png
index 0acf7a9b2af..0acf7a9b2af 100644
--- a/img/weather-clear.png
+++ b/core/img/weather-clear.png
Binary files differ
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>&nbsp;&nbsp;</span>
+ <span class="pagerbutton1"><a href="<?php echo $_['url'].($_['page']-1);?>"><?php echo $l->t( 'prev' ); ?></a>&nbsp;&nbsp;</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
new file mode 100644
index 00000000000..315395d5d42
--- /dev/null
+++ b/files/img/drop-arrow.png
Binary files differ
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" />&nbsp;
- <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'/>&nbsp;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'/>&nbsp;<?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'] ?>%;">&nbsp;</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