Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/server.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorRobin Appelman <icewind@owncloud.com>2012-01-30 16:39:51 +0400
committerRobin Appelman <icewind@owncloud.com>2012-01-30 16:39:51 +0400
commit686590bd3a510efc0cf2752a3d0fd48d536f787d (patch)
tree662fef8f57ee4c0511e949cc559ac24e33ed51d2 /lib
parent40ba508874f0e87d2d6709fa6d13107c5a49972b (diff)
parent039bbfde2d2e1efc90fa9828811566ea1f328722 (diff)
merge master into stable
Diffstat (limited to 'lib')
-rw-r--r--lib/MDB2/Driver/Datatype/sqlite3.php65
-rw-r--r--lib/MDB2/Driver/Function/sqlite3.php64
-rw-r--r--lib/MDB2/Driver/Manager/sqlite3.php154
-rw-r--r--lib/MDB2/Driver/Native/sqlite3.php64
-rw-r--r--lib/MDB2/Driver/Reverse/sqlite3.php81
-rw-r--r--lib/MDB2/Driver/sqlite3.php64
-rw-r--r--lib/app.php54
-rw-r--r--lib/appconfig.php2
-rw-r--r--lib/base.php110
-rw-r--r--lib/config.php3
-rw-r--r--lib/db.php447
-rw-r--r--lib/files.php25
-rw-r--r--lib/filestorage/local.php21
-rw-r--r--lib/filestorage/remote.php2
-rw-r--r--lib/filesystem.php212
-rw-r--r--lib/helper.php33
-rw-r--r--lib/hook.php2
-rw-r--r--lib/image.php557
-rw-r--r--lib/installer.php24
-rw-r--r--lib/l10n.php16
-rw-r--r--lib/log.php74
-rw-r--r--lib/mimetypes.fixlist.php14
-rw-r--r--lib/ocsclient.php29
-rw-r--r--lib/preferences.php1
-rw-r--r--lib/remote/cloud.php8
-rw-r--r--lib/setup.php74
-rw-r--r--lib/template.php27
-rw-r--r--lib/updater.php11
-rw-r--r--lib/user.php5
-rw-r--r--lib/util.php67
-rw-r--r--lib/vobject.php207
31 files changed, 1846 insertions, 671 deletions
diff --git a/lib/MDB2/Driver/Datatype/sqlite3.php b/lib/MDB2/Driver/Datatype/sqlite3.php
index 378d5540cbe..d74badbe4f1 100644
--- a/lib/MDB2/Driver/Datatype/sqlite3.php
+++ b/lib/MDB2/Driver/Datatype/sqlite3.php
@@ -1,49 +1,24 @@
<?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 $
-//
+/**
+ * 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/>.
+ *
+ */
require_once('MDB2/Driver/Datatype/Common.php');
diff --git a/lib/MDB2/Driver/Function/sqlite3.php b/lib/MDB2/Driver/Function/sqlite3.php
index 0d6b329f0ad..a013aea165a 100644
--- a/lib/MDB2/Driver/Function/sqlite3.php
+++ b/lib/MDB2/Driver/Function/sqlite3.php
@@ -1,48 +1,24 @@
<?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> |
-// +----------------------------------------------------------------------+
-//
-//
+/**
+ * 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/>.
+ *
+ */
require_once('MDB2/Driver/Function/Common.php');
diff --git a/lib/MDB2/Driver/Manager/sqlite3.php b/lib/MDB2/Driver/Manager/sqlite3.php
index eabbb72b3c2..8f4e1312eb8 100644
--- a/lib/MDB2/Driver/Manager/sqlite3.php
+++ b/lib/MDB2/Driver/Manager/sqlite3.php
@@ -1,48 +1,24 @@
<?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> |
-// +----------------------------------------------------------------------+
-//
-//
+/**
+ * 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/>.
+ *
+ */
require_once('MDB2/Driver/Manager/Common.php');
@@ -192,9 +168,6 @@ class MDB2_Driver_Manager_sqlite3 extends MDB2_Driver_Manager_Common
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)) {
@@ -558,9 +531,26 @@ class MDB2_Driver_Manager_sqlite3 extends MDB2_Driver_Manager_Common
return MDB2_OK;
}
+ if (empty($changes['remove']) and empty($changes['rename']) and empty($changes['change']) ){//if only rename or add changes are required, we can use ALTER TABLE
+ $query = '';
+ if (!empty($changes['name'])) {
+ $change_name = $db->quoteIdentifier($changes['name'], true);
+ $query = 'RENAME TO ' . $change_name;
+ $db->exec("ALTER TABLE $name $query");
+ }
+
+ if (!empty($changes['add']) && is_array($changes['add'])) {
+ foreach ($changes['add'] as $field_name => $field) {
+ $query= 'ADD ' . $db->getDeclaration($field['type'], $field_name, $field);
+ $db->exec("ALTER TABLE $name $query");
+ }
+ }
+ return MDB2_OK;
+ }
+
$db->loadModule('Reverse', null, true);
- // actually sqlite 2.x supports no ALTER TABLE at all .. so we emulate it
+ // for other operations we need to emulate them with sqlite3
$fields = $db->manager->listTableFields($name);
if (PEAR::isError($fields)) {
return $fields;
@@ -660,44 +650,54 @@ class MDB2_Driver_Manager_sqlite3 extends MDB2_Driver_Manager_Common
}
}
+ //rename the old table so we can create the new one
+ $db->exec("ALTER TABLE $name RENAME TO __$name");
$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);
- }
+ //these seem to only give errors
- foreach ($constraints as $constraint => $definition) {
- $this->createConstraint($name_new, $constraint, $definition);
- }
+// foreach ($indexes as $index => $definition) {
+// $this->createIndex($name_new, $index, $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;
- }
- }
+// foreach ($constraints as $constraint => $definition) {
+// $this->createConstraint($name_new, $constraint, $definition);
+// }
+
+ //fill the new table with data from the old one
+ if (!empty($select_fields)) {
+ $query = 'INSERT INTO '.$db->quoteIdentifier($name_new, true);
+ $query.= '('.implode(', ', array_slice(array_keys($fields), 0, count($select_fields))).')';
+ $query .= ' SELECT '.implode(', ', $select_fields).' FROM '.$db->quoteIdentifier('__'.$name, true);
+ $db->exec($query);
+ }
+
+// 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;
+// }
+// }
+// }
+
+ //remove the old table
+ $result = $this->dropTable('__'.$name);
+ if (PEAR::isError($result)) {
+ return $result;
}
return MDB2_OK;
}
@@ -822,7 +822,7 @@ class MDB2_Driver_Manager_sqlite3 extends MDB2_Driver_Manager_Common
return $db;
}
- $query = "SELECT name FROM sqlite_master WHERE type='table' AND sql NOT NULL ORDER BY name";
+ $query = "SELECT name FROM sqlite_master WHERE type='table' AND sql NOT NULL AND name!='sqlite_sequence' ORDER BY name";
$table_names = $db->queryCol($query);
if (PEAR::isError($table_names)) {
return $table_names;
diff --git a/lib/MDB2/Driver/Native/sqlite3.php b/lib/MDB2/Driver/Native/sqlite3.php
index 81dc67dea65..de650107238 100644
--- a/lib/MDB2/Driver/Native/sqlite3.php
+++ b/lib/MDB2/Driver/Native/sqlite3.php
@@ -1,48 +1,24 @@
<?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> |
-// +----------------------------------------------------------------------+
-//
-//
+/**
+ * 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/>.
+ *
+ */
require_once 'MDB2/Driver/Native/Common.php';
/**
diff --git a/lib/MDB2/Driver/Reverse/sqlite3.php b/lib/MDB2/Driver/Reverse/sqlite3.php
index d488977b158..33e5b590268 100644
--- a/lib/MDB2/Driver/Reverse/sqlite3.php
+++ b/lib/MDB2/Driver/Reverse/sqlite3.php
@@ -1,48 +1,24 @@
<?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> |
-// +----------------------------------------------------------------------+
-//
-//
+/**
+ * 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/>.
+ *
+ */
require_once('MDB2/Driver/Reverse/Common.php');
@@ -93,7 +69,7 @@ class MDB2_Driver_Reverse_sqlite3 extends MDB2_Driver_Reverse_Common
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';
+ $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)?( AUTOINCREMENT)?( 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)) {
@@ -114,11 +90,16 @@ class MDB2_Driver_Reverse_sqlite3 extends MDB2_Driver_Reverse_Common
if (isset($matches[8]) && strlen($matches[8])) {
$columns[$j]['unsigned'] = true;
}
- if (isset($matches[9]) && strlen($matches[9])) {
+ if (isset($matches[10]) && strlen($matches[10])) {
+ $columns[$j]['autoincrement'] = true;
+ $columns[$j]['notnull']=true;
+ }
+ if (isset($matches[10]) && strlen($matches[10])) {
$columns[$j]['autoincrement'] = true;
+ $columns[$j]['notnull']=true;
}
- if (isset($matches[12]) && strlen($matches[12])) {
- $default = $matches[12];
+ if (isset($matches[13]) && strlen($matches[13])) {
+ $default = $matches[13];
if (strlen($default) && $default[0]=="'") {
$default = str_replace("''", "'", substr($default, 1, strlen($default)-2));
}
@@ -131,8 +112,8 @@ class MDB2_Driver_Reverse_sqlite3 extends MDB2_Driver_Reverse_Common
$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');
+ } else if (isset($matches[14]) && strlen($matches[14])) {
+ $columns[$j]['notnull'] = ($matches[14] === ' NOT NULL');
}
++$j;
}
diff --git a/lib/MDB2/Driver/sqlite3.php b/lib/MDB2/Driver/sqlite3.php
index a41aeed4850..e42d36176c4 100644
--- a/lib/MDB2/Driver/sqlite3.php
+++ b/lib/MDB2/Driver/sqlite3.php
@@ -1,48 +1,24 @@
<?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> |
-// +----------------------------------------------------------------------+
-//
-//
+/**
+ * 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/>.
+ *
+ */
/**
* MDB2 SQLite3 driver
diff --git a/lib/app.php b/lib/app.php
index b9eea483a55..37a99823e3d 100644
--- a/lib/app.php
+++ b/lib/app.php
@@ -94,19 +94,28 @@ class OC_App{
*/
public static function enable( $app ){
if(!OC_Installer::isInstalled($app)){
- OC_Installer::installShippedApp($app);
+ // check if app is a shipped app or not. OCS apps have an integer as id, shipped apps use a string
+ if(!is_numeric($app)){
+ OC_Installer::installShippedApp($app);
+ }else{
+ $download=OC_OCSClient::getApplicationDownload($app,1);
+ if(isset($download['downloadlink']) and $download['downloadlink']<>'') {
+ $app=OC_Installer::installApp(array('source'=>'http','href'=>$download['downloadlink']));
+ }
+ }
}
OC_Appconfig::setValue( $app, 'enabled', 'yes' );
}
/**
- * @brief enables an app
+ * @brief disables an app
* @param $app app
* @returns true/false
*
- * This function set an app as enabled in appconfig.
+ * This function set an app as disabled in appconfig.
*/
public static function disable( $app ){
+ // check if app is a shiped app or not. if not delete
OC_Appconfig::setValue( $app, 'enabled', 'no' );
}
@@ -222,11 +231,10 @@ class OC_App{
$settings[] = array( "id" => "core_users", "order" => 2, "href" => OC_Helper::linkTo( "settings", "users.php" ), "name" => $l->t("Users"), "icon" => OC_Helper::imagePath( "settings", "users.svg" ));
// admin apps menu
$settings[] = array( "id" => "core_apps", "order" => 3, "href" => OC_Helper::linkTo( "settings", "apps.php?installed" ), "name" => $l->t("Apps"), "icon" => OC_Helper::imagePath( "settings", "apps.svg" ));
+ // admin log menu
+ $settings[] = array( "id" => "core_log", "order" => 4, "href" => OC_Helper::linkTo( "settings", "log.php" ), "name" => $l->t("Log"), "icon" => OC_Helper::imagePath( "settings", "log.svg" ));
- // if there're some admin forms
- if(!empty(self::$adminForms))
- // admins menu
- $settings[]=array( "id" => "admin", "order" => 1000, "href" => OC_Helper::linkTo( "settings", "admin.php" ), "name" => $l->t("Admin"), "icon" => OC_Helper::imagePath( "settings", "admin.svg" ));
+ $settings[]=array( "id" => "admin", "order" => 1000, "href" => OC_Helper::linkTo( "settings", "admin.php" ), "name" => $l->t("Admin"), "icon" => OC_Helper::imagePath( "settings", "admin.svg" ));
}
}
@@ -363,4 +371,36 @@ class OC_App{
}
return $apps;
}
+
+ /**
+ * check if any apps need updating and update those
+ */
+ public static function updateApps(){
+ // The rest comes here
+ $apps = OC_Appconfig::getApps();
+ foreach( $apps as $app ){
+ $installedVersion=OC_Appconfig::getValue($app,'installed_version');
+ $appInfo=OC_App::getAppInfo($app);
+ if (isset($appInfo['version'])) {
+ $currentVersion=$appInfo['version'];
+ if (version_compare($currentVersion, $installedVersion, '>')) {
+ OC_App::updateApp($app);
+ OC_Appconfig::setValue($app,'installed_version',$appInfo['version']);
+ }
+ }
+ }
+ }
+
+ /**
+ * update the database for the app and call the update script
+ * @param string appid
+ */
+ public static function updateApp($appid){
+ if(file_exists(OC::$SERVERROOT.'/apps/'.$appid.'/appinfo/database.xml')){
+ OC_DB::updateDbFromStructure(OC::$SERVERROOT.'/apps/'.$appid.'/appinfo/database.xml');
+ }
+ if(file_exists(OC::$SERVERROOT.'/apps/'.$appid.'/appinfo/update.php')){
+ include OC::$SERVERROOT.'/apps/'.$appid.'/appinfo/update.php';
+ }
+ }
}
diff --git a/lib/appconfig.php b/lib/appconfig.php
index f43ef141732..2b5cef59adc 100644
--- a/lib/appconfig.php
+++ b/lib/appconfig.php
@@ -47,7 +47,7 @@ class OC_Appconfig{
*/
public static function getApps(){
// No magic in here!
- $query = OC_DB::prepare( 'SELECT DISTINCT( appid ) FROM *PREFIX*appconfig' );
+ $query = OC_DB::prepare( 'SELECT DISTINCT appid FROM *PREFIX*appconfig' );
$result = $query->execute();
$apps = array();
diff --git a/lib/base.php b/lib/base.php
index ade4d889631..ab7cb2990ed 100644
--- a/lib/base.php
+++ b/lib/base.php
@@ -70,6 +70,31 @@ class OC{
}
}
+ /**
+ * autodetects the formfactor of the used device
+ * default -> the normal desktop browser interface
+ * mobile -> interface for smartphones
+ * tablet -> interface for tablets
+ * standalone -> the default interface but without header, footer and sidebar. just the application. useful to ue just a specific app on the desktop in a standalone window.
+ */
+ public static function detectFormfactor(){
+ // please add more useragent strings for other devices
+ if(isset($_SERVER['HTTP_USER_AGENT'])){
+ if(stripos($_SERVER['HTTP_USER_AGENT'],'ipad')>0) {
+ $mode='tablet';
+ }elseif(stripos($_SERVER['HTTP_USER_AGENT'],'iphone')>0){
+ $mode='mobile';
+ }elseif((stripos($_SERVER['HTTP_USER_AGENT'],'N9')>0) and (stripos($_SERVER['HTTP_USER_AGENT'],'nokia')>0)){
+ $mode='mobile';
+ }else{
+ $mode='default';
+ }
+ }else{
+ $mode='default';
+ }
+ return($mode);
+ }
+
public static function init(){
// register autoloader
spl_autoload_register(array('OC','autoload'));
@@ -77,6 +102,9 @@ class OC{
// set some stuff
//ob_start();
error_reporting(E_ALL | E_STRICT);
+ if (defined('DEBUG') && DEBUG){
+ ini_set('display_errors', 1);
+ }
date_default_timezone_set('Europe/Berlin');
ini_set('arg_separator.output','&amp;');
@@ -89,6 +117,14 @@ class OC{
$_SERVER['PHP_AUTH_PW'] = strip_tags($password);
}
+ //set http auth headers for apache+php-cgi work around if variable gets renamed by apache
+ if (isset($_SERVER['REDIRECT_HTTP_AUTHORIZATION']) && preg_match('/Basic\s+(.*)$/i', $_SERVER['REDIRECT_HTTP_AUTHORIZATION'], $matches))
+ {
+ list($name, $password) = explode(':', base64_decode($matches[1]));
+ $_SERVER['PHP_AUTH_USER'] = strip_tags($name);
+ $_SERVER['PHP_AUTH_PW'] = strip_tags($password);
+ }
+
// calculate the documentroot
OC::$DOCUMENTROOT=realpath($_SERVER['DOCUMENT_ROOT']);
OC::$SERVERROOT=str_replace("\\",'/',substr(__FILE__,0,-13));
@@ -116,12 +152,37 @@ class OC{
}
}
+ if(OC_Config::getValue('installed', false)){
+ $installedVersion=OC_Config::getValue('version','0.0.0');
+ $currentVersion=implode('.',OC_Util::getVersion());
+ if (version_compare($currentVersion, $installedVersion, '>')) {
+ $result=OC_DB::updateDbFromStructure(OC::$SERVERROOT.'/db_structure.xml');
+ if(!$result){
+ echo 'Error while upgrading the database';
+ die();
+ }
+ OC_Config::setValue('version',implode('.',OC_Util::getVersion()));
+ }
+
+ OC_App::updateApps();
+ }
+
ini_set('session.cookie_httponly','1;');
session_start();
+ // if the formfactor is not yet autodetected do the autodetection now. For possible forfactors check the detectFormfactor documentation
+ if(!isset($_SESSION['formfactor'])){
+ $_SESSION['formfactor']=OC::detectFormfactor();
+ }
+ // allow manual override via GET parameter
+ if(isset($_GET['formfactor'])){
+ $_SESSION['formfactor']=$_GET['formfactor'];
+ }
+
+
// Add the stuff we need always
OC_Util::addScript( "jquery-1.6.4.min" );
- OC_Util::addScript( "jquery-ui-1.8.14.custom.min" );
+ OC_Util::addScript( "jquery-ui-1.8.16.custom.min" );
OC_Util::addScript( "jquery-showpassword" );
OC_Util::addScript( "jquery.infieldlabel.min" );
OC_Util::addScript( "jquery-tipsy" );
@@ -130,7 +191,7 @@ class OC{
OC_Util::addScript('search','result');
OC_Util::addStyle( "styles" );
OC_Util::addStyle( "multiselect" );
- OC_Util::addStyle( "jquery-ui-1.8.14.custom" );
+ OC_Util::addStyle( "jquery-ui-1.8.16.custom" );
OC_Util::addStyle( "jquery-tipsy" );
$errors=OC_Util::checkServer();
@@ -154,13 +215,6 @@ class OC{
OC_User::useBackend( OC_Config::getValue( "userbackend", "database" ));
OC_Group::setBackend( OC_Config::getValue( "groupbackend", "database" ));
- // Load Apps
- // This includes plugins for users and filesystems as well
- global $RUNTIME_NOAPPS;
- if(!$RUNTIME_NOAPPS ){
- OC_App::loadApps();
- }
-
// Was in required file ... put it here
OC_Filesystem::registerStorageType('local','OC_Filestorage_Local',array('datadir'=>'string'));
@@ -170,6 +224,13 @@ class OC{
OC_Util::setupFS();
}
+ // Load Apps
+ // This includes plugins for users and filesystems as well
+ global $RUNTIME_NOAPPS;
+ if(!$RUNTIME_NOAPPS ){
+ OC_App::loadApps();
+ }
+
// Last part: connect some hooks
OC_HOOK::connect('OC_User', 'post_createUser', 'OC_Connector_Sabre_Principal', 'addPrincipal');
OC_HOOK::connect('OC_User', 'post_deleteUser', 'OC_Connector_Sabre_Principal', 'deletePrincipal');
@@ -184,23 +245,26 @@ if( !isset( $RUNTIME_NOAPPS )){
$RUNTIME_NOAPPS = false;
}
-OC::init();
-
-if(!function_exists('sys_get_temp_dir')) {
- function sys_get_temp_dir() {
- if( $temp=getenv('TMP') ) return $temp;
- if( $temp=getenv('TEMP') ) return $temp;
- if( $temp=getenv('TMPDIR') ) return $temp;
- $temp=tempnam(__FILE__,'');
- if (file_exists($temp)) {
- unlink($temp);
- return dirname($temp);
- }
- return null;
- }
+if(!function_exists('get_temp_dir')) {
+ function get_temp_dir() {
+ if( $temp=ini_get('upload_tmp_dir') ) return $temp;
+ if( $temp=getenv('TMP') ) return $temp;
+ if( $temp=getenv('TEMP') ) return $temp;
+ if( $temp=getenv('TMPDIR') ) return $temp;
+ $temp=tempnam(__FILE__,'');
+ if (file_exists($temp)) {
+ unlink($temp);
+ return dirname($temp);
+ }
+ return null;
+ }
}
+OC::init();
+
require_once('fakedirstream.php');
+
+
// FROM search.php
new OC_Search_Provider_File();
diff --git a/lib/config.php b/lib/config.php
index 3aa69327f56..8d03271b3ea 100644
--- a/lib/config.php
+++ b/lib/config.php
@@ -94,7 +94,6 @@ class OC_Config{
// Write changes
self::writeData();
-
return true;
}
@@ -175,7 +174,7 @@ class OC_Config{
$result=@file_put_contents( OC::$SERVERROOT."/config/config.php", $content );
if(!$result) {
$tmpl = new OC_Template( '', 'error', 'guest' );
- $tmpl->assign('errors',array(1=>array('error'=>"Can't write into config directory 'config'",'hint'=>"You can usually fix this by setting the owner of 'config' to the user that the web server uses (".OC_Util::checkWebserverUser().")")));
+ $tmpl->assign('errors',array(1=>array('error'=>"Can't write into config directory 'config'",'hint'=>"You can usually fix this by giving the webserver use write access to the config directory in owncloud")));
$tmpl->printPage();
exit;
}
diff --git a/lib/db.php b/lib/db.php
index 7ba08cb48d9..4860651b323 100644
--- a/lib/db.php
+++ b/lib/db.php
@@ -25,7 +25,13 @@
* MDB2 with some adaptions.
*/
class OC_DB {
- static private $DBConnection=false;
+ const BACKEND_PDO=0;
+ const BACKEND_MDB2=1;
+
+ static private $connection; //the prefered connection to use, either PDO or MDB2
+ static private $backend=null;
+ static private $MDB2=false;
+ static private $PDO=false;
static private $schema=false;
static private $affected=0;
static private $result=false;
@@ -36,107 +42,164 @@ class OC_DB {
*
* Connects to the database as specified in config.php
*/
- static public function connect(){
+ public static function connect($backend=null){
+ if(self::$connection){
+ return;
+ }
+ if(is_null($backend)){
+ $backend=self::BACKEND_MDB2;
+ if(class_exists('PDO') && OC_Config::getValue('installed', false)){//check if we can use PDO, else use MDB2 (instalation always needs to be done my mdb2)
+ $type = OC_Config::getValue( "dbtype", "sqlite" );
+ if($type=='sqlite3') $type='sqlite';
+ $drivers=PDO::getAvailableDrivers();
+ if(array_search($type,$drivers)!==false){
+ $backend=self::BACKEND_PDO;
+ }
+ }
+ }
+ if($backend==self::BACKEND_PDO){
+ self::connectPDO();
+ self::$connection=self::$PDO;
+ self::$backend=self::BACKEND_PDO;
+ }else{
+ self::connectMDB2();
+ self::$connection=self::$MDB2;
+ self::$backend=self::BACKEND_MDB2;
+ }
+ }
+
+ /**
+ * connect to the database using pdo
+ */
+ public static function connectPDO(){
+ if(self::$connection){
+ if(self::$backend==self::BACKEND_MDB2){
+ self::disconnect();
+ }else{
+ return;
+ }
+ }
+ // The global data we need
+ $name = OC_Config::getValue( "dbname", "owncloud" );
+ $host = OC_Config::getValue( "dbhost", "" );
+ $user = OC_Config::getValue( "dbuser", "" );
+ $pass = OC_Config::getValue( "dbpassword", "" );
+ $type = OC_Config::getValue( "dbtype", "sqlite" );
+ $datadir=OC_Config::getValue( "datadirectory", OC::$SERVERROOT.'/data' );
+
+ // do nothing if the connection already has been established
+ if(!self::$PDO){
+ // Add the dsn according to the database type
+ switch($type){
+ case 'sqlite':
+ $dsn='sqlite2:'.$datadir.'/'.$name.'.db';
+ break;
+ case 'sqlite3':
+ $dsn='sqlite:'.$datadir.'/'.$name.'.db';
+ break;
+ case 'mysql':
+ $dsn='mysql:dbname='.$name.';host='.$host;
+ break;
+ case 'pgsql':
+ $dsn='pgsql:dbname='.$name.';host='.$host;
+ break;
+ }
+ try{
+ self::$PDO=new PDO($dsn,$user,$pass);
+ }catch(PDOException $e){
+ echo( '<b>can not connect to database, using '.$type.'. ('.$e->getMessage().')</center>');
+ die();
+ }
+ // We always, really always want associative arrays
+ self::$PDO->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE,PDO::FETCH_ASSOC);
+ self::$PDO->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
+ }
+ return true;
+ }
+
+ /**
+ * connect to the database using mdb2
+ */
+ public static function connectMDB2(){
+ if(self::$connection){
+ if(self::$backend==self::BACKEND_PDO){
+ self::disconnect();
+ }else{
+ return;
+ }
+ }
// The global data we need
- $CONFIG_DBNAME = OC_Config::getValue( "dbname", "owncloud" );;
- $CONFIG_DBHOST = OC_Config::getValue( "dbhost", "" );;
- $CONFIG_DBUSER = OC_Config::getValue( "dbuser", "" );;
- $CONFIG_DBPASSWORD = OC_Config::getValue( "dbpassword", "" );;
- $CONFIG_DBTYPE = OC_Config::getValue( "dbtype", "sqlite" );;
- $datadir=OC_Config::getValue( "datadirectory", OC::$SERVERROOT."/data" );
+ $name = OC_Config::getValue( "dbname", "owncloud" );
+ $host = OC_Config::getValue( "dbhost", "" );
+ $user = OC_Config::getValue( "dbuser", "" );
+ $pass = OC_Config::getValue( "dbpassword", "" );
+ $type = OC_Config::getValue( "dbtype", "sqlite" );
+ $SERVERROOT=OC::$SERVERROOT;
+ $datadir=OC_Config::getValue( "datadirectory", "$SERVERROOT/data" );
// do nothing if the connection already has been established
- if(!self::$DBConnection){
+ if(!self::$MDB2){
// Require MDB2.php (not required in the head of the file so we only load it when needed)
require_once('MDB2.php');
// Prepare options array
$options = array(
- 'portability' => MDB2_PORTABILITY_ALL,
+ 'portability' => MDB2_PORTABILITY_ALL & (!MDB2_PORTABILITY_FIX_CASE),
'log_line_break' => '<br>',
'idxname_format' => '%s',
'debug' => true,
'quote_identifier' => true );
// Add the dsn according to the database type
- if( $CONFIG_DBTYPE == 'sqlite' or $CONFIG_DBTYPE == 'sqlite3' ){
- // sqlite
- $dsn = array(
- 'phptype' => $CONFIG_DBTYPE,
- 'database' => "$datadir/$CONFIG_DBNAME.db",
- 'mode' => '0644' );
- }
- elseif( $CONFIG_DBTYPE == 'mysql' ){
- // MySQL
- $dsn = array(
- 'phptype' => 'mysql',
- 'username' => $CONFIG_DBUSER,
- 'password' => $CONFIG_DBPASSWORD,
- 'hostspec' => $CONFIG_DBHOST,
- 'database' => $CONFIG_DBNAME );
+ switch($type){
+ case 'sqlite':
+ case 'sqlite3':
+ $dsn = array(
+ 'phptype' => $type,
+ 'database' => "$datadir/$name.db",
+ 'mode' => '0644'
+ );
+ break;
+ case 'mysql':
+ $dsn = array(
+ 'phptype' => 'mysql',
+ 'username' => $user,
+ 'password' => $pass,
+ 'hostspec' => $host,
+ 'database' => $name
+ );
+ break;
+ case 'pgsql':
+ $dsn = array(
+ 'phptype' => 'pgsql',
+ 'username' => $user,
+ 'password' => $pass,
+ 'hostspec' => $host,
+ 'database' => $name
+ );
+ break;
}
- elseif( $CONFIG_DBTYPE == 'pgsql' ){
- // PostgreSQL
- $dsn = array(
- 'phptype' => 'pgsql',
- 'username' => $CONFIG_DBUSER,
- 'password' => $CONFIG_DBPASSWORD,
- 'hostspec' => $CONFIG_DBHOST,
- 'database' => $CONFIG_DBNAME );
- }
-
+
// Try to establish connection
- self::$DBConnection = MDB2::factory( $dsn, $options );
-
+ self::$MDB2 = MDB2::factory( $dsn, $options );
+
// Die if we could not connect
- if( PEAR::isError( self::$DBConnection )){
- echo( '<b>can not connect to database, using '.$CONFIG_DBTYPE.'. ('.self::$DBConnection->getUserInfo().')</center>');
- $error = self::$DBConnection->getMessage();
- if(defined("DEBUG") && DEBUG) {error_log( $error);}
- if(defined("DEBUG") && DEBUG) {error_log( self::$DBConnection->getUserInfo());}
+ if( PEAR::isError( self::$MDB2 )){
+ echo( '<b>can not connect to database, using '.$type.'. ('.self::$MDB2->getUserInfo().')</center>');
+ OC_Log::write('core',self::$MDB2->getUserInfo(),OC_Log::FATAL);
+ OC_Log::write('core',self::$MDB2->getMessage(),OC_Log::FATAL);
die( $error );
}
-
+
// 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');
+ self::$MDB2->setFetchMode(MDB2_FETCHMODE_ASSOC);
}
-
+
// we are done. great!
return true;
}
/**
- * @brief SQL query
- * @param $query Query string
- * @returns result as MDB2_Result
- *
- * SQL query via MDB2 query()
- */
- static public function query( $query ){
- // Optimize the query
- $query = self::processQuery( $query );
-
- self::connect();
- //fix differences between sql versions
-
- // return the result
- $result = self::$DBConnection->exec( $query );
-
- // Die if we have an error (error means: bad query, not 0 results!)
- if( PEAR::isError($result)) {
- $entry = 'DB Error: "'.$result->getMessage().'"<br />';
- $entry .= 'Offending command was: '.$query.'<br />';
- if(defined("DEBUG") && DEBUG) {error_log( $entry );}
- die( $entry );
- }
-
- return $result;
- }
-
- /**
* @brief Prepare a SQL query
* @param $query Query string
* @returns prepared SQL query
@@ -149,21 +212,33 @@ class OC_DB {
self::connect();
// return the result
- $result = self::$DBConnection->prepare( $query );
-
- // Die if we have an error (error means: bad query, not 0 results!)
- if( PEAR::isError($result)) {
- $entry = 'DB Error: "'.$result->getMessage().'"<br />';
- $entry .= 'Offending command was: '.$query.'<br />';
- if(defined("DEBUG") && DEBUG) {error_log( $entry );}
- die( $entry );
+ if(self::$backend==self::BACKEND_MDB2){
+ $result = self::$connection->prepare( $query );
+
+ // Die if we have an error (error means: bad query, not 0 results!)
+ if( PEAR::isError($result)) {
+ $entry = 'DB Error: "'.$result->getMessage().'"<br />';
+ $entry .= 'Offending command was: '.$query.'<br />';
+ OC_Log::write('core',$entry,OC_Log::FATAL);
+ die( $entry );
+ }
+ }else{
+ try{
+ $result=self::$connection->prepare($query);
+ }catch(PDOException $e){
+ $entry = 'DB Error: "'.$e->getMessage().'"<br />';
+ $entry .= 'Offending command was: '.$query.'<br />';
+ OC_Log::write('core',$entry,OC_Log::FATAL);
+ die( $entry );
+ }
+ $result=new PDOStatementWrapper($result);
}
-
return $result;
}
/**
* @brief gets last value of autoincrement
+ * @param $table string The optional table name (will replace *PREFIX*) and add sequence suffix
* @returns id
*
* MDB2 lastInsertID()
@@ -171,9 +246,14 @@ class OC_DB {
* Call this method right after the insert command or other functions may
* cause trouble!
*/
- public static function insertid(){
+ public static function insertid($table=null){
self::connect();
- return self::$DBConnection->lastInsertID();
+ if($table !== null){
+ $prefix = OC_Config::getValue( "dbtableprefix", "oc_" );
+ $suffix = OC_Config::getValue( "dbsequencesuffix", "_id_seq" );
+ $table = str_replace( '*PREFIX*', $prefix, $table );
+ }
+ return self::$connection->lastInsertId($table.$suffix);
}
/**
@@ -184,34 +264,26 @@ class OC_DB {
*/
public static function disconnect(){
// Cut connection if required
- if(self::$DBConnection){
- self::$DBConnection->disconnect();
- self::$DBConnection=false;
+ if(self::$connection){
+ if(self::$backend==self::BACKEND_MDB2){
+ self::$connection->disconnect();
+ }
+ self::$connection=false;
+ self::$MDB2=false;
+ self::$PDO=false;
}
return true;
}
/**
- * @brief Escapes bad characters
- * @param $string string with dangerous characters
- * @returns escaped string
- *
- * MDB2 escape()
- */
- public static function escape( $string ){
- self::connect();
- return self::$DBConnection->escape( $string );
- }
-
- /**
* @brief saves database scheme to xml file
* @param $file name of file
* @returns true/false
*
* TODO: write more documentation
*/
- public static function getDbStructure( $file ){
+ public static function getDbStructure( $file ,$mode=MDB2_SCHEMA_DUMP_STRUCTURE){
self::connectScheme();
// write the scheme
@@ -221,7 +293,7 @@ class OC_DB {
'output' => $file,
'end_of_line' => "\n"
);
- self::$schema->dumpDatabase( $definition, $dump_options, MDB2_SCHEMA_DUMP_STRUCTURE );
+ self::$schema->dumpDatabase( $definition, $dump_options, $mode );
return true;
}
@@ -244,10 +316,10 @@ class OC_DB {
$content = file_get_contents( $file );
// Make changes and save them to a temporary file
- $file2 = tempnam( sys_get_temp_dir(), 'oc_db_scheme_' );
+ $file2 = tempnam( get_temp_dir(), 'oc_db_scheme_' );
$content = str_replace( '*dbname*', $CONFIG_DBNAME, $content );
$content = str_replace( '*dbprefix*', $CONFIG_DBTABLEPREFIX, $content );
- if( $CONFIG_DBTYPE == 'pgsql' ){ //mysql support it too but sqlite don't
+ if( $CONFIG_DBTYPE == 'pgsql' ){ //mysql support it too but sqlite doesn't
$content = str_replace( '<default>0000-00-00 00:00:00</default>', '<default>CURRENT_TIMESTAMP</default>', $content );
}
file_put_contents( $file2, $content );
@@ -274,6 +346,47 @@ class OC_DB {
return true;
}
+
+ /**
+ * @brief update the database scheme
+ * @param $file file to read structure from
+ */
+ public static function updateDbFromStructure($file){
+ $CONFIG_DBTABLEPREFIX = OC_Config::getValue( "dbtableprefix", "oc_" );
+ $CONFIG_DBTYPE = OC_Config::getValue( "dbtype", "sqlite" );
+
+ self::connectScheme();
+
+ // read file
+ $content = file_get_contents( $file );
+
+ $previousSchema = self::$schema->getDefinitionFromDatabase();
+ if (PEAR::isError($previousSchema)) {
+ $error = $previousSchema->getMessage();
+ OC_Log::write('core','Failed to get existing database structure for upgrading ('.$error.')',OC_Log::FATAL);
+ return false;
+ }
+
+ // Make changes and save them to a temporary file
+ $file2 = tempnam( get_temp_dir(), 'oc_db_scheme_' );
+ $content = str_replace( '*dbname*', $previousSchema['name'], $content );
+ $content = str_replace( '*dbprefix*', $CONFIG_DBTABLEPREFIX, $content );
+ if( $CONFIG_DBTYPE == 'pgsql' ){ //mysql support it too but sqlite doesn't
+ $content = str_replace( '<default>0000-00-00 00:00:00</default>', '<default>CURRENT_TIMESTAMP</default>', $content );
+ }
+ file_put_contents( $file2, $content );
+ $op = self::$schema->updateDatabase($file2, $previousSchema, array(), false);
+
+ // Delete our temporary file
+ unlink( $file2 );
+
+ if (PEAR::isError($op)) {
+ $error = $op->getMessage();
+ OC_Log::write('core','Failed to update database structure ('.$error.')',OC_Log::FATAL);
+ return false;
+ }
+ return true;
+ }
/**
* @brief connects to a MDB2 database scheme
@@ -282,13 +395,15 @@ class OC_DB {
* Connects to a MDB2 database scheme
*/
private static function connectScheme(){
- // We need a database connection
- self::connect();
+ // We need a mdb2 database connection
+ self::connectMDB2();
+ self::$MDB2->loadModule('Manager');
+ self::$MDB2->loadModule('Reverse');
// Connect if this did not happen before
if(!self::$schema){
require_once('MDB2/Schema.php');
- self::$schema=MDB2_Schema::factory(self::$DBConnection);
+ self::$schema=MDB2_Schema::factory(self::$MDB2);
}
return true;
@@ -305,23 +420,25 @@ class OC_DB {
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
- $query = str_replace( 'NOW()', self::$DBConnection->now(), $query );
- $query = str_replace( 'now()', self::$DBConnection->now(), $query );
+ $type = OC_Config::getValue( "dbtype", "sqlite" );
+ $prefix = OC_Config::getValue( "dbtableprefix", "oc_" );
// differences in escaping of table names ('`' for mysql) and getting the current timestamp
- if( $CONFIG_DBTYPE == 'sqlite' || $CONFIG_DBTYPE == 'sqlite3' ){
+ if( $type == 'sqlite' || $type == 'sqlite3' ){
$query = str_replace( '`', '\'', $query );
- }
- elseif( $CONFIG_DBTYPE == 'pgsql' ){
+ $query = str_replace( 'NOW()', 'datetime(\'now\')', $query );
+ $query = str_replace( 'now()', 'datetime(\'now\')', $query );
+ }elseif( $type == 'mysql' ){
+ $query = str_replace( 'NOW()', 'CURRENT_TIMESTAMP', $query );
+ $query = str_replace( 'now()', 'CURRENT_TIMESTAMP', $query );
+ }elseif( $type == 'pgsql' ){
$query = str_replace( '`', '"', $query );
+ $query = str_replace( 'NOW()', 'CURRENT_TIMESTAMP', $query );
+ $query = str_replace( 'now()', 'CURRENT_TIMESTAMP', $query );
}
// replace table name prefix
- $query = str_replace( '*PREFIX*', $CONFIG_DBTABLEPREFIX, $query );
+ $query = str_replace( '*PREFIX*', $prefix, $query );
return $query;
}
@@ -331,9 +448,9 @@ class OC_DB {
* @param string $tableNamme the table to drop
*/
public static function dropTable($tableName){
- self::connect();
- self::$DBConnection->loadModule('Manager');
- self::$DBConnection->dropTable($tableName);
+ self::connectMDB2();
+ self::$MDB2->loadModule('Manager');
+ self::$MDB2->dropTable($tableName);
}
/**
@@ -349,7 +466,7 @@ class OC_DB {
$content = file_get_contents( $file );
// Make changes and save them to a temporary file
- $file2 = tempnam( sys_get_temp_dir(), 'oc_db_scheme_' );
+ $file2 = tempnam( 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 );
@@ -365,37 +482,85 @@ class OC_DB {
}
/**
- * Start a transaction or set a savepoint.
- * @param string $savePoint (optional) name of the savepoint to set
+ * Start a transaction
*/
- public static function beginTransaction($savePoint=''){
+ public static function beginTransaction(){
self::connect();
- if (!self::$DBConnection->supports('transactions')) {
+ if (self::$backend=self::BACKEND_MDB2 && !self::$connection->supports('transactions')) {
return false;
}
- if($savePoint && !self::$DBConnection->supports('savepoints')){
- return false;
- }
- if($savePoint){
- self::$DBConnection->beginTransaction($savePoint);
- }else{
- self::$DBConnection->beginTransaction();
- }
+ self::$connection->beginTransaction();
}
/**
- * Commit the database changes done during a transaction that is in progress or release a savepoint.
- * @param string $savePoint (optional) name of the savepoint to commit
+ * Commit the database changes done during a transaction that is in progress
*/
public static function commit($savePoint=''){
self::connect();
- if(!self::$DBConnection->inTransaction()){
+ if(!self::$connection->inTransaction()){
return false;
}
- if($savePoint){
- self::$DBConnection->commit($savePoint);
+ self::$connection->commit();
+ }
+}
+
+/**
+ * small wrapper around PDOStatement to make it behave ,more like an MDB2 Statement
+ */
+class PDOStatementWrapper{
+ private $statement=null;
+ private $lastArguments=array();
+
+ public function __construct($statement){
+ $this->statement=$statement;
+ }
+
+ /**
+ * make execute return the result instead of a bool
+ */
+ public function execute($input=array()){
+ $this->lastArguments=$input;
+ if(count($input)>0){
+ $this->statement->execute($input);
+ }else{
+ $this->statement->execute();
+ }
+ return $this;
+ }
+
+ /**
+ * provide numRows
+ */
+ public function numRows(){
+ $regex = '/^SELECT\s+(?:ALL\s+|DISTINCT\s+)?(?:.*?)\s+FROM\s+(.*)$/i';
+ if (preg_match($regex, $this->statement->queryString, $output) > 0) {
+ $query = OC_DB::prepare("SELECT COUNT(*) FROM {$output[1]}", PDO::FETCH_NUM);
+ return $query->execute($this->lastArguments)->fetchColumn();
}else{
- self::$DBConnection->commit();
+ return $this->statement->rowCount();
}
}
+
+ /**
+ * provide an alias for fetch
+ */
+ public function fetchRow(){
+ return $this->statement->fetch();
+ }
+
+ /**
+ * pass all other function directly to the PDOStatement
+ */
+ public function __call($name,$arguments){
+ return call_user_func_array(array($this->statement,$name),$arguments);
+ }
+
+ /**
+ * Provide a simple fetchOne.
+ * fetch single column from the next row
+ * @param int $colnum the column number to fetch
+ */
+ public function fetchOne($colnum = 0){
+ return $this->statement->fetchColumn($colnum);
+ }
}
diff --git a/lib/files.php b/lib/files.php
index 631726bf9b5..9ae5320ad1d 100644
--- a/lib/files.php
+++ b/lib/files.php
@@ -91,7 +91,7 @@ class OC_Files {
if(is_array($files)){
$zip = new ZipArchive();
- $filename = sys_get_temp_dir()."/ownCloud.zip";
+ $filename = get_temp_dir()."/ownCloud.zip";
if ($zip->open($filename, ZIPARCHIVE::CREATE)!==TRUE) {
exit("cannot open <$filename>\n");
}
@@ -108,7 +108,7 @@ class OC_Files {
$zip->close();
}elseif(OC_Filesystem::is_dir($dir.'/'.$files)){
$zip = new ZipArchive();
- $filename = sys_get_temp_dir()."/ownCloud.zip";
+ $filename = get_temp_dir()."/ownCloud.zip";
if ($zip->open($filename, ZIPARCHIVE::CREATE)!==TRUE) {
exit("cannot open <$filename>\n");
}
@@ -183,8 +183,8 @@ class OC_Files {
*/
public static function move($sourceDir,$source,$targetDir,$target){
if(OC_User::isLoggedIn()){
- $targetFile=$targetDir.'/'.$target;
- $sourceFile=$sourceDir.'/'.$source;
+ $targetFile=self::normalizePath($targetDir.'/'.$target);
+ $sourceFile=self::normalizePath($sourceDir.'/'.$source);
return OC_Filesystem::rename($sourceFile,$targetFile);
}
}
@@ -271,7 +271,7 @@ class OC_Files {
* @return string guessed mime type
*/
static function pull($source,$token,$dir,$file){
- $tmpfile=tempnam(sys_get_temp_dir(),'remoteCloudFile');
+ $tmpfile=tempnam(get_temp_dir(),'remoteCloudFile');
$fp=fopen($tmpfile,'w+');
$url=$source.="/files/pull.php?token=$token";
$ch=curl_init();
@@ -305,4 +305,19 @@ class OC_Files {
$content.= "Options -Indexes\n";
@file_put_contents(OC::$SERVERROOT.'/.htaccess', $content); //supress errors in case we don't have permissions for it
}
+
+ /**
+ * normalize a path, removing any double, add leading /, etc
+ * @param string $path
+ * @return string
+ */
+ static public function normalizePath($path){
+ $path='/'.$path;
+ $old='';
+ while($old!=$path){//replace any multiplicity of slashes with a single one
+ $old=$path;
+ $path=str_replace('//','/',$path);
+ }
+ return $path;
+ }
}
diff --git a/lib/filestorage/local.php b/lib/filestorage/local.php
index d1fe87ec4c2..e846aa420e4 100644
--- a/lib/filestorage/local.php
+++ b/lib/filestorage/local.php
@@ -38,7 +38,7 @@ class OC_Filestorage_Local extends OC_Filestorage{
public function filetype($path){
$filetype=filetype($this->datadir.$path);
if($filetype=='link'){
- $filetype=filetype(readlink($this->datadir.$path));
+ $filetype=filetype(realpath($this->datadir.$path));
}
return $filetype;
}
@@ -53,7 +53,7 @@ class OC_Filestorage_Local extends OC_Filestorage{
return is_readable($this->datadir.$path);
}
public function is_writeable($path){
- return is_writeable($this->datadir.$path);
+ return is_writable($this->datadir.$path);
}
public function file_exists($path){
return file_exists($this->datadir.$path);
@@ -84,6 +84,11 @@ class OC_Filestorage_Local extends OC_Filestorage{
return $return;
}
public function rename($path1,$path2){
+ if(! $this->file_exists($path1)){
+ OC_Log::write('core','unable to rename, file does not exists : '.$path1,OC_Log::ERROR);
+ return false;
+ }
+
if($return=rename($this->datadir.$path1,$this->datadir.$path2)){
$this->clearFolderSizeCache($path1);
$this->clearFolderSizeCache($path2);
@@ -127,6 +132,13 @@ class OC_Filestorage_Local extends OC_Filestorage{
public function getMimeType($fspath){
if($this->is_readable($fspath)){
$mimeType='application/octet-stream';
+ if ($mimeType=='application/octet-stream') {
+ self::$mimetypes = include('mimetypes.fixlist.php');
+ $extention=strtolower(strrchr(basename($fspath), "."));
+ $extention=substr($extention,1);//remove leading .
+ $mimeType=(isset(self::$mimetypes[$extention]))?self::$mimetypes[$extention]:'application/octet-stream';
+
+ }
if (@is_dir($this->datadir.$fspath)) {
// directories are easy
return "httpd/unix-directory";
@@ -153,7 +165,7 @@ class OC_Filestorage_Local extends OC_Filestorage{
}
if ($mimeType=='application/octet-stream') {
// Fallback solution: (try to guess the type by the file extension
- if(!self::$mimetypes){
+ if(!self::$mimetypes || self::$mimetypes != include('mimetypes.list.php')){
self::$mimetypes=include('mimetypes.list.php');
}
$extention=strtolower(strrchr(basename($fspath), "."));
@@ -165,7 +177,7 @@ class OC_Filestorage_Local extends OC_Filestorage{
}
public function toTmpFile($path){
- $tmpFolder=sys_get_temp_dir();
+ $tmpFolder=get_temp_dir();
$filename=tempnam($tmpFolder,'OC_TEMP_FILE_'.substr($path,strrpos($path,'.')));
$fileStats = stat($this->datadir.$path);
if(copy($this->datadir.$path,$filename)){
@@ -199,7 +211,6 @@ class OC_Filestorage_Local extends OC_Filestorage{
}
private function delTree($dir) {
- if(defined("DEBUG") && DEBUG) {error_log('del'.$dir);}
$dirRelative=$dir;
$dir=$this->datadir.$dir;
if (!file_exists($dir)) return true;
diff --git a/lib/filestorage/remote.php b/lib/filestorage/remote.php
index fb14c4121a2..88bdbca481c 100644
--- a/lib/filestorage/remote.php
+++ b/lib/filestorage/remote.php
@@ -211,7 +211,7 @@ class OC_Filestorage_Remote extends OC_Filestorage{
$parent=dirname($path);
$name=substr($path,strlen($parent)+1);
$file=$this->remote->getFile($parent,$name);
- $file=tempnam(sys_get_temp_dir(),'oc_');
+ $file=tempnam(get_temp_dir(),'oc_');
file_put_contents($file,$data);
if($return=$this->remote->sendTmpFile($file,$parent,$name)){
$this->notifyObservers($path,OC_FILEACTION_WRITE);
diff --git a/lib/filesystem.php b/lib/filesystem.php
index 3d0c92e622e..bd953deb210 100644
--- a/lib/filesystem.php
+++ b/lib/filesystem.php
@@ -44,10 +44,96 @@
*/
class OC_Filesystem{
static private $storages=array();
+ static private $mounts=array();
static private $fakeRoot='';
static private $storageTypes=array();
+
+ /**
+ * classname which used for hooks handling
+ * used as signalclass in OC_Hooks::emit()
+ */
+ const CLASSNAME = 'OC_Filesystem';
+
+ /**
+ * signalname emited before file renaming
+ * @param oldpath
+ * @param newpath
+ */
+ const signal_rename = 'rename';
+
+ /**
+ * signal emited after file renaming
+ * @param oldpath
+ * @param newpath
+ */
+ const signal_post_rename = 'post_rename';
+ /**
+ * signal emited before file/dir creation
+ * @param path
+ * @param run changing this flag to false in hook handler will cancel event
+ */
+ const signal_create = 'create';
+
+ /**
+ * signal emited after file/dir creation
+ * @param path
+ * @param run changing this flag to false in hook handler will cancel event
+ */
+ const signal_post_create = 'post_create';
+
+ /**
+ * signal emits before file/dir copy
+ * @param oldpath
+ * @param newpath
+ * @param run changing this flag to false in hook handler will cancel event
+ */
+ const signal_copy = 'copy';
+
+ /**
+ * signal emits after file/dir copy
+ * @param oldpath
+ * @param newpath
+ */
+ const signal_post_copy = 'post_copy';
+
+ /**
+ * signal emits before file/dir save
+ * @param path
+ * @param run changing this flag to false in hook handler will cancel event
+ */
+ const signal_write = 'write';
+
+ /**
+ * signal emits after file/dir save
+ * @param path
+ */
+ const signal_post_write = 'post_write';
+ /**
+ * signal emits when reading file/dir
+ * @param path
+ */
+ const signal_read = 'read';
+
+ /**
+ * signal emits when removing file/dir
+ * @param path
+ */
+ const signal_delete = 'delete';
+
+ /**
+ * parameters definitions for signals
+ */
+ const signal_param_path = 'path';
+ const signal_param_oldpath = 'oldpath';
+ const signal_param_newpath = 'newpath';
+
+ /**
+ * run - changing this flag to false in hook handler will cancel event
+ */
+ const signal_param_run = 'run';
+
/**
* register a storage type
* @param string type
@@ -91,7 +177,7 @@ class OC_Filesystem{
* @param array arguments
* @return OC_Filestorage
*/
- static public function createStorage($type,$arguments){
+ static private function createStorage($type,$arguments){
if(!self::hasStorageType($type)){
return false;
}
@@ -130,44 +216,26 @@ class OC_Filesystem{
}
/**
- * check if the current users has the right premissions to read a file
- * @param string path
- * @return bool
- */
- static private function canRead($path){
- if(substr($path,0,1)!=='/'){
- $path='/'.$path;
- }
- if(strstr($path,'/../') || strrchr($path, '/') === '/..' ){
- return false;
- }
- return true;//dummy untill premissions are correctly implemented, also the correcty value because for now users are locked in their seperate data dir and can read/write everything in there
- }
- /**
- * check if the current users has the right premissions to write a file
- * @param string path
- * @return bool
- */
- static private function canWrite($path){
- if(substr($path,0,1)!=='/'){
- $path='/'.$path;
- }
- if(strstr($path,'/../') || strrchr($path, '/') === '/..' ){
- return false;
- }
- return true;//dummy untill premissions are correctly implemented, also the correcty value because for now users are locked in their seperate data dir and can read/write everything in there
- }
-
- /**
* mount an OC_Filestorage in our virtual filesystem
* @param OC_Filestorage storage
* @param string mountpoint
*/
- static public function mount($storage,$mountpoint){
+ static public function mount($type,$arguments,$mountpoint){
if(substr($mountpoint,0,1)!=='/'){
$mountpoint='/'.$mountpoint;
}
- self::$storages[self::$fakeRoot.$mountpoint]=$storage;
+ self::$mounts[$mountpoint]=array('type'=>$type,'arguments'=>$arguments);
+ }
+
+ /**
+ * create all storage backends mounted in the filesystem
+ */
+ static private function mountAll(){
+ foreach(self::$mounts as $mountPoint=>$mount){
+ if(!isset(self::$storages[$mountPoint])){
+ self::$storages[$mountPoint]=self::createStorage($mount['type'],$mount['arguments']);
+ }
+ }
}
/**
@@ -178,6 +246,10 @@ class OC_Filesystem{
static public function getStorage($path){
$mountpoint=self::getMountPoint($path);
if($mountpoint){
+ if(!isset(self::$storages[$mountpoint])){
+ $mount=self::$mounts[$mountpoint];
+ self::$storages[$mountpoint]=self::createStorage($mount['type'],$mount['arguments']);
+ }
return self::$storages[$mountpoint];
}
}
@@ -201,7 +273,7 @@ class OC_Filesystem{
}
$path=self::$fakeRoot.$path;
$foundMountPoint='';
- foreach(self::$storages as $mountpoint=>$storage){
+ foreach(self::$mounts as $mountpoint=>$storage){
if(substr($mountpoint,-1)!=='/'){
$mountpoint=$mountpoint.'/';
}
@@ -223,11 +295,26 @@ class OC_Filesystem{
*/
static public function getLocalFile($path){
$parent=substr($path,0,strrpos($path,'/'));
- if(self::canRead($parent) and $storage=self::getStorage($path)){
+ if(self::isValidPath($parent) and $storage=self::getStorage($path)){
return $storage->getLocalFile(self::getInternalPath($path));
}
}
+ /**
+ * check if the requested path is valid
+ * @param string path
+ * @return bool
+ */
+ static public function isValidPath($path){
+ if(substr($path,0,1)!=='/'){
+ $path='/'.$path;
+ }
+ if(strstr($path,'/../') || strrchr($path, '/') === '/..' ){
+ return false;
+ }
+ return true;
+ }
+
static public function mkdir($path){
return self::basicOperation('mkdir',$path,array('create','write'));
}
@@ -292,9 +379,9 @@ class OC_Filesystem{
return self::basicOperation('unlink',$path,array('delete'));
}
static public function rename($path1,$path2){
- if(OC_FileProxy::runPreProxies('rename',$path1,$path2) and self::canWrite($path1) and self::canWrite($path2)){
+ if(OC_FileProxy::runPreProxies('rename',$path1,$path2) and self::is_writeable($path1) and self::isValidPath($path2)){
$run=true;
- OC_Hook::emit( 'OC_Filesystem', 'rename', array( 'oldpath' => $path1 ,'newpath'=>$path2, 'run' => &$run));
+ OC_Hook::emit( self::CLASSNAME, self::signal_rename, array( self::signal_param_oldpath => $path1 , self::signal_param_newpath=>$path2, self::signal_param_run => &$run));
if($run){
$mp1=self::getMountPoint($path1);
$mp2=self::getMountPoint($path2);
@@ -307,21 +394,21 @@ class OC_Filesystem{
$result=$storage2->fromTmpFile($tmpFile,self::getInternalPath($path2));
$storage1->unlink(self::getInternalPath($path1));
}
- OC_Hook::emit( 'OC_Filesystem', 'post_rename', array( 'oldpath' => $path1, 'newpath'=>$path2));
+ OC_Hook::emit( self::CLASSNAME, self::signal_post_rename, array( self::signal_param_oldpath => $path1, self::signal_param_newpath=>$path2));
return $result;
}
}
}
static public function copy($path1,$path2){
- if(OC_FileProxy::runPreProxies('copy',$path1,$path2) and self::canRead($path1) and self::canWrite($path2)){
+ if(OC_FileProxy::runPreProxies('copy',$path1,$path2) and self::is_readable($path1) and self::isValidPath($path2)){
$run=true;
- OC_Hook::emit( 'OC_Filesystem', 'copy', array( 'oldpath' => $path1 ,'newpath'=>$path2, 'run' => &$run));
+ OC_Hook::emit( self::CLASSNAME, self::signal_copy, array( self::signal_param_oldpath => $path1 , self::signal_param_newpath=>$path2, self::signal_param_run => &$run));
$exists=self::file_exists($path2);
if($run and !$exists){
- OC_Hook::emit( 'OC_Filesystem', 'create', array( 'path' => $path2, 'run' => &$run));
+ OC_Hook::emit( self::CLASSNAME, self::signal_create, array( self::signal_param_path => $path2, self::signal_param_run => &$run));
}
if($run){
- OC_Hook::emit( 'OC_Filesystem', 'write', array( 'path' => $path2, 'run' => &$run));
+ OC_Hook::emit( self::CLASSNAME, self::signal_write, array( self::signal_param_path => $path2, self::signal_param_run => &$run));
}
if($run){
$mp1=self::getMountPoint($path1);
@@ -334,11 +421,11 @@ class OC_Filesystem{
$tmpFile=$storage1->toTmpFile(self::getInternalPath($path1));
$result=$storage2->fromTmpFile($tmpFile,self::getInternalPath($path2));
}
- OC_Hook::emit( 'OC_Filesystem', 'post_copy', array( 'oldpath' => $path1 ,'newpath'=>$path2));
+ OC_Hook::emit( self::CLASSNAME, self::signal_post_copy, array( self::signal_param_oldpath => $path1 , self::signal_param_newpath=>$path2));
if(!$exists){
- OC_Hook::emit( 'OC_Filesystem', 'post_create', array( 'path' => $path2));
+ OC_Hook::emit( self::CLASSNAME, self::signal_post_create, array( self::signal_param_path => $path2));
}
- OC_Hook::emit( 'OC_Filesystem', 'post_write', array( 'path' => $path2));
+ OC_Hook::emit( self::CLASSNAME, self::signal_post_write, array( self::signal_param_path => $path2));
return $result;
}
}
@@ -368,47 +455,47 @@ class OC_Filesystem{
return self::basicOperation('fopen',$path,$hooks,$mode);
}
static public function toTmpFile($path){
- if(OC_FileProxy::runPreProxies('toTmpFile',$path) and self::canRead($path) and $storage=self::getStorage($path)){
- OC_Hook::emit( 'OC_Filesystem', 'read', array( 'path' => $path));
+ if(OC_FileProxy::runPreProxies('toTmpFile',$path) and self::isValidPath($path) and $storage=self::getStorage($path)){
+ OC_Hook::emit( self::CLASSNAME, self::signal_read, array( self::signal_param_path => $path));
return $storage->toTmpFile(self::getInternalPath($path));
}
}
static public function fromTmpFile($tmpFile,$path){
- if(OC_FileProxy::runPreProxies('copy',$tmpFile,$path) and self::canWrite($path) and $storage=self::getStorage($path)){
+ if(OC_FileProxy::runPreProxies('copy',$tmpFile,$path) and self::isValidPath($path) and $storage=self::getStorage($path)){
$run=true;
$exists=self::file_exists($path);
if(!$exists){
- OC_Hook::emit( 'OC_Filesystem', 'create', array( 'path' => $path, 'run' => &$run));
+ OC_Hook::emit( self::CLASSNAME, self::signal_create, array( self::signal_param_path => $path, self::signal_param_run => &$run));
}
if($run){
- OC_Hook::emit( 'OC_Filesystem', 'write', array( 'path' => $path, 'run' => &$run));
+ OC_Hook::emit( self::CLASSNAME, self::signal_write, array( self::signal_param_path => $path, self::signal_param_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( self::CLASSNAME, self::signal_post_create, array( self::signal_param_path => $path));
}
- OC_Hook::emit( 'OC_Filesystem', 'post_write', array( 'path' => $path));
+ OC_Hook::emit( self::CLASSNAME, self::signal_post_write, array( self::signal_param_path => $path));
return $result;
}
}
}
static public function fromUploadedFile($tmpFile,$path){
- if(OC_FileProxy::runPreProxies('fromUploadedFile',$tmpFile,$path) and self::canWrite($path) and $storage=self::getStorage($path)){
+ if(OC_FileProxy::runPreProxies('fromUploadedFile',$tmpFile,$path) and self::isValidPath($path) and $storage=self::getStorage($path)){
$run=true;
$exists=self::file_exists($path);
if(!$exists){
- OC_Hook::emit( 'OC_Filesystem', 'create', array( 'path' => $path, 'run' => &$run));
+ OC_Hook::emit( self::CLASSNAME, self::signal_create, array( self::signal_param_path => $path, self::signal_param_run => &$run));
}
if($run){
- OC_Hook::emit( 'OC_Filesystem', 'write', array( 'path' => $path, 'run' => &$run));
+ OC_Hook::emit( self::CLASSNAME, self::signal_write, array( self::signal_param_path => $path, self::signal_param_run => &$run));
}
if($run){
$result=$storage->fromUploadedFile($tmpFile,self::getInternalPath($path));
if(!$exists){
- OC_Hook::emit( 'OC_Filesystem', 'post_create', array( 'path' => $path));
+ OC_Hook::emit( self::CLASSNAME, self::signal_post_create, array( self::signal_param_path => $path));
}
- OC_Hook::emit( 'OC_Filesystem', 'post_write', array( 'path' => $path));
+ OC_Hook::emit( self::CLASSNAME, self::signal_post_write, array( self::signal_param_path => $path));
return $result;
}
}
@@ -425,6 +512,7 @@ class OC_Filesystem{
}
static public function search($query){
+ self::mountAll();
$files=array();
$fakeRoot=self::$fakeRoot;
$fakeRootLength=strlen($fakeRoot);
@@ -443,6 +531,10 @@ class OC_Filesystem{
return $files;
}
+
+ static public function update_session_file_hash($sessionname,$sessionvalue){
+ $_SESSION[$sessionname] = $sessionvalue;
+ }
/**
* abstraction for running most basic operations
@@ -453,14 +545,14 @@ class OC_Filesystem{
* @return mixed
*/
private static function basicOperation($operation,$path,$hooks=array(),$extraParam=null){
- if(OC_FileProxy::runPreProxies($operation,$path, $extraParam) and self::canRead($path) and $storage=self::getStorage($path)){
+ if(OC_FileProxy::runPreProxies($operation,$path, $extraParam) and self::isValidPath($path) and $storage=self::getStorage($path)){
$interalPath=self::getInternalPath($path);
$run=true;
foreach($hooks as $hook){
if($hook!='read'){
- OC_Hook::emit( 'OC_Filesystem', $hook, array( 'path' => $path, 'run' => &$run));
+ OC_Hook::emit( self::CLASSNAME, $hook, array( self::signal_param_path => $path, self::signal_param_run => &$run));
}else{
- OC_Hook::emit( 'OC_Filesystem', $hook, array( 'path' => $path));
+ OC_Hook::emit( self::CLASSNAME, $hook, array( self::signal_param_path => $path));
}
}
if($run){
@@ -472,7 +564,7 @@ class OC_Filesystem{
$result=OC_FileProxy::runPostProxies($operation,$path,$result);
foreach($hooks as $hook){
if($hook!='read'){
- OC_Hook::emit( 'OC_Filesystem', 'post_'.$hook, array( 'path' => $path));
+ OC_Hook::emit( self::CLASSNAME, 'post_'.$hook, array( self::signal_param_path => $path));
}
}
return $result;
diff --git a/lib/helper.php b/lib/helper.php
index c2a81ba3306..4d1219d78d4 100644
--- a/lib/helper.php
+++ b/lib/helper.php
@@ -56,7 +56,7 @@ class OC_Helper {
if($absolute){
// Checking if the request was made through HTTPS. The last in line is for IIS
- $protocol = isset($_SERVER['HTTPS']) && ($_SERVER['HTTPS']) && ($_SERVER['HTTPS']!='off');
+ $protocol = isset($_SERVER['HTTPS']) && !empty($_SERVER['HTTPS']) && ($_SERVER['HTTPS']!='off');
$urlLinkTo = ($protocol?'https':'http') . '://' . $_SERVER['HTTP_HOST'] . $urlLinkTo;
}
@@ -96,6 +96,12 @@ class OC_Helper {
* Returns the path to the image of this file type.
*/
public static function mimetypeIcon( $mimetype ){
+ $alias=array('application/xml'=>'code/xml');
+// echo $mimetype;
+ if(isset($alias[$mimetype])){
+ $mimetype=$alias[$mimetype];
+// echo $mimetype;
+ }
// Replace slash with a minus
$mimetype = str_replace( "/", "-", $mimetype );
@@ -154,24 +160,25 @@ class OC_Helper {
*/
public static function computerFileSize( $str ){
$bytes = 0;
+ $str=strtolower($str);
$bytes_array = array(
- 'B' => 1,
- 'K' => 1024,
- 'KB' => 1024,
- 'MB' => 1024 * 1024,
- 'M' => 1024 * 1024,
- 'GB' => 1024 * 1024 * 1024,
- 'G' => 1024 * 1024 * 1024,
- 'TB' => 1024 * 1024 * 1024 * 1024,
- 'T' => 1024 * 1024 * 1024 * 1024,
- 'PB' => 1024 * 1024 * 1024 * 1024 * 1024,
- 'P' => 1024 * 1024 * 1024 * 1024 * 1024,
+ 'b' => 1,
+ 'k' => 1024,
+ 'kb' => 1024,
+ 'mb' => 1024 * 1024,
+ 'm' => 1024 * 1024,
+ 'gb' => 1024 * 1024 * 1024,
+ 'g' => 1024 * 1024 * 1024,
+ 'tb' => 1024 * 1024 * 1024 * 1024,
+ 't' => 1024 * 1024 * 1024 * 1024,
+ 'pb' => 1024 * 1024 * 1024 * 1024 * 1024,
+ 'p' => 1024 * 1024 * 1024 * 1024 * 1024,
);
$bytes = floatval($str);
- if (preg_match('#([KMGTP]?B?)$#si', $str, $matches) && !empty($bytes_array[$matches[1]])) {
+ if (preg_match('#([kmgtp]?b?)$#si', $str, $matches) && !empty($bytes_array[$matches[1]])) {
$bytes *= $bytes_array[$matches[1]];
}
diff --git a/lib/hook.php b/lib/hook.php
index b069a7da6c0..83a16106bf0 100644
--- a/lib/hook.php
+++ b/lib/hook.php
@@ -20,7 +20,7 @@ class OC_Hook{
* TODO: write example
*/
static public function connect( $signalclass, $signalname, $slotclass, $slotname ){
- // Cerate the data structure
+ // Create the data structure
if( !array_key_exists( $signalclass, self::$registered )){
self::$registered[$signalclass] = array();
}
diff --git a/lib/image.php b/lib/image.php
new file mode 100644
index 00000000000..6de3ed9104d
--- /dev/null
+++ b/lib/image.php
@@ -0,0 +1,557 @@
+<?php
+
+/**
+* ownCloud
+*
+* @author Thomas Tanghus
+* @copyright 2011 Thomas Tanghus <thomas@tanghus.net>
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+* License as published by the Free Software Foundation; either
+* version 3 of the License, or any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+*
+* You should have received a copy of the GNU Affero General Public
+* License along with this library. If not, see <http://www.gnu.org/licenses/>.
+*
+*/
+
+//From user comments at http://dk2.php.net/manual/en/function.exif-imagetype.php
+if ( ! function_exists( 'exif_imagetype' ) ) {
+ function exif_imagetype ( $filename ) {
+ if ( ( list($width, $height, $type, $attr) = getimagesize( $filename ) ) !== false ) {
+ return $type;
+ }
+ return false;
+ }
+}
+
+function ellipsis($str, $maxlen) {
+ if (strlen($str) > $maxlen) {
+ $characters = floor($maxlen / 2);
+ return substr($str, 0, $characters) . '...' . substr($str, -1 * $characters);
+ }
+ return $str;
+}
+
+/**
+ * Class for basic image manipulation
+ *
+ */
+class OC_Image {
+ static private $resource = false; // tmp resource.
+ static private $destroy = false; // if the resource is created withing the object.
+ static private $imagetype = IMAGETYPE_PNG; // Default to png if file type isn't evident.
+ static private $filepath = null;
+ /**
+ * @brief Constructor.
+ * @param $imageref The path to a local file, a base64 encoded string or a resource created by an imagecreate* function.
+ * If a resource is passed it is the job of the caller to destroy it using imagedestroy($var)
+ * @returns bool False on error
+ */
+ function __construct($imageref = null) {
+ //OC_Log::write('core','OC_Image::__construct, start', OC_Log::DEBUG);
+ if(!extension_loaded('gd') || !function_exists('gd_info')) {
+ //if(!function_exists('imagecreatefromjpeg')) {
+ OC_Log::write('core','OC_Image::__construct, GD module not installed', OC_Log::ERROR);
+ return false;
+ }
+ if(!is_null($imageref)) {
+ self::load($imageref);
+ }
+ }
+
+ /**
+ * @brief Destructor.
+ */
+ function __destruct() {
+ if(is_resource(self::$resource) && self::$destroy) {
+ imagedestroy(self::$resource); // Why does this issue a warning.
+ }
+ }
+
+ /**
+ * @brief Determine whether the object contains an image resource.
+ * @returns bool
+ */
+ public function valid() { // apparently you can't name a method 'empty'...
+ $ret = is_resource(self::$resource);
+ return $ret;
+ }
+
+ /**
+ * @brief Returns the MIME type of the image or an empty string if no image is loaded.
+ * @returns int
+ */
+ public function mimeType() {
+ return is_resource(self::$resource) ? image_type_to_mime_type(self::$imagetype) : '';
+ }
+
+ /**
+ * @brief Returns the width of the image or -1 if no image is loaded.
+ * @returns int
+ */
+ public function width() {
+ return is_resource(self::$resource) ? imagesx(self::$resource) : -1;
+ }
+
+ /**
+ * @brief Returns the height of the image or -1 if no image is loaded.
+ * @returns int
+ */
+ public function height() {
+ return is_resource(self::$resource) ? imagesy(self::$resource) : -1;
+ }
+
+ /**
+ * @brief Outputs the image.
+ * @returns bool
+ */
+ public function show() {
+ return $this->_output();
+ }
+
+ /**
+ * @brief Saves the image.
+ * @returns bool
+ */
+
+ public function save($filepath=null) {
+ if($filepath === null && self::$filepath === null) {
+ OC_Log::write('core','OC_Image::save. save() called with no path.', OC_Log::ERROR);
+ return false;
+ } elseif($filepath === null && $this->filepath !== null) {
+ $filepath = $this->filepath;
+ }
+ return $this->_output($filepath, true);
+ }
+
+ /**
+ * @brief Outputs/saves the image.
+ */
+ private function _output($filepath=null, $really=false) {
+ if($really === false) {
+ header('Content-Type: '.self::mimeType());
+ $filepath = null; // Just being cautious ;-)
+ } else {
+ if(!is_writable(dirname($filepath))) {
+ OC_Log::write('core','OC_Image::_output. Directory \''.dirname($filepath).'\' is not writable.', OC_Log::ERROR);
+ return false;
+ } elseif(is_writable(dirname($filepath)) && file_exists($filepath) && !is_writable($filepath)) {
+ OC_Log::write('core','OC_Image::_output. File \''.$filepath.'\' is not writable.', OC_Log::ERROR);
+ return false;
+ }
+ }
+ $retval = false;
+ switch(self::$imagetype) {
+ case IMAGETYPE_GIF:
+ $retval = imagegif(self::$resource, $filepath);
+ break;
+ case IMAGETYPE_JPEG:
+ $retval = imagejpeg(self::$resource, $filepath);
+ break;
+ case IMAGETYPE_PNG:
+ $retval = imagepng(self::$resource, $filepath);
+ break;
+ case IMAGETYPE_XBM:
+ $retval = imagexbm(self::$resource, $filepath);
+ break;
+ case IMAGETYPE_WBMP:
+ case IMAGETYPE_BMP:
+ $retval = imagewbmp(self::$resource, $filepath);
+ break;
+ default:
+ $retval = imagepng(self::$resource, $filepath);
+ }
+ return $retval;
+ }
+
+ /**
+ * @brief Prints the image when called as $image().
+ */
+ public function __invoke() {
+ return self::show();
+ }
+
+ /**
+ * @returns Returns the image resource in any.
+ */
+ public function resource() {
+ return self::$resource;
+ }
+
+ /**
+ * @returns Returns a base64 encoded string suitable for embedding in a VCard.
+ */
+ function __toString() {
+ ob_start();
+ $res = imagepng(self::$resource);
+ if (!$res) {
+ OC_Log::write('core','OC_Image::_string. Error writing image',OC_Log::ERROR);
+ }
+ return base64_encode(ob_get_clean());
+ }
+
+ /**
+ * (I'm open for suggestions on better method name ;)
+ * @brief Fixes orientation based on EXIF data.
+ * @returns bool.
+ */
+ public function fixOrientation() {
+ if(!is_callable('exif_read_data')){
+ OC_Log::write('core','OC_Image::fixOrientation() Exif module not enabled.', OC_Log::DEBUG);
+ return false;
+ }
+ if(!is_resource(self::$resource)) {
+ OC_Log::write('core','OC_Image::fixOrientation() No image loaded.', OC_Log::DEBUG);
+ return false;
+ }
+ if(is_null(self::$filepath) || !is_readable(self::$filepath)) {
+ OC_Log::write('core','OC_Image::fixOrientation() No readable file path set.', OC_Log::DEBUG);
+ return false;
+ }
+ $exif = exif_read_data(self::$filepath, 'IFD0');
+ if(!$exif) {
+ return false;
+ }
+ if(!isset($exif['Orientation'])) {
+ return true; // Nothing to fix
+ }
+ $o = $exif['Orientation'];
+ OC_Log::write('core','OC_Image::fixOrientation() Orientation: '.$o, OC_Log::DEBUG);
+ $rotate = 0;
+ $flip = false;
+ switch($o) {
+ case 1:
+ $rotate = 0;
+ $flip = false;
+ break;
+ case 2: // Not tested
+ $rotate = 0;
+ $flip = true;
+ break;
+ case 3:
+ $rotate = 180;
+ $flip = false;
+ break;
+ case 4: // Not tested
+ $rotate = 180;
+ $flip = true;
+ break;
+ case 5: // Not tested
+ $rotate = 90;
+ $flip = true;
+ break;
+ case 6:
+ //$rotate = 90;
+ $rotate = 270;
+ $flip = false;
+ break;
+ case 7: // Not tested
+ $rotate = 270;
+ $flip = true;
+ break;
+ case 8:
+ $rotate = 270;
+ $flip = false;
+ break;
+ }
+ if($rotate) {
+ $res = imagerotate(self::$resource, $rotate, -1);
+ if($res) {
+ if(imagealphablending($res, true)) {
+ if(imagesavealpha($res, true)) {
+ self::$resource = $res;
+ return true;
+ } else {
+ OC_Log::write('core','OC_Image::fixOrientation() Error during alphasaving.', OC_Log::DEBUG);
+ return false;
+ }
+ } else {
+ OC_Log::write('core','OC_Image::fixOrientation() Error during alphablending.', OC_Log::DEBUG);
+ return false;
+ }
+ } else {
+ OC_Log::write('core','OC_Image::fixOrientation() Error during oriention fixing.', OC_Log::DEBUG);
+ return false;
+ }
+ }
+ }
+
+ /**
+ * @brief Loads an image from a local file, a base64 encoded string or a resource created by an imagecreate* function.
+ * @param $imageref The path to a local file, a base64 encoded string or a resource created by an imagecreate* function.
+ * If a resource is passed it is the job of the caller to destroy it using imagedestroy($var)
+ * @returns An image resource or false on error
+ */
+ public function load($imageref) {
+ if(self::loadFromFile($imageref) !== false) {
+ return self::$resource;
+ } elseif(self::loadFromBase64($imageref) !== false) {
+ return self::$resource;
+ } elseif(self::loadFromData($imageref) !== false) {
+ return self::$resource;
+ } elseif(self::loadFromResource($imageref) !== false) {
+ return self::$resource;
+ } else {
+ OC_Log::write('core','OC_Image::load, couldn\'t load anything. Giving up!', OC_Log::DEBUG);
+ return false;
+ }
+ }
+
+ /**
+ * @brief Loads an image from a local file.
+ * @param $imageref The path to a local file.
+ * @returns An image resource or false on error
+ */
+ public function loadFromFile($imagepath=false) {
+ if(!is_file($imagepath) || !file_exists($imagepath) || !is_readable($imagepath)) {
+ // Debug output disabled because this method is tried before loadFromBase64?
+ OC_Log::write('core','OC_Image::loadFromFile, couldn\'t load: '.ellipsis($imagepath, 50), OC_Log::DEBUG);
+ return false;
+ }
+ $itype = exif_imagetype($imagepath);
+ switch($itype) {
+ case IMAGETYPE_GIF:
+ if (imagetypes() & IMG_GIF) {
+ self::$resource = imagecreatefromgif($imagepath);
+ } else {
+ OC_Log::write('core','OC_Image::loadFromFile, GIF images not supported: '.$imagepath, OC_Log::DEBUG);
+ }
+ break;
+ case IMAGETYPE_JPEG:
+ if (imagetypes() & IMG_JPG) {
+ self::$resource = imagecreatefromjpeg($imagepath);
+ } else {
+ OC_Log::write('core','OC_Image::loadFromFile, JPG images not supported: '.$imagepath, OC_Log::DEBUG);
+ }
+ break;
+ case IMAGETYPE_PNG:
+ if (imagetypes() & IMG_PNG) {
+ self::$resource = imagecreatefrompng($imagepath);
+ } else {
+ OC_Log::write('core','OC_Image::loadFromFile, PNG images not supported: '.$imagepath, OC_Log::DEBUG);
+ }
+ break;
+ case IMAGETYPE_XBM:
+ if (imagetypes() & IMG_XPM) {
+ self::$resource = imagecreatefromxbm($imagepath);
+ } else {
+ OC_Log::write('core','OC_Image::loadFromFile, XBM/XPM images not supported: '.$imagepath, OC_Log::DEBUG);
+ }
+ break;
+ case IMAGETYPE_WBMP:
+ case IMAGETYPE_BMP:
+ if (imagetypes() & IMG_WBMP) {
+ self::$resource = imagecreatefromwbmp($imagepath);
+ } else {
+ OC_Log::write('core','OC_Image::loadFromFile, (W)BMP images not supported: '.$imagepath, OC_Log::DEBUG);
+ }
+ break;
+ /*
+ case IMAGETYPE_TIFF_II: // (intel byte order)
+ break;
+ case IMAGETYPE_TIFF_MM: // (motorola byte order)
+ break;
+ case IMAGETYPE_JPC:
+ break;
+ case IMAGETYPE_JP2:
+ break;
+ case IMAGETYPE_JPX:
+ break;
+ case IMAGETYPE_JB2:
+ break;
+ case IMAGETYPE_SWC:
+ break;
+ case IMAGETYPE_IFF:
+ break;
+ case IMAGETYPE_ICO:
+ break;
+ case IMAGETYPE_SWF:
+ break;
+ case IMAGETYPE_PSD:
+ break;
+ */
+ default:
+ self::$resource = imagecreatefromstring(file_get_contents($imagepath));
+ $itype = IMAGETYPE_PNG;
+ OC_Log::write('core','OC_Image::loadFromFile, Default', OC_Log::DEBUG);
+ break;
+ }
+ if($this->valid()) {
+ self::$imagetype = $itype;
+ self::$filepath = $imagepath;
+ self::$destroy = true;
+ }
+ return self::$resource;
+ }
+
+ /**
+ * @brief Loads an image from a string of data.
+ * @param $str A string of image data as read from a file.
+ * @returns An image resource or false on error
+ */
+ public function loadFromData($str) {
+ if(is_resource($str)) {
+ return false;
+ }
+ self::$resource = imagecreatefromstring($str);
+ if(!self::$resource) {
+ OC_Log::write('core','OC_Image::loadFromData, couldn\'t load', OC_Log::DEBUG);
+ return false;
+ }
+ self::$destroy = true;
+ return self::$resource;
+ }
+
+ /**
+ * @brief Loads an image from a base64 encoded string.
+ * @param $str A string base64 encoded string of image data.
+ * @returns An image resource or false on error
+ */
+ public function loadFromBase64($str) {
+ if(!is_string($str)) {
+ return false;
+ }
+ $data = base64_decode($str);
+ if($data) { // try to load from string data
+ self::$resource = imagecreatefromstring($data);
+ if(!self::$resource) {
+ OC_Log::write('core','OC_Image::loadFromBase64, couldn\'t load', OC_Log::DEBUG);
+ return false;
+ }
+ self::$destroy = true;
+ return self::$resource;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * @brief Checks if image resource is valid and assigns it to self::$resource.
+ * @param $res An image resource.
+ * @returns An image resource or false on error
+ */
+ public function loadFromResource($res) {
+ if(!is_resource($res)) {
+ return false;
+ }
+ self::$resource = $res;
+ }
+
+ /**
+ * @brief Resizes the image preserving ratio.
+ * @param $maxsize The maximum size of either the width or height.
+ * @returns bool
+ */
+ public function resize($maxsize) {
+ if(!self::$resource) {
+ OC_Log::write('core','OC_Image::resize, No image loaded', OC_Log::ERROR);
+ return false;
+ }
+ $width_orig=imageSX(self::$resource);
+ $height_orig=imageSY(self::$resource);
+ $ratio_orig = $width_orig/$height_orig;
+
+ if ($ratio_orig > 1) {
+ $new_height = round($maxsize/$ratio_orig);
+ $new_width = $maxsize;
+ } else {
+ $new_width = round($maxsize*$ratio_orig);
+ $new_height = $maxsize;
+ }
+
+ $process = imagecreatetruecolor(round($new_width), round($new_height));
+ if ($process == false) {
+ OC_Log::write('core','OC_Image::resize. Error creating true color image',OC_Log::ERROR);
+ imagedestroy($process);
+ return false;
+ }
+
+ imagecopyresampled($process, self::$resource, 0, 0, 0, 0, $new_width, $new_height, $width_orig, $height_orig);
+ if ($process == false) {
+ OC_Log::write('core','OC_Image::resize. Error resampling process image '.$new_width.'x'.$new_height,OC_Log::ERROR);
+ imagedestroy($process);
+ return false;
+ }
+ self::$resource = $process;
+ return true;
+ }
+
+ /**
+ * @brief Crops the image to the middle square. If the image is already square it just returns.
+ * @returns bool for success or failure
+ */
+ public function centerCrop() {
+ if(!self::$resource) {
+ OC_Log::write('core','OC_Image::centerCrop, No image loaded', OC_Log::ERROR);
+ return false;
+ }
+ $width_orig=imageSX(self::$resource);
+ $height_orig=imageSY(self::$resource);
+ if($width_orig === $height_orig) {
+ return true;
+ }
+ $ratio_orig = $width_orig/$height_orig;
+ $width = $height = min($width_orig, $height_orig);
+
+ if ($ratio_orig > 1) {
+ $x = ($width_orig/2) - ($width/2);
+ $y = 0;
+ } else {
+ $y = ($height_orig/2) - ($height/2);
+ $x = 0;
+ }
+ $process = imagecreatetruecolor($width, $height);
+ if ($process == false) {
+ OC_Log::write('core','OC_Image::centerCrop. Error creating true color image',OC_Log::ERROR);
+ imagedestroy($process);
+ return false;
+ }
+ imagecopyresampled($process, self::$resource, 0, 0, $x, $y, $width, $height, $width, $height);
+ if ($process == false) {
+ OC_Log::write('core','OC_Image::centerCrop. Error resampling process image '.$width.'x'.$height,OC_Log::ERROR);
+ imagedestroy($process);
+ return false;
+ }
+ self::$resource = $process;
+ return true;
+ }
+
+ /**
+ * @brief Crops the image from point $x$y with dimension $wx$h.
+ * @param $x Horizontal position
+ * @param $y Vertical position
+ * @param $w Width
+ * @param $h Hight
+ * @returns bool for success or failure
+ */
+ public function crop($x, $y, $w, $h) {
+ if(!self::$resource) {
+ OC_Log::write('core','OC_Image::crop, No image loaded', OC_Log::ERROR);
+ return false;
+ }
+ $width_orig=imageSX(self::$resource);
+ $height_orig=imageSY(self::$resource);
+ //OC_Log::write('core','OC_Image::crop. Original size: '.$width_orig.'x'.$height_orig, OC_Log::DEBUG);
+ $process = imagecreatetruecolor($w, $h);
+ if ($process == false) {
+ OC_Log::write('core','OC_Image::crop. Error creating true color image',OC_Log::ERROR);
+ imagedestroy($process);
+ return false;
+ }
+ imagecopyresampled($process, self::$resource, 0, 0, $x, $y, $w, $h, $w, $h);
+ if ($process == false) {
+ OC_Log::write('core','OC_Image::crop. Error resampling process image '.$w.'x'.$h,OC_Log::ERROR);
+ imagedestroy($process);
+ return false;
+ }
+ self::$resource = $process;
+ return true;
+ }
+}
diff --git a/lib/installer.php b/lib/installer.php
index 0febb2cab46..b2f817e702f 100644
--- a/lib/installer.php
+++ b/lib/installer.php
@@ -56,28 +56,28 @@ class OC_Installer{
*/
public static function installApp( $data = array()){
if(!isset($data['source'])){
- if(defined("DEBUG") && DEBUG) {error_log("No source specified when installing app");}
+ OC_Log::write('core','No source specified when installing app',OC_Log::ERROR);
return false;
}
//download the file if necesary
if($data['source']=='http'){
- $path=tempnam(sys_get_temp_dir(),'oc_installer_');
+ $path=tempnam(get_temp_dir(),'oc_installer_');
if(!isset($data['href'])){
- if(defined("DEBUG") && DEBUG) {error_log("No href specified when installing app from http");}
+ OC_Log::write('core','No href specified when installing app from http',OC_Log::ERROR);
return false;
}
copy($data['href'],$path);
}else{
if(!isset($data['path'])){
- if(defined("DEBUG") && DEBUG) {error_log("No path specified when installing app from local file");}
+ OC_Log::write('core','No path specified when installing app from local file',OC_Log::ERROR);
return false;
}
$path=$data['path'];
}
//extract the archive in a temporary folder
- $extractDir=tempnam(sys_get_temp_dir(),'oc_installer_uncompressed_');
+ $extractDir=tempnam(get_temp_dir(),'oc_installer_uncompressed_');
unlink($extractDir);
mkdir($extractDir);
$zip = new ZipArchive;
@@ -85,7 +85,7 @@ class OC_Installer{
$zip->extractTo($extractDir);
$zip->close();
} else {
- if(defined("DEBUG") && DEBUG) {error_log("Failed to open archive when installing app");}
+ OC_Log::write('core','Failed to open archive when installing app',OC_Log::ERROR);
OC_Helper::rmdirr($extractDir);
if($data['source']=='http'){
unlink($path);
@@ -95,7 +95,7 @@ class OC_Installer{
//load the info.xml file of the app
if(!is_file($extractDir.'/appinfo/info.xml')){
- if(defined("DEBUG") && DEBUG) {error_log("App does not provide an info.xml file");}
+ OC_Log::write('core','App does not provide an info.xml file',OC_Log::ERROR);
OC_Helper::rmdirr($extractDir);
if($data['source']=='http'){
unlink($path);
@@ -107,7 +107,7 @@ class OC_Installer{
//check if an app with the same id is already installed
if(self::isInstalled( $info['id'] )){
- if(defined("DEBUG") && DEBUG) {error_log("App already installed");}
+ OC_Log::write('core','App already installed',OC_Log::WARN);
OC_Helper::rmdirr($extractDir);
if($data['source']=='http'){
unlink($path);
@@ -117,7 +117,7 @@ class OC_Installer{
//check if the destination directory already exists
if(is_dir($basedir)){
- if(defined("DEBUG") && DEBUG) {error_log("App's directory already exists");}
+ OC_Log::write('core','App directory already exists',OC_Log::WARN);
OC_Helper::rmdirr($extractDir);
if($data['source']=='http'){
unlink($path);
@@ -131,7 +131,7 @@ class OC_Installer{
//copy the app to the correct place
if(!mkdir($basedir)){
- if(defined("DEBUG") && DEBUG) {error_log('Can\'t create app folder ('.$basedir.')');}
+ OC_Log::write('core','Can\'t create app folder ('.$basedir.')',OC_Log::ERROR);
OC_Helper::rmdirr($extractDir);
if($data['source']=='http'){
unlink($path);
@@ -152,14 +152,14 @@ class OC_Installer{
}
//run appinfo/install.php
- if(!isset($data['noinstall']) or $data['noinstall']==false and is_file($basedir.'/appinfo/install.php')){
+ if((!isset($data['noinstall']) or $data['noinstall']==false) and file_exists($basedir.'/appinfo/install.php')){
include($basedir.'/appinfo/install.php');
}
//set the installed version
OC_Appconfig::setValue($info['id'],'installed_version',$info['version']);
OC_Appconfig::setValue($info['id'],'enabled','no');
- return true;
+ return $info['id'];
}
/**
diff --git a/lib/l10n.php b/lib/l10n.php
index 54331d44ae4..a5544eb3a27 100644
--- a/lib/l10n.php
+++ b/lib/l10n.php
@@ -110,6 +110,22 @@ class OC_L10N{
}
/**
+ * @brief Translating
+ * @param $textArray The text array we need a translation for
+ * @returns Translation or the same text
+ *
+ * Returns the translation. If no translation is found, $textArray will be
+ * returned.
+ */
+ public function tA($textArray){
+ $result = array();
+ foreach($textArray as $key => $text){
+ $result[$key] = $this->t($text);
+ }
+ return $result;
+ }
+
+ /**
* @brief getTranslations
* @returns Fetch all translations
*
diff --git a/lib/log.php b/lib/log.php
new file mode 100644
index 00000000000..446ddd48848
--- /dev/null
+++ b/lib/log.php
@@ -0,0 +1,74 @@
+<?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/>.
+ *
+ */
+
+/**
+ *logging utilities
+ *
+ * Log is saved at data/owncloud.log (on default)
+ */
+
+class OC_Log{
+ const DEBUG=0;
+ const INFO=1;
+ const WARN=2;
+ const ERROR=3;
+ const FATAL=4;
+
+ /**
+ * write a message in the log
+ * @param string $app
+ * @param string $message
+ * @param int level
+ */
+ public static function write($app,$message,$level){
+ $minLevel=OC_Config::getValue( "loglevel", 2 );
+ if($level>=$minLevel){
+ $datadir=OC_Config::getValue( "datadirectory", OC::$SERVERROOT.'/data' );
+ $logFile=OC_Config::getValue( "logfile", $datadir.'/owncloud.log' );
+ $entry=array('app'=>$app,'message'=>$message,'level'=>$level,'time'=>time());
+ $fh=fopen($logFile,'a');
+ fwrite($fh,json_encode($entry)."\n");
+ fclose($fh);
+ }
+ }
+
+ public static function getEntries(){
+ $datadir=OC_Config::getValue( "datadirectory", OC::$SERVERROOT.'/data' );
+ $logFile=OC_Config::getValue( "logfile", $datadir.'/owncloud.log' );
+ $entries=array();
+ if(!file_exists($logFile)){
+ return array();
+ }
+ $fh=fopen($logFile,'r');
+ if($fh === false){ // Unable to read log file!
+ return array();
+ }
+ while(!feof($fh)){
+ $line=fgets($fh);
+ if($line){
+ $entries[]=json_decode($line);
+ }
+ }
+ fclose($fh);
+ return $entries;
+ }
+}
diff --git a/lib/mimetypes.fixlist.php b/lib/mimetypes.fixlist.php
new file mode 100644
index 00000000000..1c6acbc4438
--- /dev/null
+++ b/lib/mimetypes.fixlist.php
@@ -0,0 +1,14 @@
+<?php
+return array(
+ 'ics'=>'text/calendar',
+ 'ical'=>'text/calendar',
+ 'js'=>'application/javascript',
+ 'odt'=>'application/vnd.oasis.opendocument.text',
+ 'ods'=>'application/vnd.oasis.opendocument.spreadsheet',
+ 'odg'=>'application/vnd.oasis.opendocument.graphics',
+ 'odp'=>'application/vnd.oasis.opendocument.presentation',
+ 'pl'=>'text/x-script.perl',
+ 'py'=>'text/x-script.phyton',
+ 'vcf' => 'text/vcard',
+ 'vcard' => 'text/vcard'
+);
diff --git a/lib/ocsclient.php b/lib/ocsclient.php
index 654c5e0527b..9d5932fb720 100644
--- a/lib/ocsclient.php
+++ b/lib/ocsclient.php
@@ -108,6 +108,7 @@ class OC_OCSClient{
$xml=@file_get_contents($url);
if($xml==FALSE){
+ OC_Log::write('core','Unable to parse OCS content',OC_Log::FATAL);
return NULL;
}
$data=simplexml_load_string($xml);
@@ -129,6 +130,33 @@ class OC_OCSClient{
return $app;
}
+ /**
+ * @brief Get the download url for an application from the OCS server
+ * @returns array with application data
+ *
+ * This function returns an download url for an applications from the OCS server
+ */
+ public static function getApplicationDownload($id,$item){
+ $url='http://api.apps.owncloud.com/v1/content/download/'.urlencode($id).'/'.urlencode($item);
+
+ $xml=@file_get_contents($url);
+ if($xml==FALSE){
+ OC_Log::write('core','Unable to parse OCS content',OC_Log::FATAL);
+ return NULL;
+ }
+ $data=simplexml_load_string($xml);
+
+ $tmp=$data->data->content;
+ $app=array();
+ if(isset($tmp->downloadlink)) {
+ $app['downloadlink']=$tmp->downloadlink;
+ }else{
+ $app['downloadlink']='';
+ }
+ return $app;
+ }
+
+
/**
* @brief Get all the knowledgebase entries from the OCS server
* @returns array with q and a data
@@ -143,6 +171,7 @@ class OC_OCSClient{
$kbe=array();
$xml=@file_get_contents($url);
if($xml==FALSE){
+ OC_Log::write('core','Unable to parse knowledgebase content',OC_Log::FATAL);
return NULL;
}
$data=simplexml_load_string($xml);
diff --git a/lib/preferences.php b/lib/preferences.php
index 6d8aa17afd5..75201f455ba 100644
--- a/lib/preferences.php
+++ b/lib/preferences.php
@@ -140,7 +140,6 @@ class OC_Preferences{
// Check if the key does exist
$query = OC_DB::prepare( 'SELECT configvalue FROM *PREFIX*preferences WHERE userid = ? AND appid = ? AND configkey = ?' );
$values=$query->execute(array($user,$app,$key))->fetchAll();
- if(defined("DEBUG") && DEBUG) {error_log(print_r($values,true));}
$exists=(count($values)>0);
if( !$exists ){
diff --git a/lib/remote/cloud.php b/lib/remote/cloud.php
index 75d60155d06..a9c74e8bf5f 100644
--- a/lib/remote/cloud.php
+++ b/lib/remote/cloud.php
@@ -17,7 +17,7 @@ class OC_REMOTE_CLOUD{
*/
private function apiCall($action,$parameters=false,$assoc=false){
if(!$this->cookiefile){
- $this->cookiefile=sys_get_temp_dir().'/remoteCloudCookie'.uniqid();
+ $this->cookiefile=get_temp_dir().'/remoteCloudCookie'.uniqid();
}
$url=$this->path.='/files/api.php';
$fields_string="action=$action&";
@@ -168,9 +168,9 @@ class OC_REMOTE_CLOUD{
}
$ch=curl_init();
if(!$this->cookiefile){
- $this->cookiefile=sys_get_temp_dir().'/remoteCloudCookie'.uniqid();
+ $this->cookiefile=get_temp_dir().'/remoteCloudCookie'.uniqid();
}
- $tmpfile=tempnam(sys_get_temp_dir(),'remoteCloudFile');
+ $tmpfile=tempnam(get_temp_dir(),'remoteCloudFile');
$fp=fopen($tmpfile,'w+');
$url=$this->path.="/files/api.php?action=get&dir=$dir&file=$file";
curl_setopt($ch,CURLOPT_URL,$url);
@@ -191,7 +191,7 @@ class OC_REMOTE_CLOUD{
public function sendTmpFile($tmp,$targetDir,$targetFile){
$token=sha1(uniqid().$tmp);
- $file=sys_get_temp_dir().'/'.'remoteCloudFile'.$token;
+ $file=get_temp_dir().'/'.'remoteCloudFile'.$token;
rename($tmp,$file);
if( OC_Config::getValue( "forcessl", false ) or isset($_SERVER['HTTPS']) and $_SERVER['HTTPS'] == 'on') {
$url = "https://". $_SERVER['SERVER_NAME'] . OC::$WEBROOT;
diff --git a/lib/setup.php b/lib/setup.php
index 36ee966c556..30a91b4681b 100644
--- a/lib/setup.php
+++ b/lib/setup.php
@@ -84,7 +84,7 @@ class OC_Setup {
$dbpass = $options['dbpass'];
$dbname = $options['dbname'];
$dbhost = $options['dbhost'];
- $dbtableprefix = $options['dbtableprefix'];
+ $dbtableprefix = isset($options['dbtableprefix']) ? $options['dbtableprefix'] : 'oc_';
OC_Config::setValue('dbname', $dbname);
OC_Config::setValue('dbhost', $dbhost);
OC_Config::setValue('dbtableprefix', $dbtableprefix);
@@ -98,35 +98,45 @@ class OC_Setup {
);
}
else {
+ $oldUser=OC_Config::getValue('dbuser', false);
+ $oldPassword=OC_Config::getValue('dbpassword', false);
+
$query="SELECT user FROM mysql.user WHERE user='$dbuser'"; //this should be enough to check for admin rights in mysql
if(mysql_query($query, $connection)) {
//use the admin login data for the new database user
//add prefix to the mysql user name to prevent collissions
- $dbusername=substr('oc_mysql_'.$username,0,16);
- //hash the password so we don't need to store the admin config in the config file
- $dbpassword=md5(time().$password);
-
- self::createDBUser($dbusername, $dbpassword, $connection);
-
- OC_Config::setValue('dbuser', $dbusername);
- OC_Config::setValue('dbpassword', $dbpassword);
+ $dbusername=substr('oc_'.$username,0,16);
+ if($dbusername!=$oldUser){
+ //hash the password so we don't need to store the admin config in the config file
+ $dbpassword=md5(time().$password);
+
+ self::createDBUser($dbusername, $dbpassword, $connection);
+
+ OC_Config::setValue('dbuser', $dbusername);
+ OC_Config::setValue('dbpassword', $dbpassword);
+ }
//create the database
self::createDatabase($dbname, $dbusername, $connection);
}
else {
- OC_Config::setValue('dbuser', $dbuser);
- OC_Config::setValue('dbpassword', $dbpass);
+ if($dbuser!=$oldUser){
+ OC_Config::setValue('dbuser', $dbuser);
+ OC_Config::setValue('dbpassword', $dbpass);
+ }
//create the database
self::createDatabase($dbname, $dbuser, $connection);
}
//fill the database if needed
- $query="SELECT * FROM $dbname.{$dbtableprefix}users";
+ $query="select count(*) from information_schema.tables where table_schema='$dbname' AND table_name = '{$dbtableprefix}users';";
$result = mysql_query($query,$connection);
- if(!$result) {
+ if($result){
+ $row=mysql_fetch_row($result);
+ }
+ if(!$result or $row[0]==0) {
OC_DB::createDbFromStructure('db_structure.xml');
}
mysql_close($connection);
@@ -160,8 +170,8 @@ class OC_Setup {
//add prefix to the postgresql user name to prevent collissions
$dbusername='oc_'.$username;
- //hash the password so we don't need to store the admin config in the config file
- $dbpassword=md5(time().$password);
+ //create a new password so we don't need to store the admin config in the config file
+ $dbpassword=md5(time());
self::pg_createDBUser($dbusername, $dbpassword, $connection);
@@ -179,13 +189,29 @@ class OC_Setup {
self::pg_createDatabase($dbname, $dbuser, $connection);
}
- //fill the database if needed
- $query = "SELECT relname FROM pg_class WHERE relname='{$dbtableprefix}users' limit 1";
- $result = pg_query($connection, $query);
- if(!$result) {
- OC_DB::createDbFromStructure('db_structure.xml');
- }
+ // the connection to dbname=postgres is not needed anymore
pg_close($connection);
+
+ // connect to the ownCloud database (dbname=$dbname) an check if it needs to be filled
+ $dbuser = OC_CONFIG::getValue('dbuser');
+ $dbpass = OC_CONFIG::getValue('dbpassword');
+ $connection_string = "host=$dbhost dbname=$dbname user=$dbuser password=$dbpass";
+ $connection = @pg_connect($connection_string);
+ if(!$connection) {
+ $error[] = array(
+ 'error' => 'PostgreSQL username and/or password not valid',
+ 'hint' => 'You need to enter either an existing account or the administrator.'
+ );
+ } else {
+ $query = "select count(*) FROM pg_class WHERE relname='{$dbtableprefix}users' limit 1";
+ $result = pg_query($connection, $query);
+ if($result) {
+ $row = pg_fetch_row($result);
+ }
+ if(!$result or $row[0]==0) {
+ OC_DB::createDbFromStructure('db_structure.xml');
+ }
+ }
}
}
else {
@@ -221,7 +247,7 @@ class OC_Setup {
}
public static function createDatabase($name,$user,$connection) {
- //we cant user OC_BD functions here because we need to connect as the administrative user.
+ //we cant use OC_BD functions here because we need to connect as the administrative user.
$query = "CREATE DATABASE IF NOT EXISTS `$name`";
$result = mysql_query($query, $connection);
if(!$result) {
@@ -243,7 +269,7 @@ class OC_Setup {
}
public static function pg_createDatabase($name,$user,$connection) {
- //we cant user OC_BD functions here because we need to connect as the administrative user.
+ //we cant use OC_BD functions here because we need to connect as the administrative user.
$query = "CREATE DATABASE $name OWNER $user";
$result = pg_query($connection, $query);
if(!$result) {
@@ -275,7 +301,7 @@ class OC_Setup {
$content.= "php_value post_max_size 512M\n";
$content.= "SetEnv htaccessWorking true\n";
$content.= "</IfModule>\n";
- $content.= "<IfModule !mod_php5.c>\n";
+ $content.= "<IfModule mod_rewrite.c>\n";
$content.= "RewriteEngine on\n";
$content.= "RewriteRule .* - [env=HTTP_AUTHORIZATION:%{HTTP:Authorization},last]\n";
$content.= "</IfModule>\n";
diff --git a/lib/template.php b/lib/template.php
index 440b62003e7..881d2a27b1e 100644
--- a/lib/template.php
+++ b/lib/template.php
@@ -98,6 +98,33 @@ function relative_modified_date($timestamp) {
else { return $l->t('years ago'); }
}
+function html_select_options($options, $selected, $params=array()) {
+ if (!is_array($selected)){
+ $selected=array($selected);
+ }
+ if (isset($params['combine']) && $params['combine']){
+ $options = array_combine($options, $options);
+ }
+ $value_name = $label_name = false;
+ if (isset($params['value'])){
+ $value_name = $params['value'];
+ }
+ if (isset($params['label'])){
+ $label_name = $params['label'];
+ }
+ $html = '';
+ foreach($options as $value => $label){
+ if ($value_name && is_array($label)){
+ $value = $label[$value_name];
+ }
+ if ($label_name && is_array($label)){
+ $label = $label[$label_name];
+ }
+ $select = in_array($value, $selected) ? ' selected="selected"' : '';
+ $html .= '<option value="' . $value . '"' . $select . '>' . $label . '</option>'."\n";
+ }
+ return $html;
+}
/**
* This class provides the templates for owncloud.
diff --git a/lib/updater.php b/lib/updater.php
index e4db719a62c..e992e4dcf11 100644
--- a/lib/updater.php
+++ b/lib/updater.php
@@ -52,13 +52,9 @@ class OC_Updater{
$tmp['url'] = $data->url;
$tmp['web'] = $data->web;
-
return $tmp;
-
}
-
-
public static function ShowUpdatingHint(){
$data=OC_Updater::check();
if(isset($data['version']) and $data['version']<>'') {
@@ -67,10 +63,8 @@ class OC_Updater{
$txt='Your ownCloud is up to date';
}
return($txt);
-
}
-
/**
* do ownCloud update
*/
@@ -83,9 +77,4 @@ class OC_Updater{
//update version in config
}
-
}
-
-
-
-?>
diff --git a/lib/user.php b/lib/user.php
index 241d9aa8b10..34f44f572e0 100644
--- a/lib/user.php
+++ b/lib/user.php
@@ -120,7 +120,7 @@ class OC_User {
return false;
}
// No empty username
- if( !$uid ){
+ if(trim($uid) == ''){
return false;
}
// Check if user already exists
@@ -169,7 +169,8 @@ class OC_User {
foreach( OC_Group::getUserGroups( $uid ) as $i ){
OC_Group::removeFromGroup( $uid, $i );
}
-
+ // Delete the user's keys in preferences
+ OC_Preferences::deleteUser($uid);
// Emit and exit
OC_Hook::emit( "OC_User", "post_deleteUser", array( "uid" => $uid ));
return true;
diff --git a/lib/util.php b/lib/util.php
index 2b2238f9220..2fba1206bff 100644
--- a/lib/util.php
+++ b/lib/util.php
@@ -24,7 +24,7 @@ class OC_Util {
$success=@mkdir($CONFIG_DATADIRECTORY_ROOT);
if(!$success) {
$tmpl = new OC_Template( '', 'error', 'guest' );
- $tmpl->assign('errors',array(1=>array('error'=>"Can't create data directory (".$CONFIG_DATADIRECTORY_ROOT.")",'hint'=>"You can usually fix this by setting the owner of '".OC::$SERVERROOT."' to the user that the web server uses (".OC_Util::checkWebserverUser().")")));
+ $tmpl->assign('errors',array(1=>array('error'=>"Can't create data directory (".$CONFIG_DATADIRECTORY_ROOT.")",'hint'=>"You can usually fix this by giving the webserver write access to the ownCloud directory '".OC::$SERVERROOT."' ")));
$tmpl->printPage();
exit;
}
@@ -36,42 +36,14 @@ class OC_Util {
}
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_ROOT));
-// if( OC_Config::getValue( "enablebackup", false )){
-// // This creates the Directorys recursively
-// if(!is_dir( "$CONFIG_BACKUPDIRECTORY/$user/$root" )){
-// mkdir( "$CONFIG_BACKUPDIRECTORY/$user/$root", 0755, true );
-// }
-// $backupStorage=OC_Filesystem::createStorage('local',array('datadir'=>$CONFIG_BACKUPDIRECTORY));
-// $backup=new OC_FILEOBSERVER_BACKUP(array('storage'=>$backupStorage));
-// $rootStorage->addObserver($backup);
-// }
- OC_Filesystem::mount($rootStorage,'/');
-
- // TODO add this storage provider in a proper way
- $sharedStorage = OC_Filesystem::createStorage('shared',array('datadir'=>'/'.OC_User::getUser().'/files/Shared'));
- OC_Filesystem::mount($sharedStorage,'/'.OC_User::getUser().'/files/Shared/');
+ //first set up the local "root" storage
+ OC_Filesystem::mount('local',array('datadir'=>$CONFIG_DATADIRECTORY_ROOT),'/');
OC::$CONFIG_DATADIRECTORY = $CONFIG_DATADIRECTORY_ROOT."/$user/$root";
if( !is_dir( OC::$CONFIG_DATADIRECTORY )){
mkdir( OC::$CONFIG_DATADIRECTORY, 0755, true );
}
-// TODO: find a cool way for doing this
-// //set up the other storages according to the system settings
-// foreach($CONFIG_FILESYSTEM as $storageConfig){
-// if(OC_Filesystem::hasStorageType($storageConfig['type'])){
-// $arguments=$storageConfig;
-// unset($arguments['type']);
-// unset($arguments['mountpoint']);
-// $storage=OC_Filesystem::createStorage($storageConfig['type'],$arguments);
-// if($storage){
-// OC_Filesystem::mount($storage,$storageConfig['mountpoint']);
-// }
-// }
-// }
-
//jail the user into his "home" directory
OC_Filesystem::chroot("/$user/$root");
$quotaProxy=new OC_FileProxy_Quota();
@@ -90,7 +62,7 @@ class OC_Util {
* @return array
*/
public static function getVersion(){
- return array(2,00,1);
+ return array(3,00,0);
}
/**
@@ -98,7 +70,7 @@ class OC_Util {
* @return string
*/
public static function getVersionString(){
- return '2';
+ return '3';
}
/**
@@ -153,7 +125,7 @@ class OC_Util {
*/
public static function formatDate( $timestamp,$dateOnly=false){
if(isset($_SESSION['timezone'])){//adjust to clients timezone if we know it
- $systemTimeZone = intval(exec('date +%z'));
+ $systemTimeZone = intval(date('O'));
$systemTimeZone=(round($systemTimeZone/100,0)*60)+($systemTimeZone%100);
$clientTimeZone=$_SESSION['timezone']*60;
$offset=$clientTimeZone-$systemTimeZone;
@@ -203,15 +175,14 @@ class OC_Util {
$errors=array();
//check for database drivers
- if(!is_callable('sqlite_open') and !is_callable('mysql_connect')){
- $errors[]=array('error'=>'No database drivers (sqlite or mysql) installed.<br/>','hint'=>'');//TODO: sane hint
+ if(!(is_callable('sqlite_open') or class_exists('SQLite3')) and !is_callable('mysql_connect') and !is_callable('pg_connect')){
+ $errors[]=array('error'=>'No database drivers (sqlite, mysql, or postgresql) installed.<br/>','hint'=>'');//TODO: sane hint
}
$CONFIG_DBTYPE = OC_Config::getValue( "dbtype", "sqlite" );
$CONFIG_DBNAME = OC_Config::getValue( "dbname", "owncloud" );
- $serverUser=OC_Util::checkWebserverUser();
//common hint for all file permissons error messages
- $permissionsHint="Permissions can usually be fixed by setting the owner of the file or directory to the user the web server runs as ($serverUser)";
+ $permissionsHint="Permissions can usually be fixed by giving the webserver write access to the ownCloud directory";
//check for correct file permissions
if(!stristr(PHP_OS, 'WIN')){
@@ -255,6 +226,10 @@ class OC_Util {
$errors[]=array('error'=>'PHP module ctype is not installed.<br/>','hint'=>'Please ask your server administrator to install the module.');
}
+ if(file_exists(OC::$SERVERROOT."/config/config.php") and !is_writeable(OC::$SERVERROOT."/config/config.php")){
+ $errors[]=array('error'=>"Can't write into config directory 'config'",'hint'=>"You can usually fix this by giving the webserver use write access to the config directory in owncloud");
+ }
+
return $errors;
}
@@ -267,22 +242,6 @@ class OC_Util {
OC_Template::printGuestPage("", "login", $parameters);
}
- /**
- * Try to get the username the httpd server runs on, used in hints
- */
- public static function checkWebserverUser(){
- $stat=stat($_SERVER['DOCUMENT_ROOT']);
- if(is_callable('posix_getpwuid')){
- $serverUser=posix_getpwuid($stat['uid']);
- $serverUser='\''.$serverUser['name'].'\'';
- }elseif(exec('whoami')){
- $serverUser=exec('whoami');
- }else{
- $serverUser='\'www-data\' for ubuntu/debian'; //TODO: try to detect the distro and give a guess based on that
- }
- return $serverUser;
- }
-
/**
* Check if the app is enabled, send json error msg if not
diff --git a/lib/vobject.php b/lib/vobject.php
new file mode 100644
index 00000000000..e3479fc6d36
--- /dev/null
+++ b/lib/vobject.php
@@ -0,0 +1,207 @@
+<?php
+/**
+ * ownCloud
+ *
+ * @author Bart Visscher
+ * @copyright 2011 Bart Visscher bartv@thisnet.nl
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/**
+ * This class provides a streamlined interface to the Sabre VObject classes
+ */
+class OC_VObject{
+ /** @var Sabre_VObject_Component */
+ protected $vobject;
+
+ /**
+ * @returns Sabre_VObject_Component
+ */
+ public function getVObject(){
+ return $this->vobject;
+ }
+
+ /**
+ * @brief Parses the VObject
+ * @param string VObject as string
+ * @returns Sabre_VObject or null
+ */
+ public static function parse($data){
+ try {
+ Sabre_VObject_Reader::$elementMap['LAST-MODIFIED'] = 'Sabre_VObject_Element_DateTime';
+ $vobject = Sabre_VObject_Reader::read($data);
+ if ($vobject instanceof Sabre_VObject_Component){
+ $vobject = new OC_VObject($vobject);
+ }
+ return $vobject;
+ } catch (Exception $e) {
+ OC_Log::write('vobject', $e->getMessage(), OC_Log::ERROR);
+ return null;
+ }
+ }
+
+ /**
+ * @brief Escapes semicolons
+ * @param string $value
+ * @return string
+ */
+ public static function escapeSemicolons($value){
+ foreach($value as &$i ){
+ $i = implode("\\\\;", explode(';', $i));
+ }
+ return implode(';',$value);
+ }
+
+ /**
+ * @brief Creates an array out of a multivalue property
+ * @param string $value
+ * @return array
+ */
+ public static function unescapeSemicolons($value){
+ $array = explode(';',$value);
+ for($i=0;$i<count($array);$i++){
+ if(substr($array[$i],-2,2)=="\\\\"){
+ if(isset($array[$i+1])){
+ $array[$i] = substr($array[$i],0,count($array[$i])-2).';'.$array[$i+1];
+ unset($array[$i+1]);
+ }
+ else{
+ $array[$i] = substr($array[$i],0,count($array[$i])-2).';';
+ }
+ $i = $i - 1;
+ }
+ }
+ return $array;
+ }
+
+ /**
+ * Constuctor
+ * @param Sabre_VObject_Component or string
+ */
+ public function __construct($vobject_or_name){
+ if (is_object($vobject_or_name)){
+ $this->vobject = $vobject_or_name;
+ } else {
+ $this->vobject = new Sabre_VObject_Component($vobject_or_name);
+ }
+ }
+
+ public function add($item, $itemValue = null){
+ if ($item instanceof OC_VObject){
+ $item = $item->getVObject();
+ }
+ $this->vobject->add($item, $itemValue);
+ }
+
+ /**
+ * @brief Add property to vobject
+ * @param object $name of property
+ * @param object $value of property
+ * @param object $parameters of property
+ * @returns Sabre_VObject_Property newly created
+ */
+ public function addProperty($name, $value, $parameters=array()){
+ if(is_array($value)){
+ $value = OC_VObject::escapeSemicolons($value);
+ }
+ $property = new Sabre_VObject_Property( $name, $value );
+ foreach($parameters as $name => $value){
+ $property->parameters[] = new Sabre_VObject_Parameter($name, $value);
+ }
+
+ $this->vobject->add($property);
+ return $property;
+ }
+
+ public function setUID(){
+ $uid = substr(md5(rand().time()),0,10);
+ $this->vobject->add('UID',$uid);
+ }
+
+ public function setString($name, $string){
+ if ($string != ''){
+ $string = strtr($string, array("\r\n"=>"\n"));
+ $this->vobject->__set($name, $string);
+ }else{
+ $this->vobject->__unset($name);
+ }
+ }
+
+ /**
+ * Sets or unsets the Date and Time for a property.
+ * When $datetime is set to 'now', use the current time
+ * When $datetime is null, unset the property
+ *
+ * @param string property name
+ * @param DateTime $datetime
+ * @param int $dateType
+ * @return void
+ */
+ public function setDateTime($name, $datetime, $dateType=Sabre_VObject_Element_DateTime::LOCALTZ){
+ if ($datetime == 'now'){
+ $datetime = new DateTime();
+ }
+ if ($datetime instanceof DateTime){
+ $datetime_element = new Sabre_VObject_Element_DateTime($name);
+ $datetime_element->setDateTime($datetime, $dateType);
+ $this->vobject->__set($name, $datetime_element);
+ }else{
+ $this->vobject->__unset($name);
+ }
+ }
+
+ public function getAsString($name){
+ return $this->vobject->__isset($name) ?
+ $this->vobject->__get($name)->value :
+ '';
+ }
+
+ public function getAsArray($name){
+ $values = array();
+ if ($this->vobject->__isset($name)){
+ $values = explode(',', $this->getAsString($name));
+ $values = array_map('trim', $values);
+ }
+ return $values;
+ }
+
+ public function &__get($name){
+ if ($name == 'children'){
+ return $this->vobject->children;
+ }
+ $return = $this->vobject->__get($name);
+ if ($return instanceof Sabre_VObject_Component){
+ $return = new OC_VObject($return);
+ }
+ return $return;
+ }
+
+ public function __set($name, $value){
+ return $this->vobject->__set($name, $value);
+ }
+
+ public function __unset($name){
+ return $this->vobject->__unset($name);
+ }
+
+ public function __isset($name){
+ return $this->vobject->__isset($name);
+ }
+
+ public function __call($function,$arguments){
+ return call_user_func_array(array($this->vobject, $function), $arguments);
+ }
+}