aboutsummaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/ajax/share.php9
-rw-r--r--core/css/icons.css4
-rw-r--r--core/css/styles.css2
-rw-r--r--core/img/actions/checkmark-white.pngbin0 -> 286 bytes
-rw-r--r--core/img/actions/checkmark-white.svg4
-rw-r--r--core/img/actions/toggle-filelist.pngbin0 -> 195 bytes
-rw-r--r--core/img/actions/toggle-filelist.svg11
-rw-r--r--core/img/actions/toggle-pictures.pngbin0 -> 193 bytes
-rw-r--r--core/img/actions/toggle-pictures.svg9
-rw-r--r--core/img/places/picture.pngbin242 -> 434 bytes
-rw-r--r--core/img/places/picture.svg5
-rw-r--r--core/js/config.php6
-rw-r--r--core/js/core.json43
-rw-r--r--core/js/js.js87
-rw-r--r--core/js/tests/specHelper.js18
-rw-r--r--core/js/tests/specs/coreSpec.js210
-rw-r--r--core/setup.php73
-rw-r--r--core/setup/controller.php138
-rw-r--r--core/templates/installation.php78
-rw-r--r--core/templates/layout.base.php2
-rw-r--r--core/templates/layout.guest.php2
-rw-r--r--core/templates/layout.user.php33
22 files changed, 533 insertions, 201 deletions
diff --git a/core/ajax/share.php b/core/ajax/share.php
index 268cd4f53a7..8b48effb458 100644
--- a/core/ajax/share.php
+++ b/core/ajax/share.php
@@ -121,7 +121,7 @@ if (isset($_POST['action']) && isset($_POST['itemType']) && isset($_POST['itemSo
if (isset($items[0]['expiration'])) {
try {
$date = new DateTime($items[0]['expiration']);
- $expiration = $date->format('Y-m-d');
+ $expiration = $l->l('date', $date->getTimestamp());
} catch (Exception $e) {
\OCP\Util::writeLog('sharing', "Couldn't read date: " . $e->getMessage(), \OCP\Util::ERROR);
}
@@ -187,6 +187,8 @@ if (isset($_POST['action']) && isset($_POST['itemType']) && isset($_POST['itemSo
break;
case 'email':
+ // enable l10n support
+ $l = OC_L10N::get('core');
// read post variables
$user = OCP\USER::getUser();
$displayName = OCP\User::getDisplayName();
@@ -199,16 +201,13 @@ if (isset($_POST['action']) && isset($_POST['itemType']) && isset($_POST['itemSo
if (isset($_POST['expiration']) && $_POST['expiration'] !== '') {
try {
$date = new DateTime($_POST['expiration']);
- $expiration = $date->format('Y-m-d');
+ $expiration = $l->l('date', $date->getTimestamp());
} catch (Exception $e) {
\OCP\Util::writeLog('sharing', "Couldn't read date: " . $e->getMessage(), \OCP\Util::ERROR);
}
}
- // enable l10n support
- $l = OC_L10N::get('core');
-
// setup the email
$subject = (string)$l->t('%s shared »%s« with you', array($displayName, $file));
diff --git a/core/css/icons.css b/core/css/icons.css
index 57c37c5c51c..2dc35084122 100644
--- a/core/css/icons.css
+++ b/core/css/icons.css
@@ -47,6 +47,10 @@
background-image: url('../img/actions/checkmark.svg');
}
+.icon-checkmark-white {
+ background-image: url('../img/actions/checkmark-white.svg');
+}
+
.icon-clock {
background-image: url('../img/actions/clock.svg');
}
diff --git a/core/css/styles.css b/core/css/styles.css
index 03eb76ddce5..bee44785f12 100644
--- a/core/css/styles.css
+++ b/core/css/styles.css
@@ -686,7 +686,7 @@ label.infield { cursor:text !important; top:1.05em; left:.85em; }
/* Apps management as sticky footer, less obtrusive in the list */
#navigation .wrapper {
min-height: 100%;
- margin: 0 auto -72px;
+ margin: 0 auto -82px 0;
}
#apps-management, #navigation .push {
height: 72px;
diff --git a/core/img/actions/checkmark-white.png b/core/img/actions/checkmark-white.png
new file mode 100644
index 00000000000..08b8783649f
--- /dev/null
+++ b/core/img/actions/checkmark-white.png
Binary files differ
diff --git a/core/img/actions/checkmark-white.svg b/core/img/actions/checkmark-white.svg
new file mode 100644
index 00000000000..5e8fe8abccc
--- /dev/null
+++ b/core/img/actions/checkmark-white.svg
@@ -0,0 +1,4 @@
+<svg xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" version="1.1" xml:space="preserve" height="16px" viewBox="-0.5 -0.5 16 16" width="16px" enable-background="new -0.5 -0.5 16 16" y="0px" x="0px" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" overflow="visible"><metadata><rdf:RDF><cc:Work rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/><dc:title/></cc:Work></rdf:RDF></metadata><defs>
+</defs>
+<path fill="#ffffff" d="M12.438,3.6875c-0.363,0-0.726,0.1314-1,0.4063l-4.5005,4.5-1.9687-2c-0.5498-0.5484-1.4489-0.5498-2,0l-0.5,0.5c-0.5512,0.5496-0.5512,1.4502,0,2l2.9687,2.9682c0.0063,0.007-0.0065,0.025,0,0.032l0.5,0.5c0.5497,0.55,1.4503,0.55,2,0l0.5-0.5,0.1875-0.219,5.313-5.2812c0.549-0.5498,0.549-1.4503,0-2l-0.5-0.5c-0.275-0.2749-0.638-0.4063-1-0.4063z" transform="translate(-0.5,-0.5)"/>
+</svg>
diff --git a/core/img/actions/toggle-filelist.png b/core/img/actions/toggle-filelist.png
new file mode 100644
index 00000000000..45d363f1934
--- /dev/null
+++ b/core/img/actions/toggle-filelist.png
Binary files differ
diff --git a/core/img/actions/toggle-filelist.svg b/core/img/actions/toggle-filelist.svg
new file mode 100644
index 00000000000..940f6a49e63
--- /dev/null
+++ b/core/img/actions/toggle-filelist.svg
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="16" width="16" version="1.0" xmlns:cc="http://creativecommons.org/ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:dc="http://purl.org/dc/elements/1.1/">
+ <g>
+ <rect rx=".5" ry=".5" height="4" width="4" y="1" x="1"/>
+ <rect rx=".5" ry=".5" height="1" width="9" y="2" x="6"/>
+ <rect rx=".5" ry=".5" height="4" width="4" y="6" x="1"/>
+ <rect rx=".5" ry=".5" height="1" width="9" y="7" x="6"/>
+ <rect rx=".5" ry=".5" height="4" width="4" y="11" x="1"/>
+ <rect rx=".5" ry=".5" height="1" width="9" y="12" x="6"/>
+ </g>
+</svg>
diff --git a/core/img/actions/toggle-pictures.png b/core/img/actions/toggle-pictures.png
new file mode 100644
index 00000000000..8068d17e30d
--- /dev/null
+++ b/core/img/actions/toggle-pictures.png
Binary files differ
diff --git a/core/img/actions/toggle-pictures.svg b/core/img/actions/toggle-pictures.svg
new file mode 100644
index 00000000000..5205c0226d1
--- /dev/null
+++ b/core/img/actions/toggle-pictures.svg
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="16" width="16" version="1.0" xmlns:cc="http://creativecommons.org/ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:dc="http://purl.org/dc/elements/1.1/">
+ <g>
+ <rect rx=".5" ry=".5" height="6" width="6" y="1" x="1"/>
+ <rect rx=".5" ry=".5" height="6" width="6" y="1" x="9"/>
+ <rect rx=".5" ry=".5" height="6" width="6" y="9" x="9"/>
+ <rect rx=".5" ry=".5" height="6" width="6" y="9" x="1"/>
+ </g>
+</svg>
diff --git a/core/img/places/picture.png b/core/img/places/picture.png
index 7b3af8c7f84..2b96ea518ce 100644
--- a/core/img/places/picture.png
+++ b/core/img/places/picture.png
Binary files differ
diff --git a/core/img/places/picture.svg b/core/img/places/picture.svg
index 791cbb5909a..82d457f5c7c 100644
--- a/core/img/places/picture.svg
+++ b/core/img/places/picture.svg
@@ -1,7 +1,4 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="32" width="32" version="1.1" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/">
- <g transform="translate(581.71 -2.0765)">
- <path style="block-progression:tb;text-indent:0;color:#000000;text-transform:none" d="m-575.01 3.0806c-0.39495 0.0765-0.70712 0.46665-0.70001 0.87488l-0.00062 26.246c0.00001 0.45808 0.41045 0.87487 0.86155 0.87488h20.28c0.4511-0.000012 0.86154-0.4168 0.86155-0.87488l0.00061-25.921c-0.00065-0.67287-0.53099-1.2037-1.0337-1.1998h-20.27zm1.2998 19.996h18l0.00082 6h-18.001z"/>
- <path style="block-progression:tb;text-indent:0;color:#000000;text-transform:none" d="m-575.01 4.0806c-0.39495 0.0765-0.70712 0.46665-0.70001 0.87488l-0.00062 26.246c0.00001 0.45808 0.41045 0.87487 0.86155 0.87488h20.28c0.4511-0.000012 0.86154-0.4168 0.86155-0.87488l0.00061-25.921c-0.00065-0.67287-0.53099-1.2037-1.0337-1.1998h-20.27zm1.2998 19.996h18l0.00082 6h-18.001z" fill="#fff"/>
- </g>
+ <path style="block-progression:tb;color:#000000;text-transform:none;text-indent:0" fill="#fff" d="m0.6875 4c-0.39495 0.0765-0.69461 0.4668-0.6875 0.875v22.25c0.00001 0.458 0.4239 0.875 0.875 0.875h30.25c0.4511-0.000012 0.87499-0.41692 0.875-0.875v-21.906c-0.001-0.6731-0.529-1.2229-1.031-1.219zm2.3125 3h26v10l-2-2-5 7-6.625-4-9.1875 7h-3.1875zm6 3c-1.6569 0-3 1.3431-3 3s1.3431 3 3 3 3-1.3431 3-3-1.3431-3-3-3z"/>
</svg>
diff --git a/core/js/config.php b/core/js/config.php
index dd46f7889d1..517ea1615a8 100644
--- a/core/js/config.php
+++ b/core/js/config.php
@@ -55,6 +55,12 @@ $array = array(
)
),
"firstDay" => json_encode($l->l('firstday', 'firstday')) ,
+ "oc_config" => json_encode(
+ array(
+ 'session_lifetime' => \OCP\Config::getSystemValue('session_lifetime', 60 * 60 * 24),
+ 'session_keepalive' => \OCP\Config::getSystemValue('session_keepalive', true)
+ )
+ )
);
// Echo it
diff --git a/core/js/core.json b/core/js/core.json
index 79cfc42f587..4beab7cf796 100644
--- a/core/js/core.json
+++ b/core/js/core.json
@@ -1,28 +1,23 @@
{
+ "libraries": [
+ "jquery-1.10.0.min.js",
+ "jquery-migrate-1.2.1.min.js",
+ "jquery-ui-1.10.0.custom.js",
+ "jquery-showpassword.js",
+ "jquery.infieldlabel.js",
+ "jquery.placeholder.js",
+ "jquery-tipsy.js"
+ ],
"modules": [
- "jquery-1.10.0.min.js",
- "jquery-migrate-1.2.1.min.js",
- "jquery-ui-1.10.0.custom.js",
- "jquery-showpassword.js",
- "jquery.infieldlabel.js",
- "jquery.placeholder.js",
- "jquery-tipsy.js",
- "compatibility.js",
- "jquery.ocdialog.js",
- "oc-dialogs.js",
- "js.js",
- "octemplate.js",
- "eventsource.js",
- "config.js",
- "multiselect.js",
- "search.js",
- "router.js",
- "oc-requesttoken.js",
- "styles.js",
- "apps.js",
- "fixes.js",
- "jquery-ui-2.10.0.custom.js",
- "jquery-tipsy.js",
- "jquery.ocdialog.js"
+ "compatibility.js",
+ "jquery.ocdialog.js",
+ "oc-dialogs.js",
+ "js.js",
+ "octemplate.js",
+ "eventsource.js",
+ "config.js",
+ "multiselect.js",
+ "router.js",
+ "oc-requesttoken.js"
]
}
diff --git a/core/js/js.js b/core/js/js.js
index e84f482d672..cb177712a3a 100644
--- a/core/js/js.js
+++ b/core/js/js.js
@@ -11,6 +11,8 @@ var oc_webroot;
var oc_current_user = document.getElementsByTagName('head')[0].getAttribute('data-user');
var oc_requesttoken = document.getElementsByTagName('head')[0].getAttribute('data-requesttoken');
+window.oc_config = window.oc_config || {};
+
if (typeof oc_webroot === "undefined") {
oc_webroot = location.pathname;
var pos = oc_webroot.indexOf('/index.php/');
@@ -253,6 +255,12 @@ var OC={
return link;
},
/**
+ * Redirect to the target URL, can also be used for downloads.
+ */
+ redirect: function(targetUrl) {
+ window.location = targetUrl;
+ },
+ /**
* get the absolute path to an image file
* @param app the app id to which the image belongs
* @param file the name of the image file
@@ -364,6 +372,34 @@ var OC={
}
return result;
},
+
+ /**
+ * Builds a URL query from a JS map.
+ * @param params parameter map
+ * @return string containing a URL query (without question) mark
+ */
+ buildQueryString: function(params) {
+ var s = '';
+ var first = true;
+ if (!params) {
+ return s;
+ }
+ for (var key in params) {
+ var value = params[key];
+ if (first) {
+ first = false;
+ }
+ else {
+ s += '&';
+ }
+ s += encodeURIComponent(key);
+ if (value !== null && typeof(value) !== 'undefined') {
+ s += '=' + encodeURIComponent(value);
+ }
+ }
+ return s;
+ },
+
/**
* Opens a popup with the setting for an app.
* @param appid String. The ID of the app e.g. 'calendar', 'contacts' or 'files'.
@@ -708,8 +744,39 @@ function fillWindow(selector) {
console.warn("This function is deprecated! Use CSS instead");
}
-$(document).ready(function(){
- sessionHeartBeat();
+/**
+ * Initializes core
+ */
+function initCore() {
+
+ /**
+ * Calls the server periodically to ensure that session doesn't
+ * time out
+ */
+ function initSessionHeartBeat(){
+ // interval in seconds
+ var interval = 900;
+ if (oc_config.session_lifetime) {
+ interval = Math.floor(oc_config.session_lifetime / 2);
+ }
+ // minimum one minute
+ if (interval < 60) {
+ interval = 60;
+ }
+ OC.Router.registerLoadedCallback(function(){
+ var url = OC.Router.generate('heartbeat');
+ setInterval(function(){
+ $.post(url);
+ }, interval * 1000);
+ });
+ }
+
+ // session heartbeat (defaults to enabled)
+ if (typeof(oc_config.session_keepalive) === 'undefined' ||
+ !!oc_config.session_keepalive) {
+
+ initSessionHeartBeat();
+ }
if(!SVGSupport()){ //replace all svg images with png images for browser that dont support svg
replaceSVG();
@@ -822,7 +889,9 @@ $(document).ready(function(){
$('input[type=text]').focus(function(){
this.select();
});
-});
+}
+
+$(document).ready(initCore);
/**
* Filter Jquery selector by attribute value
@@ -952,15 +1021,3 @@ jQuery.fn.exists = function(){
return this.length > 0;
};
-/**
- * Calls the server periodically every 15 mins to ensure that session doesnt
- * time out
- */
-function sessionHeartBeat(){
- OC.Router.registerLoadedCallback(function(){
- var url = OC.Router.generate('heartbeat');
- setInterval(function(){
- $.post(url);
- }, 900000);
- });
-}
diff --git a/core/js/tests/specHelper.js b/core/js/tests/specHelper.js
index 4a30878df51..1848d08354e 100644
--- a/core/js/tests/specHelper.js
+++ b/core/js/tests/specHelper.js
@@ -19,6 +19,8 @@
*
*/
+/* global OC */
+
/**
* Simulate the variables that are normally set by PHP code
*/
@@ -57,10 +59,15 @@ window.oc_webroot = location.href + '/';
window.oc_appswebroots = {
"files": window.oc_webroot + '/apps/files/'
};
+window.oc_config = {
+ session_lifetime: 600 * 1000,
+ session_keepalive: false
+};
// global setup for all tests
(function setupTests() {
- var fakeServer = null;
+ var fakeServer = null,
+ routesRequestStub;
beforeEach(function() {
// enforce fake XHR, tests should not depend on the server and
@@ -78,9 +85,18 @@ window.oc_appswebroots = {
// make it globally available, so that other tests can define
// custom responses
window.fakeServer = fakeServer;
+
+ OC.Router.routes = [];
+ OC.Router.routes_request = {
+ state: sinon.stub().returns('resolved'),
+ done: sinon.stub()
+ };
});
afterEach(function() {
+ OC.Router.routes_request.state.reset();
+ OC.Router.routes_request.done.reset();
+
// uncomment this to log requests
// console.log(window.fakeServer.requests);
fakeServer.restore();
diff --git a/core/js/tests/specs/coreSpec.js b/core/js/tests/specs/coreSpec.js
index 827669f270b..478505e9287 100644
--- a/core/js/tests/specs/coreSpec.js
+++ b/core/js/tests/specs/coreSpec.js
@@ -18,6 +18,8 @@
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
*/
+
+/* global OC */
describe('Core base tests', function() {
describe('Base values', function() {
it('Sets webroots', function() {
@@ -25,6 +27,103 @@ describe('Core base tests', function() {
expect(OC.appswebroots).toBeDefined();
});
});
+ describe('basename', function() {
+ it('Returns the nothing if no file name given', function() {
+ expect(OC.basename('')).toEqual('');
+ });
+ it('Returns the nothing if dir is root', function() {
+ expect(OC.basename('/')).toEqual('');
+ });
+ it('Returns the same name if no path given', function() {
+ expect(OC.basename('some name.txt')).toEqual('some name.txt');
+ });
+ it('Returns the base name if root path given', function() {
+ expect(OC.basename('/some name.txt')).toEqual('some name.txt');
+ });
+ it('Returns the base name if double root path given', function() {
+ expect(OC.basename('//some name.txt')).toEqual('some name.txt');
+ });
+ it('Returns the base name if subdir given without root', function() {
+ expect(OC.basename('subdir/some name.txt')).toEqual('some name.txt');
+ });
+ it('Returns the base name if subdir given with root', function() {
+ expect(OC.basename('/subdir/some name.txt')).toEqual('some name.txt');
+ });
+ it('Returns the base name if subdir given with double root', function() {
+ expect(OC.basename('//subdir/some name.txt')).toEqual('some name.txt');
+ });
+ it('Returns the base name if subdir has dot', function() {
+ expect(OC.basename('/subdir.dat/some name.txt')).toEqual('some name.txt');
+ });
+ it('Returns dot if file name is dot', function() {
+ expect(OC.basename('/subdir/.')).toEqual('.');
+ });
+ // TODO: fix the source to make it work like PHP's basename
+ it('Returns the dir itself if no file name given', function() {
+ // TODO: fix the source to make it work like PHP's dirname
+ // expect(OC.basename('subdir/')).toEqual('subdir');
+ expect(OC.basename('subdir/')).toEqual('');
+ });
+ it('Returns the dir itself if no file name given with root', function() {
+ // TODO: fix the source to make it work like PHP's dirname
+ // expect(OC.basename('/subdir/')).toEqual('subdir');
+ expect(OC.basename('/subdir/')).toEqual('');
+ });
+ });
+ describe('dirname', function() {
+ it('Returns the nothing if no file name given', function() {
+ expect(OC.dirname('')).toEqual('');
+ });
+ it('Returns the root if dir is root', function() {
+ // TODO: fix the source to make it work like PHP's dirname
+ // expect(OC.dirname('/')).toEqual('/');
+ expect(OC.dirname('/')).toEqual('');
+ });
+ it('Returns the root if dir is double root', function() {
+ // TODO: fix the source to make it work like PHP's dirname
+ // expect(OC.dirname('//')).toEqual('/');
+ expect(OC.dirname('//')).toEqual('/'); // oh no...
+ });
+ it('Returns dot if dir is dot', function() {
+ expect(OC.dirname('.')).toEqual('.');
+ });
+ it('Returns dot if no root given', function() {
+ // TODO: fix the source to make it work like PHP's dirname
+ // expect(OC.dirname('some dir')).toEqual('.');
+ expect(OC.dirname('some dir')).toEqual('some dir'); // oh no...
+ });
+ it('Returns the dir name if file name and root path given', function() {
+ // TODO: fix the source to make it work like PHP's dirname
+ // expect(OC.dirname('/some name.txt')).toEqual('/');
+ expect(OC.dirname('/some name.txt')).toEqual('');
+ });
+ it('Returns the dir name if double root path given', function() {
+ expect(OC.dirname('//some name.txt')).toEqual('/'); // how lucky...
+ });
+ it('Returns the dir name if subdir given without root', function() {
+ expect(OC.dirname('subdir/some name.txt')).toEqual('subdir');
+ });
+ it('Returns the dir name if subdir given with root', function() {
+ expect(OC.dirname('/subdir/some name.txt')).toEqual('/subdir');
+ });
+ it('Returns the dir name if subdir given with double root', function() {
+ // TODO: fix the source to make it work like PHP's dirname
+ // expect(OC.dirname('//subdir/some name.txt')).toEqual('/subdir');
+ expect(OC.dirname('//subdir/some name.txt')).toEqual('//subdir'); // oh...
+ });
+ it('Returns the dir name if subdir has dot', function() {
+ expect(OC.dirname('/subdir.dat/some name.txt')).toEqual('/subdir.dat');
+ });
+ it('Returns the dir name if file name is dot', function() {
+ expect(OC.dirname('/subdir/.')).toEqual('/subdir');
+ });
+ it('Returns the dir name if no file name given', function() {
+ expect(OC.dirname('subdir/')).toEqual('subdir');
+ });
+ it('Returns the dir name if no file name given with root', function() {
+ expect(OC.dirname('/subdir/')).toEqual('/subdir');
+ });
+ });
describe('Link functions', function() {
var TESTAPP = 'testapp';
var TESTAPP_ROOT = OC.webroot + '/appsx/testapp';
@@ -67,4 +166,115 @@ describe('Core base tests', function() {
});
});
});
+ describe('Query string building', function() {
+ it('Returns empty string when empty params', function() {
+ expect(OC.buildQueryString()).toEqual('');
+ expect(OC.buildQueryString({})).toEqual('');
+ });
+ it('Encodes regular query strings', function() {
+ expect(OC.buildQueryString({
+ a: 'abc',
+ b: 'def'
+ })).toEqual('a=abc&b=def');
+ });
+ it('Encodes special characters', function() {
+ expect(OC.buildQueryString({
+ unicode: '汉字',
+ })).toEqual('unicode=%E6%B1%89%E5%AD%97');
+ expect(OC.buildQueryString({
+ b: 'spaace value',
+ 'space key': 'normalvalue',
+ 'slash/this': 'amp&ersand'
+ })).toEqual('b=spaace%20value&space%20key=normalvalue&slash%2Fthis=amp%26ersand');
+ });
+ it('Encodes data types and empty values', function() {
+ expect(OC.buildQueryString({
+ 'keywithemptystring': '',
+ 'keywithnull': null,
+ 'keywithundefined': null,
+ something: 'else'
+ })).toEqual('keywithemptystring=&keywithnull&keywithundefined&something=else');
+ expect(OC.buildQueryString({
+ 'booleanfalse': false,
+ 'booleantrue': true
+ })).toEqual('booleanfalse=false&booleantrue=true');
+ expect(OC.buildQueryString({
+ 'number': 123,
+ })).toEqual('number=123');
+ });
+ });
+ describe('Session heartbeat', function() {
+ var clock,
+ oldConfig,
+ loadedStub,
+ routeStub,
+ counter;
+
+ beforeEach(function() {
+ clock = sinon.useFakeTimers();
+ oldConfig = window.oc_config;
+ loadedStub = sinon.stub(OC.Router, 'registerLoadedCallback');
+ routeStub = sinon.stub(OC.Router, 'generate').returns('/heartbeat');
+ counter = 0;
+
+ fakeServer.autoRespond = true;
+ fakeServer.autoRespondAfter = 0;
+ fakeServer.respondWith(/\/heartbeat/, function(xhr) {
+ counter++;
+ xhr.respond(200, {'Content-Type': 'application/json'}, '{}');
+ });
+ });
+ afterEach(function() {
+ clock.restore();
+ window.oc_config = oldConfig;
+ loadedStub.restore();
+ routeStub.restore();
+ });
+ it('sends heartbeat half the session lifetime when heartbeat enabled', function() {
+ window.oc_config = {
+ session_keepalive: true,
+ session_lifetime: 300
+ };
+ window.initCore();
+ expect(loadedStub.calledOnce).toEqual(true);
+ loadedStub.yield();
+ expect(routeStub.calledWith('heartbeat')).toEqual(true);
+
+ expect(counter).toEqual(0);
+
+ // less than half, still nothing
+ clock.tick(100 * 1000);
+ expect(counter).toEqual(0);
+
+ // reach past half (160), one call
+ clock.tick(55 * 1000);
+ expect(counter).toEqual(1);
+
+ // almost there to the next, still one
+ clock.tick(140 * 1000);
+ expect(counter).toEqual(1);
+
+ // past it, second call
+ clock.tick(20 * 1000);
+ expect(counter).toEqual(2);
+ });
+ it('does no send heartbeat when heartbeat disabled', function() {
+ window.oc_config = {
+ session_keepalive: false,
+ session_lifetime: 300
+ };
+ window.initCore();
+ expect(loadedStub.notCalled).toEqual(true);
+ expect(routeStub.notCalled).toEqual(true);
+
+ expect(counter).toEqual(0);
+
+ clock.tick(1000000);
+
+ // still nothing
+ expect(counter).toEqual(0);
+ });
+
+ });
});
+
diff --git a/core/setup.php b/core/setup.php
deleted file mode 100644
index 958376b2cce..00000000000
--- a/core/setup.php
+++ /dev/null
@@ -1,73 +0,0 @@
-<?php
-
-// Check for autosetup:
-$autosetup_file = OC::$SERVERROOT."/config/autoconfig.php";
-if( file_exists( $autosetup_file )) {
- OC_Log::write('core', 'Autoconfig file found, setting up owncloud...', OC_Log::INFO);
- include $autosetup_file;
- $_POST = array_merge ($_POST, $AUTOCONFIG);
- $_REQUEST = array_merge ($_REQUEST, $AUTOCONFIG);
-}
-
-$dbIsSet = isset($_POST['dbtype']);
-$directoryIsSet = isset($_POST['directory']);
-$adminAccountIsSet = isset($_POST['adminlogin']);
-
-if ($dbIsSet AND $directoryIsSet AND $adminAccountIsSet) {
- $_POST['install'] = 'true';
- if( file_exists( $autosetup_file )) {
- unlink($autosetup_file);
- }
-}
-
-OC_Util::addScript( '3rdparty', 'strengthify/jquery.strengthify' );
-OC_Util::addStyle( '3rdparty', 'strengthify/strengthify' );
-OC_Util::addScript('setup');
-
-$hasSQLite = class_exists('SQLite3');
-$hasMySQL = is_callable('mysql_connect');
-$hasPostgreSQL = is_callable('pg_connect');
-$hasOracle = is_callable('oci_connect');
-$hasMSSQL = is_callable('sqlsrv_connect');
-$datadir = OC_Config::getValue('datadirectory', OC::$SERVERROOT.'/data');
-$vulnerableToNullByte = false;
-if(@file_exists(__FILE__."\0Nullbyte")) { // Check if the used PHP version is vulnerable to the NULL Byte attack (CVE-2006-7243)
- $vulnerableToNullByte = true;
-}
-
-// Protect data directory here, so we can test if the protection is working
-OC_Setup::protectDataDirectory();
-
-$opts = array(
- 'hasSQLite' => $hasSQLite,
- 'hasMySQL' => $hasMySQL,
- 'hasPostgreSQL' => $hasPostgreSQL,
- 'hasOracle' => $hasOracle,
- 'hasMSSQL' => $hasMSSQL,
- 'directory' => $datadir,
- 'secureRNG' => OC_Util::secureRNGAvailable(),
- 'htaccessWorking' => OC_Util::isHtAccessWorking(),
- 'vulnerableToNullByte' => $vulnerableToNullByte,
- 'errors' => array(),
- 'dbIsSet' => $dbIsSet,
- 'directoryIsSet' => $directoryIsSet,
-);
-
-if(isset($_POST['install']) AND $_POST['install']=='true') {
- // We have to launch the installation process :
- $e = OC_Setup::install($_POST);
- $errors = array('errors' => $e);
-
- if(count($e) > 0) {
- //OC_Template::printGuestPage("", "error", array("errors" => $errors));
- $options = array_merge($_POST, $opts, $errors);
- OC_Template::printGuestPage("", "installation", $options);
- }
- else {
- header( 'Location: '.OC_Helper::linkToRoute( 'post_setup_check' ));
- exit();
- }
-}
-else {
- OC_Template::printGuestPage("", "installation", $opts);
-}
diff --git a/core/setup/controller.php b/core/setup/controller.php
new file mode 100644
index 00000000000..c628bda609b
--- /dev/null
+++ b/core/setup/controller.php
@@ -0,0 +1,138 @@
+<?php
+/**
+ * Copyright (c) 2013 Bart Visscher <bartv@thisnet.nl>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace OC\Core\Setup;
+
+class Controller {
+ public function run($post) {
+ // Check for autosetup:
+ $post = $this->loadAutoConfig($post);
+ $opts = $this->getSystemInfo();
+
+ if(isset($post['install']) AND $post['install']=='true') {
+ // We have to launch the installation process :
+ $e = \OC_Setup::install($post);
+ $errors = array('errors' => $e);
+
+ if(count($e) > 0) {
+ $options = array_merge($post, $opts, $errors);
+ $this->display($options);
+ }
+ else {
+ $this->finishSetup();
+ }
+ }
+ else {
+ $this->display($opts);
+ }
+ }
+
+ public function display($post) {
+ $defaults = array(
+ 'adminlogin' => '',
+ 'adminpass' => '',
+ 'dbuser' => '',
+ 'dbpass' => '',
+ 'dbname' => '',
+ 'dbtablespace' => '',
+ 'dbhost' => '',
+ );
+ $parameters = array_merge($defaults, $post);
+
+ \OC_Util::addScript( '3rdparty', 'strengthify/jquery.strengthify' );
+ \OC_Util::addStyle( '3rdparty', 'strengthify/strengthify' );
+ \OC_Util::addScript('setup');
+ \OC_Template::printGuestPage('', 'installation', $parameters);
+ }
+
+ public function finishSetup() {
+ header( 'Location: '.\OC_Helper::linkToRoute( 'post_setup_check' ));
+ exit();
+ }
+
+ public function loadAutoConfig($post) {
+ $dbIsSet = isset($post['dbtype']);
+ $directoryIsSet = isset($post['directory']);
+ $adminAccountIsSet = isset($post['adminlogin']);
+
+ $autosetup_file = \OC::$SERVERROOT.'/config/autoconfig.php';
+ if( file_exists( $autosetup_file )) {
+ \OC_Log::write('core', 'Autoconfig file found, setting up owncloud...', \OC_Log::INFO);
+ include $autosetup_file;
+ $post = array_merge ($post, $AUTOCONFIG);
+ }
+
+ if ($dbIsSet AND $directoryIsSet AND $adminAccountIsSet) {
+ $post['install'] = 'true';
+ if( file_exists( $autosetup_file )) {
+ unlink($autosetup_file);
+ }
+ }
+ $post['dbIsSet'] = $dbIsSet;
+ $post['directoryIsSet'] = $directoryIsSet;
+
+ return $post;
+ }
+
+ public function getSystemInfo() {
+ $hasSQLite = class_exists('SQLite3');
+ $hasMySQL = is_callable('mysql_connect');
+ $hasPostgreSQL = is_callable('pg_connect');
+ $hasOracle = is_callable('oci_connect');
+ $hasMSSQL = is_callable('sqlsrv_connect');
+ $databases = array();
+ if ($hasSQLite) {
+ $databases['sqlite'] = 'SQLite';
+ }
+ if ($hasMySQL) {
+ $databases['mysql'] = 'MySQL';
+ }
+ if ($hasPostgreSQL) {
+ $databases['pgsql'] = 'PostgreSQL';
+ }
+ if ($hasOracle) {
+ $databases['oci'] = 'Oracle';
+ }
+ if ($hasMSSQL) {
+ $databases['mssql'] = 'MS SQL';
+ }
+ $datadir = \OC_Config::getValue('datadirectory', \OC::$SERVERROOT.'/data');
+ $vulnerableToNullByte = false;
+ if(@file_exists(__FILE__."\0Nullbyte")) { // Check if the used PHP version is vulnerable to the NULL Byte attack (CVE-2006-7243)
+ $vulnerableToNullByte = true;
+ }
+
+ $errors = array();
+
+ // Protect data directory here, so we can test if the protection is working
+ \OC_Setup::protectDataDirectory();
+ try {
+ $htaccessWorking = \OC_Util::isHtAccessWorking();
+ } catch (\OC\HintException $e) {
+ $errors[] = array(
+ 'error' => $e->getMessage(),
+ 'hint' => $e->getHint()
+ );
+ $htaccessWorking = false;
+ }
+
+ return array(
+ 'hasSQLite' => $hasSQLite,
+ 'hasMySQL' => $hasMySQL,
+ 'hasPostgreSQL' => $hasPostgreSQL,
+ 'hasOracle' => $hasOracle,
+ 'hasMSSQL' => $hasMSSQL,
+ 'databases' => $databases,
+ 'directory' => $datadir,
+ 'secureRNG' => \OC_Util::secureRNGAvailable(),
+ 'htaccessWorking' => $htaccessWorking,
+ 'vulnerableToNullByte' => $vulnerableToNullByte,
+ 'errors' => $errors,
+ );
+ }
+}
diff --git a/core/templates/installation.php b/core/templates/installation.php
index 182fc83a4d4..9670a5e9ee5 100644
--- a/core/templates/installation.php
+++ b/core/templates/installation.php
@@ -48,13 +48,13 @@
<legend><?php print_unescaped($l->t( 'Create an <strong>admin account</strong>' )); ?></legend>
<p class="infield grouptop">
<input type="text" name="adminlogin" id="adminlogin" placeholder=""
- value="<?php p(OC_Helper::init_var('adminlogin')); ?>" autocomplete="off" autofocus required />
+ value="<?php p($_['adminlogin']); ?>" autocomplete="off" autofocus required />
<label for="adminlogin" class="infield"><?php p($l->t( 'Username' )); ?></label>
<img class="svg" src="<?php p(image_path('', 'actions/user.svg')); ?>" alt="" />
</p>
<p class="infield groupbottom">
<input type="password" name="adminpass" data-typetoggle="#show" id="adminpass" placeholder=""
- value="<?php p(OC_Helper::init_var('adminpass')); ?>" required />
+ value="<?php p($_['adminpass']); ?>" required />
<label for="adminpass" class="infield"><?php p($l->t( 'Password' )); ?></label>
<img class="svg" id="adminpass-icon" src="<?php print_unescaped(image_path('', 'actions/password.svg')); ?>" alt="" />
<input type="checkbox" id="show" name="show" />
@@ -75,7 +75,7 @@
<label for="directory"><?php p($l->t( 'Data folder' )); ?></label>
<input type="text" name="directory" id="directory"
placeholder="<?php p(OC::$SERVERROOT."/data"); ?>"
- value="<?php p(OC_Helper::init_var('directory', $_['directory'])); ?>" />
+ value="<?php p($_['directory']); ?>" />
</div>
</fieldset>
<?php endif; ?>
@@ -86,62 +86,16 @@
$hasOtherDB = true; else $hasOtherDB =false; //other than SQLite ?>
<legend><?php p($l->t( 'Configure the database' )); ?></legend>
<div id="selectDbType">
- <?php if($_['hasSQLite']): ?>
- <input type='hidden' id='hasSQLite' value="true" />
- <?php if(!$hasOtherDB): ?>
- <p>SQLite <?php p($l->t( 'will be used' )); ?>.</p>
- <input type="hidden" id="dbtype" name="dbtype" value="sqlite" />
+ <?php foreach($_['databases'] as $type => $label): ?>
+ <?php if(count($_['databases']) === 1): ?>
+ <p class="info"><?php p($label . ' ' . $l->t( 'will be used' )); ?>.</p>
+ <input type="hidden" id="dbtype" name="dbtype" value="<?php p($type) ?>" />
<?php else: ?>
- <input type="radio" name="dbtype" value="sqlite" id="sqlite"
- <?php OC_Helper::init_radio('dbtype', 'sqlite', 'sqlite'); ?>/>
- <label class="sqlite" for="sqlite">SQLite</label>
- <?php endif; ?>
- <?php endif; ?>
-
- <?php if($_['hasMySQL']): ?>
- <input type='hidden' id='hasMySQL' value='true'/>
- <?php if(!$_['hasSQLite'] and !$_['hasPostgreSQL'] and !$_['hasOracle'] and !$_['hasMSSQL']): ?>
- <p>MySQL <?php p($l->t( 'will be used' )); ?>.</p>
- <input type="hidden" id="dbtype" name="dbtype" value="mysql" />
- <?php else: ?>
- <input type="radio" name="dbtype" value="mysql" id="mysql"
- <?php OC_Helper::init_radio('dbtype', 'mysql', 'sqlite'); ?>/>
- <label class="mysql" for="mysql">MySQL</label>
- <?php endif; ?>
- <?php endif; ?>
-
- <?php if($_['hasPostgreSQL']): ?>
- <?php if(!$_['hasSQLite'] and !$_['hasMySQL'] and !$_['hasOracle'] and !$_['hasMSSQL']): ?>
- <p>PostgreSQL <?php p($l->t( 'will be used' )); ?>.</p>
- <input type="hidden" id="dbtype" name="dbtype" value="pgsql" />
- <?php else: ?>
- <label class="pgsql" for="pgsql">PostgreSQL</label>
- <input type="radio" name="dbtype" value='pgsql' id="pgsql"
- <?php OC_Helper::init_radio('dbtype', 'pgsql', 'sqlite'); ?>/>
- <?php endif; ?>
- <?php endif; ?>
-
- <?php if($_['hasOracle']): ?>
- <?php if(!$_['hasSQLite'] and !$_['hasMySQL'] and !$_['hasPostgreSQL'] and !$_['hasMSSQL']): ?>
- <p>Oracle <?php p($l->t( 'will be used' )); ?>.</p>
- <input type="hidden" id="dbtype" name="dbtype" value="oci" />
- <?php else: ?>
- <label class="oci" for="oci">Oracle</label>
- <input type="radio" name="dbtype" value='oci' id="oci"
- <?php OC_Helper::init_radio('dbtype', 'oci', 'sqlite'); ?>/>
- <?php endif; ?>
- <?php endif; ?>
-
- <?php if($_['hasMSSQL']): ?>
- <input type='hidden' id='hasMSSQL' value='true'/>
- <?php if(!$_['hasSQLite'] and !$_['hasMySQL'] and !$_['hasPostgreSQL'] and !$_['hasOracle']): ?>
- <p>MS SQL <?php p($l->t( 'will be used' )); ?>.</p>
- <input type="hidden" id="dbtype" name="dbtype" value="mssql" />
- <?php else: ?>
- <label class="mssql" for="mssql">MS SQL</label>
- <input type="radio" name="dbtype" value='mssql' id="mssql" <?php OC_Helper::init_radio('dbtype', 'mssql', 'sqlite'); ?>/>
- <?php endif; ?>
+ <input type="radio" name="dbtype" value="<?php p($type) ?>" id="<?php p($type) ?>"
+ <?php p($_['dbtype'] === $type ? 'checked="checked" ' : '') ?>/>
+ <label class="<?php p($type) ?>" for="<?php p($type) ?>"><?php p($label) ?></label>
<?php endif; ?>
+ <?php endforeach; ?>
</div>
<?php if($hasOtherDB): ?>
@@ -149,11 +103,11 @@
<p class="infield grouptop">
<label for="dbuser" class="infield"><?php p($l->t( 'Database user' )); ?></label>
<input type="text" name="dbuser" id="dbuser" placeholder=""
- value="<?php p(OC_Helper::init_var('dbuser')); ?>" autocomplete="off" />
+ value="<?php p($_['dbuser']); ?>" autocomplete="off" />
</p>
<p class="infield groupmiddle">
<input type="password" name="dbpass" id="dbpass" placeholder="" data-typetoggle="#dbpassword"
- value="<?php p(OC_Helper::init_var('dbpass')); ?>" />
+ value="<?php p($_['dbpass']); ?>" />
<label for="dbpass" class="infield"><?php p($l->t( 'Database password' )); ?></label>
<input type="checkbox" id="dbpassword" name="dbpassword" />
<label for="dbpassword"></label>
@@ -161,7 +115,7 @@
<p class="infield groupmiddle">
<label for="dbname" class="infield"><?php p($l->t( 'Database name' )); ?></label>
<input type="text" name="dbname" id="dbname" placeholder=""
- value="<?php p(OC_Helper::init_var('dbname')); ?>"
+ value="<?php p($_['dbname']); ?>"
autocomplete="off" pattern="[0-9a-zA-Z$_-]+" />
</p>
<?php if($_['hasOracle']): ?>
@@ -169,14 +123,14 @@
<p class="infield groupmiddle">
<label for="dbtablespace" class="infield"><?php p($l->t( 'Database tablespace' )); ?></label>
<input type="text" name="dbtablespace" id="dbtablespace" placeholder=""
- value="<?php p(OC_Helper::init_var('dbtablespace')); ?>" autocomplete="off" />
+ value="<?php p($_['dbtablespace']); ?>" autocomplete="off" />
</p>
</div>
<?php endif; ?>
<p class="infield groupbottom">
<label for="dbhost" class="infield"><?php p($l->t( 'Database host' )); ?></label>
<input type="text" name="dbhost" id="dbhost" placeholder=""
- value="<?php p(OC_Helper::init_var('dbhost')); ?>" />
+ value="<?php p($_['dbhost']); ?>" />
</p>
</div>
<?php endif; ?>
diff --git a/core/templates/layout.base.php b/core/templates/layout.base.php
index 8cd237deea1..bae52a73234 100644
--- a/core/templates/layout.base.php
+++ b/core/templates/layout.base.php
@@ -11,7 +11,7 @@
<?php p($theme->getTitle()); ?>
</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, maximum-scale=1.0">
<link rel="shortcut icon" href="<?php print_unescaped(image_path('', 'favicon.png')); ?>" />
<link rel="apple-touch-icon-precomposed" href="<?php print_unescaped(image_path('', 'favicon-touch.png')); ?>" />
<?php foreach ($_['cssfiles'] as $cssfile): ?>
diff --git a/core/templates/layout.guest.php b/core/templates/layout.guest.php
index 47ca5903dab..6a96b17b100 100644
--- a/core/templates/layout.guest.php
+++ b/core/templates/layout.guest.php
@@ -11,7 +11,7 @@
<?php p($theme->getTitle()); ?>
</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <meta name="viewport" content="width=device-width, minimum-scale=1.0, maximum-scale=1.0">
<meta name="apple-itunes-app" content="app-id=543672169">
<link rel="shortcut icon" href="<?php print_unescaped(image_path('', 'favicon.png')); ?>" />
<link rel="apple-touch-icon-precomposed" href="<?php print_unescaped(image_path('', 'favicon-touch.png')); ?>" />
diff --git a/core/templates/layout.user.php b/core/templates/layout.user.php
index 89987625d63..bc1c700402e 100644
--- a/core/templates/layout.user.php
+++ b/core/templates/layout.user.php
@@ -48,15 +48,16 @@
<a href="<?php print_unescaped(link_to('', 'index.php')); ?>" title="" id="owncloud"><img class="svg"
src="<?php print_unescaped(image_path('', 'logo-wide.svg')); ?>" alt="<?php p($theme->getName()); ?>" /></a>
<div id="logo-claim" style="display:none;"><?php p($theme->getLogoClaim()); ?></div>
- <ul id="settings" class="svg">
+ <div id="settings" class="svg">
<span id="expand" tabindex="0" role="link">
<span id="expandDisplayName"><?php p(trim($_['user_displayname']) != '' ? $_['user_displayname'] : $_['user_uid']) ?></span>
- <img class="svg" src="<?php print_unescaped(image_path('', 'actions/caret.svg')); ?>" />
- <?php if ($_['enableAvatars']): ?>
- <div class="avatardiv"></div>
- <?php endif; ?>
+ <img class="svg" alt="" src="<?php print_unescaped(image_path('', 'actions/caret.svg')); ?>" />
</span>
+ <?php if ($_['enableAvatars']): ?>
+ <div class="avatardiv"></div>
+ <?php endif; ?>
<div id="expanddiv">
+ <ul>
<?php foreach($_['settingsnavigation'] as $entry):?>
<li>
<a href="<?php print_unescaped($entry['href']); ?>" title=""
@@ -72,8 +73,9 @@
<?php p($l->t('Log out'));?>
</a>
</li>
+ </ul>
</div>
- </ul>
+ </div>
<form class="searchbox" action="#" method="post">
<input id="searchbox" class="svg" type="search" name="query"
@@ -83,37 +85,40 @@
</div></header>
<nav><div id="navigation">
- <ul id="apps" class="svg">
- <div class="wrapper"><!-- for sticky footer of apps management -->
+ <div id="apps" class="svg">
+ <ul class="wrapper"><!-- for sticky footer of apps management -->
<?php foreach($_['navigation'] as $entry): ?>
<li data-id="<?php p($entry['id']); ?>">
<a href="<?php print_unescaped($entry['href']); ?>" title=""
<?php if( $entry['active'] ): ?> class="active"<?php endif; ?>>
- <img class="icon svg" src="<?php print_unescaped($entry['icon']); ?>"/>
+ <img class="icon svg" alt="" src="<?php print_unescaped($entry['icon']); ?>"/>
<span>
<?php p($entry['name']); ?>
</span>
</a>
</li>
<?php endforeach; ?>
+
<?php if(OC_User::isAdminUser(OC_User::getUser())): ?>
- <div class="push"></div><!-- for for sticky footer of apps management -->
+ <li class="push"></li><!-- for sticky footer of apps management -->
<?php endif; ?>
- </div>
+ </ul>
<!-- show "More apps" link to app administration directly in app navigation, as sticky footer -->
<?php if(OC_User::isAdminUser(OC_User::getUser())): ?>
- <li id="apps-management">
+ <ul id="apps-management">
+ <li>
<a href="<?php print_unescaped(OC_Helper::linkToRoute('settings_apps').'?installed'); ?>" title=""
<?php if( $_['appsmanagement_active'] ): ?> class="active"<?php endif; ?>>
- <img class="icon svg" src="<?php print_unescaped(OC_Helper::imagePath('settings', 'apps.svg')); ?>"/>
+ <img class="icon svg" alt="" src="<?php print_unescaped(OC_Helper::imagePath('settings', 'apps.svg')); ?>"/>
<span>
<?php p($l->t('Apps')); ?>
</span>
</a>
</li>
+ </ul>
<?php endif; ?>
- </ul>
+ </div>
</div></nav>
<div id="content-wrapper">