merged from upstream

This commit is contained in:
Florian Hülsmann 2012-04-02 23:54:18 +02:00
commit bd9fa658de
75 changed files with 3208 additions and 492 deletions

1954
3rdparty/Archive/Tar.php vendored Normal file

File diff suppressed because it is too large Load Diff

5
README
View File

@ -3,10 +3,11 @@ A personal cloud which runs on your own server.
http://ownCloud.org
Installation instructions: http://owncloud.org/support/setup-and-installation/
Source code: http://gitorious.org/owncloud
Installation instructions: http://owncloud.org/support
Source code: http://gitorious.org/owncloud
Mailing list: http://mail.kde.org/mailman/listinfo/owncloud
IRC channel: http://webchat.freenode.net/?channels=owncloud
Diaspora: https://joindiaspora.com/u/owncloud
Identi.ca: http://identi.ca/owncloud

View File

@ -10,7 +10,7 @@ ob_start();
require_once('../../../../lib/base.php');
OC_JSON::checkLoggedIn();
OC_Util::checkAppEnabled('calendar');
$nl = "\n";
$nl = "\n\r";
$progressfile = OC::$APPSROOT . '/apps/calendar/import_tmp/' . md5(session_id()) . '.txt';
if(is_writable('import_tmp/')){
$progressfopen = fopen($progressfile, 'w');

View File

@ -11,7 +11,7 @@ OC_Util::checkLoggedIn();
OC_Util::checkAppEnabled('calendar');
$cal = isset($_GET['calid']) ? $_GET['calid'] : NULL;
$event = isset($_GET['eventid']) ? $_GET['eventid'] : NULL;
$nl = "\n";
$nl = "\n\r";
if(isset($cal)){
$calendar = OC_Calendar_App::getCalendar($cal);
$calobjects = OC_Calendar_Object::all($cal);

View File

@ -19,6 +19,11 @@
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
*/
function bailOut($msg) {
OC_JSON::error(array('data' => array('message' => $msg)));
OC_Log::write('contacts','ajax/saveproperty.php: '.$msg, OC_Log::DEBUG);
exit();
}
// Init owncloud
require_once('../../../lib/base.php');
@ -27,7 +32,10 @@ require_once('../../../lib/base.php');
OC_JSON::checkLoggedIn();
OC_JSON::checkAppEnabled('contacts');
$id = $_GET['id'];
$id = isset($_GET['id'])?$_GET['id']:null;
if(!$id) {
bailOut(OC_Contacts_App::$l10n->t('id is not set.'));
}
$card = OC_Contacts_App::getContactObject( $id );
OC_Contacts_VCard::delete($id);

View File

@ -0,0 +1,68 @@
<?php
class OC_Migration_Provider_Contacts extends OC_Migration_Provider{
// Create the xml for the user supplied
function export( ){
$options = array(
'table'=>'contacts_addressbooks',
'matchcol'=>'userid',
'matchval'=>$this->uid,
'idcol'=>'id'
);
$ids = $this->content->copyRows( $options );
$options = array(
'table'=>'contacts_cards',
'matchcol'=>'addressbookid',
'matchval'=>$ids
);
// Export tags
$ids2 = $this->content->copyRows( $options );
// If both returned some ids then they worked
if( is_array( $ids ) && is_array( $ids2 ) )
{
return true;
} else {
return false;
}
}
// Import function for bookmarks
function import( ){
switch( $this->appinfo->version ){
default:
// All versions of the app have had the same db structure, so all can use the same import function
$query = $this->content->prepare( "SELECT * FROM contacts_addressbooks WHERE userid LIKE ?" );
$results = $query->execute( array( $this->olduid ) );
$idmap = array();
while( $row = $results->fetchRow() ){
// Import each bookmark, saving its id into the map
$query = OC_DB::prepare( "INSERT INTO *PREFIX*contacts_addressbooks (`userid`, `displayname`, `uri`, `description`, `ctag`) VALUES (?, ?, ?, ?, ?)" );
$query->execute( array( $this->uid, $row['displayname'], $row['uri'], $row['description'], $row['ctag'] ) );
// Map the id
$idmap[$row['id']] = OC_DB::insertid();
}
// Now tags
foreach($idmap as $oldid => $newid){
$query = $this->content->prepare( "SELECT * FROM contacts_cards WHERE addressbookid LIKE ?" );
$results = $query->execute( array( $oldid ) );
while( $row = $results->fetchRow() ){
// Import the tags for this bookmark, using the new bookmark id
$query = OC_DB::prepare( "INSERT INTO *PREFIX*contacts_cards (`addressbookid`, `fullname`, `carddata`, `uri`, `lastmodified`) VALUES (?, ?, ?, ?, ?)" );
$query->execute( array( $newid, $row['fullname'], $row['carddata'], $row['uri'], $row['lastmodified'] ) );
}
}
// All done!
break;
}
return true;
}
}
// Load the provider
new OC_Migration_Provider_Contacts( 'contacts' );

View File

@ -10,8 +10,6 @@
#contacts_propertymenu_button { position:absolute;top:15px;right:150px; background:url('../../../core/img/actions/add.svg') no-repeat center; }
#contacts_propertymenu { background-color: #fff; position:absolute;top:40px;right:150px; overflow:hidden; text-overflow:ellipsis; /*border: thin solid #1d2d44;*/ -moz-box-shadow:0 0 10px #000; -webkit-box-shadow:0 0 10px #000; box-shadow:0 0 10px #000; -moz-border-radius:0.5em; -webkit-border-radius:0.5em; border-radius:0.5em; -moz-border-radius:0.5em; -webkit-border-radius:0.5em; border-radius:0.5em; }
#contacts_propertymenu li { display: block; font-weight: bold; height: 20px; width: 100px; }
/*#contacts_propertymenu li:first-child { border-top: thin solid #1d2d44; -moz-border-radius-topleft:0.5em; -webkit-border-top-left-radius:0.5em; border-top-left-radius:0.5em; -moz-border-radius-topright:0.5em; -webkit-border-top-right-radius:0.5em; border-top-right-radius:0.5em; }
#contacts_propertymenu li:last-child { border-bottom: thin solid #1d2d44; -moz-border-radius-bottomleft:0.5em; -webkit-border-bottom-left-radius:0.5em; border-bottom-left-radius:0.5em; -moz-border-radius-bottomright:0.5em; -webkit-border-bottom-right-radius:0.5em; border-bottom-right-radius:0.5em; }*/
#contacts_propertymenu li a { padding: 3px; display: block }
#contacts_propertymenu li:hover { background-color: #1d2d44; }
#contacts_propertymenu li a:hover { color: #fff }
@ -25,54 +23,12 @@
#card input[type="text"],input[type="email"],input[type="tel"],input[type="date"], select { background-color: #f8f8f8; border: 0 !important; -webkit-appearance:none !important; -moz-appearance:none !important; -webkit-box-sizing:none !important; -moz-box-sizing:none !important; box-sizing:none !important; -moz-box-shadow: none; -webkit-box-shadow: none; box-shadow: none; -moz-border-radius: 0px; -webkit-border-radius: 0px; border-radius: 0px; float: left; }
#card input[type="text"]:hover, input[type="text"]:focus, input[type="text"]:active,input[type="email"]:hover,input[type="tel"]:hover,input[type="date"]:hover,input[type="date"],input[type="date"]:hover,input[type="date"]:active,input[type="date"]:active,input[type="date"]:active,input[type="email"]:active,input[type="tel"]:active, select:hover, select:focus, select:active { border: 0 !important; -webkit-appearance:textfield; -moz-appearance:textfield; -webkit-box-sizing:content-box; -moz-box-sizing:content-box; box-sizing:content-box; background:#fff; color:#333; border:1px solid #ddd; -moz-box-shadow:0 1px 1px #fff, 0 2px 0 #bbb inset; -webkit-box-shadow:0 1px 1px #fff, 0 1px 0 #bbb inset; box-shadow:0 1px 1px #fff, 0 1px 0 #bbb inset; -moz-border-radius:.5em; -webkit-border-radius:.5em; border-radius:.5em; outline:none; float: left; }
input[type="text"]:invalid,input[type="email"]:invalid,input[type="tel"]:invalid,input[type="date"]:invalid { background-color: #ffc0c0 !important; }
/*input[type="text"]:valid,input[type="email"]:valid,input[type="tel"]:valid,input[type="date"]:valid { background-color: #b1d28f !important; }*/
dl.form
{
width: 100%;
float: left;
clear: right;
margin: 0;
padding: 0;
}
.form dt
{
display: table-cell;
clear: left;
float: left;
width: 7em;
/*overflow: hidden;*/
margin: 0;
padding: 0.8em 0.5em 0 0;
font-weight: bold;
text-align:right;
text-overflow:ellipsis;
o-text-overflow: ellipsis;
vertical-align: text-bottom;
/*
white-space: pre-wrap;
white-space: -moz-pre-wrap !important;
white-space: -pre-wrap;
white-space: -o-pre-wrap;*/
}
.form dd
{
display: table-cell;
clear: right;
float: left;
margin: 0;
padding: 0px;
white-space: nowrap;
vertical-align: text-bottom;
/*min-width: 20em;*/
/*background-color: yellow;*/
}
dl.form { width: 100%; float: left; clear: right; margin: 0; padding: 0; }
.form dt { display: table-cell; clear: left; float: left; width: 7em; margin: 0; padding: 0.8em 0.5em 0 0; font-weight: bold; text-align:right; text-overflow:ellipsis; o-text-overflow: ellipsis; vertical-align: text-bottom;/* white-space: pre-wrap; white-space: -moz-pre-wrap !important; white-space: -pre-wrap; white-space: -o-pre-wrap;*/ }
.form dd { display: table-cell; clear: right; float: left; margin: 0; padding: 0px; white-space: nowrap; vertical-align: text-bottom; }
.loading { background: url('../../../core/img/loading.gif') no-repeat center !important; /*cursor: progress; */ cursor: wait; }
/*.add { cursor: pointer; width: 25px; height: 25px; margin: 0px; float: right; position:relative; content: "\+"; font-weight: bold; color: #666; font-size: large; bottom: 0px; right: 0px; clear: both; text-align: center; vertical-align: bottom; display: none; }*/
.listactions { height: 1em; width:60px; float: left; clear: right; }
.add,.edit,.delete,.mail, .globe { cursor: pointer; width: 20px; height: 20px; margin: 0; float: left; position:relative; display: none; }
.add { background:url('../../../core/img/actions/add.svg') no-repeat center; clear: both; }
@ -82,75 +38,21 @@ dl.form
/*.globe { background:url('../img/globe.svg') no-repeat center; }*/
.globe { background:url('../../../core/img/actions/public.svg') no-repeat center; }
#messagebox_msg { font-weight: bold; font-size: 1.2em; }
/* Name editor */
#edit_name_dialog {
/*width: 25em;*/
padding:0;
}
#edit_name_dialog > input {
width: 15em;
}
/* Address editor */
#edit_address_dialog {
/*width: 30em;*/
}
#edit_address_dialog > input {
width: 15em;
}
#edit_name_dialog { padding:0; }
#edit_name_dialog > input { width: 15em; }
#edit_address_dialog { /*width: 30em;*/ }
#edit_address_dialog > input { width: 15em; }
#edit_photo_dialog_img { display: block; width: 150; height: 200; border: thin solid black; }
#fn { float: left; }
/**
* Create classes form, floateven and floatodd which flows left and right respectively.
*/
.contactsection {
float: left;
min-width: 30em;
max-width: 40em;
margin: 0.5em;
border: thin solid lightgray;
-webkit-border-radius: 0.5em;
-moz-border-radius: 0.5em;
border-radius: 0.5em;
background-color: #f8f8f8;
}
.contactsection { float: left; min-width: 30em; max-width: 40em; margin: 0.5em; border: thin solid lightgray; -webkit-border-radius: 0.5em; -moz-border-radius: 0.5em; border-radius: 0.5em; background-color: #f8f8f8; }
.contactpart legend {
/*background: #fff;
font-weight: bold;
left: 1em;
border: thin solid gray;
-webkit-border-radius: 0.5em;
-moz-border-radius: 0.5em;
border-radius: 0.5em;
padding: 3px;*/
width:auto; padding:.3em; border:1px solid #ddd; font-weight:bold; cursor:pointer; background:#f8f8f8; color:#555; text-shadow:#fff 0 1px 0; -moz-box-shadow:0 1px 1px #fff, 0 1px 1px #fff inset; -webkit-box-shadow:0 1px 1px #fff, 0 1px 1px #fff inset; -moz-border-radius:.5em; -webkit-border-radius:.5em; border-radius:.5em;
}
/*#contacts_details_photo {
cursor: pointer;
z-index:1;
margin: auto;
}
*/
#cropbox {
margin: auto;
}
.contactpart legend { width:auto; padding:.3em; border:1px solid #ddd; font-weight:bold; cursor:pointer; background:#f8f8f8; color:#555; text-shadow:#fff 0 1px 0; -moz-box-shadow:0 1px 1px #fff, 0 1px 1px #fff inset; -webkit-box-shadow:0 1px 1px #fff, 0 1px 1px #fff inset; -moz-border-radius:.5em; -webkit-border-radius:.5em; border-radius:.5em; }
#cropbox { margin: auto; }
/* Photo editor */
/*#contacts_details_photo_wrapper {
z-index: 1000;
}*/
#contacts_details_photo {
border-radius: 0.5em;
border: thin solid #bbb;
padding: 0.5em;
margin: 1em 1em 1em 7em;
cursor: pointer;
/*background: #f8f8f8;*/
background: url(../../../core/img/loading.gif) no-repeat center center;
clear: right;
}
#contacts_details_photo { border-radius: 0.5em; border: thin solid #bbb; padding: 0.5em; margin: 1em 1em 1em 7em; cursor: pointer; background: url(../../../core/img/loading.gif) no-repeat center center; clear: right; }
#contacts_details_photo:hover { background: #fff; }
#contacts_details_photo_progress { margin: 0.3em 0.3em 0.3em 7em; clear: left; }
/* Address editor */
@ -168,13 +70,6 @@ dl.addresscard dd > ul { margin: 0.3em; padding: 0.3em; }
#adr_zipcode {}
#adr_country {}
.delimiter {
height: 10px;
clear: both;
}
/*input[type="text"] { float: left; max-width: 15em; }
input[type="radio"] { float: left; -khtml-appearance: none; width: 20px; height: 20px; vertical-align: middle; }*/
#file_upload_target, #crop_target { display:none; }
#file_upload_start { opacity:0; filter:alpha(opacity=0); z-index:1; position:absolute; left:0; top:0; cursor:pointer; width:0; height:0;}

View File

@ -213,19 +213,27 @@ Contacts={
honpre:'',
honsuf:'',
data:undefined,
update:function() {
update:function(id) {
// Make sure proper DOM is loaded.
console.log('Card.update(), #n: ' + $('#n').length);
var newid;
console.log('Card.update(), id: ' + id);
console.log('Card.update(), #contacts: ' + $('#contacts li').length);
if($('#n').length == 0 && $('#contacts li').length > 0) {
if(id == undefined) {
newid = $('#contacts li:first-child').data('id');
} else {
newid = id;
}
if($('#contacts li').length > 0) {
$.getJSON(OC.filePath('contacts', 'ajax', 'loadcard.php'),{},function(jsondata){
if(jsondata.status == 'success'){
$('#rightcontent').html(jsondata.data.page);
Contacts.UI.loadHandlers();
if($('#contacts li').length > 0) {
var firstid = $('#contacts li:first-child').data('id');
console.log('trying to load: ' + firstid);
$.getJSON(OC.filePath('contacts', 'ajax', 'contactdetails.php'),{'id':firstid},function(jsondata){
//var newid = $('#contacts li:first-child').data('id');
//$('#contacts li:first-child').addClass('active');
$('#leftcontent li[data-id="'+newid+'"]').addClass('active');
console.log('trying to load: ' + newid);
$.getJSON(OC.filePath('contacts', 'ajax', 'contactdetails.php'),{'id':newid},function(jsondata){
if(jsondata.status == 'success'){
Contacts.UI.Card.loadContact(jsondata.data);
} else{
@ -300,35 +308,49 @@ Contacts={
}
});
},
delete: function() {
delete:function() {
$('#contacts_deletecard').tipsy('hide');
$.getJSON('ajax/deletecard.php',{'id':this.id},function(jsondata){
if(jsondata.status == 'success'){
$('#leftcontent [data-id="'+jsondata.data.id+'"]').remove();
$('#rightcontent').data('id','');
//$('#rightcontent').empty();
this.id = this.fn = this.fullname = this.shortname = this.famname = this.givname = this.addname = this.honpre = this.honsuf = '';
this.data = undefined;
// Load first in list.
if($('#contacts li').length > 0) {
Contacts.UI.Card.update();
} else {
// load intro page
$.getJSON('ajax/loadintro.php',{},function(jsondata){
if(jsondata.status == 'success'){
id = '';
$('#rightcontent').data('id','');
$('#rightcontent').html(jsondata.data.page);
OC.dialogs.confirm(t('contacts', 'Are you sure you want to delete this contact?'), t('contacts', 'Warning'), function(answer) {
if(answer == true) {
$.getJSON('ajax/deletecard.php',{'id':Contacts.UI.Card.id},function(jsondata){
if(jsondata.status == 'success'){
var newid = '';
var curlistitem = $('#leftcontent [data-id="'+jsondata.data.id+'"]');
var newlistitem = curlistitem.prev();
console.log('Previous: ' + newlistitem);
if(newlistitem == undefined) {
newlistitem = curlistitem.next();
}
else{
OC.dialogs.alert(jsondata.data.message, t('contacts', 'Error'));
curlistitem.remove();
if(newlistitem != undefined) {
newid = newlistitem.data('id');
}
});
}
}
else{
OC.dialogs.alert(jsondata.data.message, t('contacts', 'Error'));
//alert(jsondata.data.message);
$('#rightcontent').data('id',newid);
//$('#rightcontent').empty();
this.id = this.fn = this.fullname = this.shortname = this.famname = this.givname = this.addname = this.honpre = this.honsuf = '';
this.data = undefined;
// Load first in list.
if($('#contacts li').length > 0) {
Contacts.UI.Card.update(newid);
} else {
// load intro page
$.getJSON('ajax/loadintro.php',{},function(jsondata){
if(jsondata.status == 'success'){
id = '';
$('#rightcontent').data('id','');
$('#rightcontent').html(jsondata.data.page);
}
else{
OC.dialogs.alert(jsondata.data.message, t('contacts', 'Error'));
}
});
}
}
else{
OC.dialogs.alert(jsondata.data.message, t('contacts', 'Error'));
//alert(jsondata.data.message);
}
});
}
});
return false;
@ -1232,6 +1254,7 @@ $(document).ready(function(){
*/
$('#leftcontent li').live('click',function(){
var id = $(this).data('id');
$(this).addClass('active');
var oldid = $('#rightcontent').data('id');
if(oldid != 0){
$('#leftcontent li[data-id="'+oldid+'"]').removeClass('active');

View File

@ -56,13 +56,6 @@ $id = isset($_['id']) ? $_['id'] : '';
<dd style="display:none;" class="propertycontainer" id="nickname_value" data-element="NICKNAME"><input id="nickname" required="required" name="value[NICKNAME]" type="text" class="contacts_property" style="width:16em;" name="value" value="" placeholder="<?php echo $l->t('Enter nickname'); ?>" /><a class="action delete" onclick="$(this).tipsy('hide');Contacts.UI.Card.deleteProperty(this, 'single');" title="<?php echo $l->t('Delete'); ?>"></a></dd>
<dt style="display:none;" id="bday_label" data-element="BDAY"><label for="bday"><?php echo $l->t('Birthday'); ?></label></dt>
<dd style="display:none;" class="propertycontainer" id="bday_value" data-element="BDAY"><input id="bday" required="required" name="value" type="text" class="contacts_property" value="" placeholder="<?php echo $l->t('dd-mm-yyyy'); ?>" /><a class="action delete" onclick="$(this).tipsy('hide');Contacts.UI.Card.deleteProperty(this, 'single');" title="<?php echo $l->t('Delete'); ?>"></a></dd>
<!-- dt id="categories_label" data-element="CATEGORIES"><label for="categories"><?php echo $l->t('Categories'); ?></label></dt>
<dd class="propertycontainer" id="categories_value" data-element="CATEGORIES">
<select class="contacts_property" multiple="multiple" id="categories" name="value[]">
<?php echo html_select_options($_['categories'], array(), array('combine'=>true)) ?>
</select>
<a class="action edit" onclick="$(this).tipsy('hide');OCCategories.edit();" title="<?php echo $l->t('Edit categories'); ?>"></a>
</dd -->
<dt style="display:none;" id="categories_label" data-element="CATEGORIES"><label for="categories"><?php echo $l->t('Categories'); ?></label></dt>
<dd style="display:none;" class="propertycontainer" id="categories_value" data-element="CATEGORIES"><input id="categories" required="required" name="value[CATEGORIES]" type="text" class="contacts_property" style="width:16em;" name="value" value="" placeholder="<?php echo $l->t('Categories'); ?>" /><a class="action delete" onclick="$(this).tipsy('hide');Contacts.UI.Card.deleteProperty(this, 'single');" title="<?php echo $l->t('Delete'); ?>"></a><a class="action edit" onclick="$(this).tipsy('hide');OCCategories.edit();" title="<?php echo $l->t('Edit categories'); ?>"></a></dd>
</dl>
@ -131,6 +124,7 @@ $(document).ready(function(){
if('<?php echo $id; ?>'!='') {
$.getJSON(OC.filePath('contacts', 'ajax', 'contactdetails.php'),{'id':'<?php echo $id; ?>'},function(jsondata){
if(jsondata.status == 'success'){
$('#leftcontent li[data-id="<?php echo $id; ?>"]').addClass('active');
Contacts.UI.Card.loadContact(jsondata.data);
}
else{

View File

@ -7,7 +7,8 @@
*/
OC::$CLASSPATH['OC_Archive'] = 'apps/files_archive/lib/archive.php';
foreach(array('ZIP') as $type){
OC::$CLASSPATH['Archive_Tar'] = '3rdparty/Archive/Tar.php';
foreach(array('ZIP','TAR') as $type){
OC::$CLASSPATH['OC_Archive_'.$type] = 'apps/files_archive/lib/'.strtolower($type).'.php';
}

View File

@ -7,4 +7,7 @@
<licence>AGPL</licence>
<author>Robin Appelman</author>
<require>3</require>
<types>
<filesystem/>
</types>
</info>

View File

@ -11,5 +11,9 @@ $(document).ready(function() {
window.location='index.php?dir='+encodeURIComponent($('#dir').val()).replace(/%2F/g, '/')+'/'+encodeURIComponent(filename);
});
FileActions.setDefault('application/zip','Open');
FileActions.register('application/x-gzip','Open','',function(filename){
window.location='index.php?dir='+encodeURIComponent($('#dir').val()).replace(/%2F/g, '/')+'/'+encodeURIComponent(filename);
});
FileActions.setDefault('application/x-gzip','Open');
}
});

View File

@ -17,6 +17,15 @@ abstract class OC_Archive{
switch($ext){
case '.zip':
return new OC_Archive_ZIP($path);
case '.gz':
case '.bz':
case '.bz2':
if(strpos($path,'.tar.')){
return new OC_Archive_TAR($path);
}
break;
case '.tgz':
return new OC_Archive_TAR($path);
}
}
@ -77,6 +86,13 @@ abstract class OC_Archive{
* @return bool
*/
abstract function extractFile($path,$dest);
/**
* extract the archive
* @param string path
* @param string dest
* @return bool
*/
abstract function extract($dest);
/**
* check if a file or folder exists in the archive
* @param string path

View File

@ -125,7 +125,7 @@ class OC_Filestorage_Archive extends OC_Filestorage_Common{
self::$rootView=new OC_FilesystemView('');
}
self::$enableAutomount=false;//prevent recursion
$supported=array('zip');
$supported=array('zip','tar.gz','tar.bz2','tgz');
foreach($supported as $type){
$ext='.'.$type.'/';
if(($pos=strpos(strtolower($path),$ext))!==false){
@ -139,4 +139,8 @@ class OC_Filestorage_Archive extends OC_Filestorage_Common{
}
self::$enableAutomount=true;
}
public function rename($path1,$path2){
return $this->archive->rename($path1,$path2);
}
}

View File

@ -0,0 +1,277 @@
<?php
/**
* Copyright (c) 2012 Robin Appelman <icewind@owncloud.com>
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
class OC_Archive_TAR extends OC_Archive{
const PLAIN=0;
const GZIP=1;
const BZIP=2;
/**
* @var Archive_Tar tar
*/
private $tar=null;
private $path;
function __construct($source){
$types=array(null,'gz','bz');
$this->path=$source;
$this->tar=new Archive_Tar($source,$types[self::getTarType($source)]);
}
/**
* try to detect the type of tar compression
* @param string file
* @return str
*/
static public function getTarType($file){
if(strpos($file,'.')){
$extention=substr($file,strrpos($file,'.'));
switch($extention){
case 'gz':
case 'tgz':
return self::GZIP;
case 'bz':
case 'bz2':
return self::BZIP;
default:
return self::PLAIN;
}
}else{
return self::PLAIN;
}
}
/**
* add an empty folder to the archive
* @param string path
* @return bool
*/
function addFolder($path){
$tmpBase=get_temp_dir().'/';
if(substr($path,-1,1)!='/'){
$path.='/';
}
if($this->fileExists($path)){
return false;
}
mkdir($tmpBase.$path);
$result=$this->tar->addModify(array($tmpBase.$path),'',$tmpBase);
rmdir($tmpBase.$path);
return $result;
}
/**
* add a file to the archive
* @param string path
* @param string source either a local file or string data
* @return bool
*/
function addFile($path,$source=''){
if($this->fileExists($path)){
$this->remove($path);
}
if(file_exists($source)){
$header=array();
$dummy='';
$this->tar->_openAppend();
$result=$this->tar->_addfile($source,$header,$dummy,$dummy,$path);
}else{
$result=$this->tar->addString($path,$source);
}
return $result;
}
/**
* rename a file or folder in the archive
* @param string source
* @param string dest
* @return bool
*/
function rename($source,$dest){
//no proper way to delete, rename entire archive, rename file and remake archive
$tmp=OC_Helper::tmpFolder();
$this->tar->extract($tmp);
rename($tmp.$source,$tmp.$dest);
$this->tar=null;
unlink($this->path);
$types=array(null,'gz','bz');
$this->tar=new Archive_Tar($this->path,$types[self::getTarType($this->path)]);
$this->tar->createModify(array($tmp),'',$tmp.'/');
}
private function getHeader($file){
$headers=$this->tar->listContent();
foreach($headers as $header){
if($file==$header['filename'] or $file.'/'==$header['filename']){
return $header;
}
}
return null;
}
/**
* get the uncompressed size of a file in the archive
* @param string path
* @return int
*/
function filesize($path){
$stat=$this->getHeader($path);
return $stat['size'];
}
/**
* get the last modified time of a file in the archive
* @param string path
* @return int
*/
function mtime($path){
$stat=$this->getHeader($path);
return $stat['mtime'];
}
/**
* get the files in a folder
* @param path
* @return array
*/
function getFolder($path){
$files=$this->getFiles();
$folderContent=array();
$pathLength=strlen($path);
foreach($files as $file){
if(substr($file,0,$pathLength)==$path and $file!=$path){
if(strrpos(substr($file,0,-1),'/')<=$pathLength){
$folderContent[]=substr($file,$pathLength);
}
}
}
return $folderContent;
}
/**
*get all files in the archive
* @return array
*/
function getFiles(){
$headers=$this->tar->listContent();
$files=array();
foreach($headers as $header){
$files[]=$header['filename'];
}
return $files;
}
/**
* get the content of a file
* @param string path
* @return string
*/
function getFile($path){
return $this->tar->extractInString($path);
}
/**
* extract a single file from the archive
* @param string path
* @param string dest
* @return bool
*/
function extractFile($path,$dest){
$tmp=OC_Helper::tmpFolder();
if(!$this->fileExists($path)){
return false;
}
$success=$this->tar->extractList(array($path),$tmp);
if($success){
rename($tmp.$path,$dest);
}
OC_Helper::rmdirr($tmp);
return $success;
}
/**
* extract the archive
* @param string path
* @param string dest
* @return bool
*/
function extract($dest){
return $this->tar->extract($dest);
}
/**
* check if a file or folder exists in the archive
* @param string path
* @return bool
*/
function fileExists($path){
return $this->getHeader($path)!==null;
}
/**
* remove a file or folder from the archive
* @param string path
* @return bool
*/
function remove($path){
if(!$this->fileExists($path)){
return false;
}
//no proper way to delete, extract entire archive, delete file and remake archive
$tmp=OC_Helper::tmpFolder();
$this->tar->extract($tmp);
OC_Helper::rmdirr($tmp.$path);
$this->tar=null;
unlink($this->path);
$this->reopen();
$this->tar->createModify(array($tmp),'',$tmp);
return true;
}
/**
* get a file handler
* @param string path
* @param string mode
* @return resource
*/
function getStream($path,$mode){
if(strrpos($path,'.')!==false){
$ext=substr($path,strrpos($path,'.'));
}else{
$ext='';
}
$tmpFile=OC_Helper::tmpFile($ext);
if($this->fileExists($path)){
$this->extractFile($path,$tmpFile);
}elseif($mode=='r' or $mode=='rb'){
return false;
}
if($mode=='r' or $mode=='rb'){
return fopen($tmpFile,$mode);
}else{
OC_CloseStreamWrapper::$callBacks[$tmpFile]=array($this,'writeBack');
self::$tempFiles[$tmpFile]=$path;
return fopen('close://'.$tmpFile,$mode);
}
}
private static $tempFiles=array();
/**
* write back temporary files
*/
function writeBack($tmpFile){
if(isset(self::$tempFiles[$tmpFile])){
$this->addFile(self::$tempFiles[$tmpFile],$tmpFile);
unlink($tmpFile);
}
}
/**
* reopen the archive to ensure everything is written
*/
private function reopen(){
if($this->tar){
$this->tar->_close();
$this->tar=null;
}
$types=array(null,'gz','bz');
$this->tar=new Archive_Tar($this->path,$types[self::getTarType($this->path)]);
}
}

View File

@ -11,7 +11,6 @@ class OC_Archive_ZIP extends OC_Archive{
* @var ZipArchive zip
*/
private $zip=null;
private $contents=array();
private $success=false;
private $path;
@ -56,7 +55,9 @@ class OC_Archive_ZIP extends OC_Archive{
* @return bool
*/
function rename($source,$dest){
return $this->zip->renameName($source,$dest);
$source=$this->stripPath($source);
$dest=$this->stripPath($dest);
$this->zip->renameName($source,$dest);
}
/**
* get the uncompressed size of a file in the archive
@ -99,15 +100,11 @@ class OC_Archive_ZIP extends OC_Archive{
* @return array
*/
function getFiles(){
if(count($this->contents)){
return $this->contents;
}
$fileCount=$this->zip->numFiles;
$files=array();
for($i=0;$i<$fileCount;$i++){
$files[]=$this->zip->getNameIndex($i);
}
$this->contents=$files;
return $files;
}
/**
@ -128,13 +125,22 @@ class OC_Archive_ZIP extends OC_Archive{
$fp = $this->zip->getStream($path);
file_put_contents($dest,$fp);
}
/**
* extract the archive
* @param string path
* @param string dest
* @return bool
*/
function extract($dest){
return $this->zip->extractTo($dest);
}
/**
* check if a file or folder exists in the archive
* @param string path
* @return bool
*/
function fileExists($path){
return $this->zip->locateName($path)!==false;
return ($this->zip->locateName($path)!==false) or ($this->zip->locateName($path.'/')!==false);
}
/**
* remove a file or folder from the archive
@ -142,7 +148,11 @@ class OC_Archive_ZIP extends OC_Archive{
* @return bool
*/
function remove($path){
return $this->zip->deleteName($path);
if($this->fileExists($path.'/')){
return $this->zip->deleteName($path.'/');
}else{
return $this->zip->deleteName($path);
}
}
/**
* get a file handler
@ -179,4 +189,12 @@ class OC_Archive_ZIP extends OC_Archive{
unlink($tmpFile);
}
}
private function stripPath($path){
if(substr($path,0,1)=='/'){
return substr($path,1);
}else{
return $path;
}
}
}

View File

@ -27,10 +27,10 @@ abstract class Test_Archive extends UnitTestCase {
$this->instance=$this->getExisting();
$allFiles=$this->instance->getFiles();
$expected=array('lorem.txt','logo-wide.png','dir/','dir/lorem.txt');
$this->assertEqual(4,count($allFiles));
$this->assertEqual(4,count($allFiles),'only found '.count($allFiles).' out of 4 expected files');
foreach($expected as $file){
$this->assertNotIdentical(false,array_search($file,$allFiles),'cant find '.$file.' in archive');
$this->assertTrue($this->instance->fileExists($file));
$this->assertTrue($this->instance->fileExists($file),'file '.$file.' does not exist in archive');
}
$this->assertFalse($this->instance->fileExists('non/existing/file'));
@ -68,6 +68,7 @@ abstract class Test_Archive extends UnitTestCase {
$this->instance->addFile('lorem.txt',$textFile);
$this->assertEqual(1,count($this->instance->getFiles()));
$this->assertTrue($this->instance->fileExists('lorem.txt'));
$this->assertFalse($this->instance->fileExists('lorem.txt/'));
$this->assertEqual(file_get_contents($textFile),$this->instance->getFile('lorem.txt'));
$this->instance->addFile('lorem.txt','foobar');
@ -94,4 +95,39 @@ abstract class Test_Archive extends UnitTestCase {
$this->assertTrue($this->instance->fileExists('lorem.txt'));
$this->assertEqual(file_get_contents($dir.'/lorem.txt'),$this->instance->getFile('lorem.txt'));
}
public function testFolder(){
$this->instance=$this->getNew();
$this->assertFalse($this->instance->fileExists('/test'));
$this->assertFalse($this->instance->fileExists('/test/'));
$this->instance->addFolder('/test');
$this->assertTrue($this->instance->fileExists('/test'));
$this->assertTrue($this->instance->fileExists('/test/'));
$this->instance->remove('/test');
$this->assertFalse($this->instance->fileExists('/test'));
$this->assertFalse($this->instance->fileExists('/test/'));
}
public function testExtract(){
$dir=OC::$SERVERROOT.'/apps/files_archive/tests/data';
$this->instance=$this->getExisting();
$tmpDir=OC_Helper::tmpFolder();
$this->instance->extract($tmpDir);
$this->assertEqual(true,file_exists($tmpDir.'lorem.txt'));
$this->assertEqual(true,file_exists($tmpDir.'dir/lorem.txt'));
$this->assertEqual(true,file_exists($tmpDir.'logo-wide.png'));
$this->assertEqual(file_get_contents($dir.'/lorem.txt'),file_get_contents($tmpDir.'lorem.txt'));
OC_Helper::rmdirr($tmpDir);
}
public function testMoveRemove(){
$dir=OC::$SERVERROOT.'/apps/files_archive/tests/data';
$textFile=$dir.'/lorem.txt';
$this->instance=$this->getNew();
$this->instance->addFile('lorem.txt',$textFile);
$this->assertFalse($this->instance->fileExists('target.txt'));
$this->instance->rename('lorem.txt','target.txt');
$this->assertTrue($this->instance->fileExists('target.txt'));
$this->assertFalse($this->instance->fileExists('lorem.txt'));
$this->assertEqual(file_get_contents($textFile),$this->instance->getFile('target.txt'));
$this->instance->remove('target.txt');
$this->assertFalse($this->instance->fileExists('target.txt'));
}
}

View File

@ -0,0 +1,20 @@
<?php
/**
* Copyright (c) 2012 Robin Appelman <icewind@owncloud.com>
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
require_once('archive.php');
class Test_Archive_TAR extends Test_Archive{
protected function getExisting(){
$dir=OC::$SERVERROOT.'/apps/files_archive/tests/data';
return new OC_Archive_TAR($dir.'/data.tar.gz');
}
protected function getNew(){
return new OC_Archive_TAR(OC_Helper::tmpFile('.tar.gz'));
}
}

View File

@ -7,4 +7,7 @@
<licence>AGPL</licence>
<author>Robin Appelman</author>
<require>3</require>
<types>
<filesystem/>
</types>
</info>

View File

@ -0,0 +1,11 @@
<?php
/**
* Copyright (c) 2012 Robin Appelman <icewind@owncloud.com>
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
OC::$CLASSPATH['OC_Filestorage_FTP']='apps/files_external/lib/ftp.php';
OC::$CLASSPATH['OC_Filestorage_DAV']='apps/files_external/lib/webdav.php';
OC::$CLASSPATH['OC_Filestorage_Google']='apps/files_external/lib/google.php';

View File

@ -0,0 +1,13 @@
<?xml version="1.0"?>
<info>
<id>files_external</id>
<name>External storage support</name>
<description>Mount external storage sources</description>
<version>0.1</version>
<licence>AGPL</licence>
<author>Robin Appelman</author>
<require>3</require>
<types>
<filesystem/>
</types>
</info>

View File

@ -12,7 +12,7 @@ class Test_Filestorage_FTP extends Test_FileStorage {
public function setUp(){
$id=uniqid();
$this->config=include('apps/files_remote/tests/config.php');
$this->config=include('apps/files_external/tests/config.php');
$this->config['ftp']['root'].='/'.$id;//make sure we have an new empty folder to work in
$this->instance=new OC_Filestorage_FTP($this->config['ftp']);
}

View File

@ -27,7 +27,7 @@ class Test_Filestorage_Google extends Test_FileStorage {
public function setUp(){
$id=uniqid();
$this->config=include('apps/files_remote/tests/config.php');
$this->config=include('apps/files_external/tests/config.php');
$this->config['google']['root'].='/'.$id;//make sure we have an new empty folder to work in
$this->instance=new OC_Filestorage_Google($this->config['google']);
}
@ -35,4 +35,4 @@ class Test_Filestorage_Google extends Test_FileStorage {
public function tearDown(){
$this->instance->rmdir('/');
}
}
}

View File

@ -12,7 +12,7 @@ class Test_Filestorage_DAV extends Test_FileStorage {
public function setUp(){
$id=uniqid();
$this->config=include('apps/files_remote/tests/config.php');
$this->config=include('apps/files_external/tests/config.php');
$this->config['webdav']['root'].='/'.$id;//make sure we have an new empty folder to work in
$this->instance=new OC_Filestorage_DAV($this->config['webdav']);
}

View File

@ -1,11 +0,0 @@
<?php
/**
* Copyright (c) 2012 Robin Appelman <icewind@owncloud.com>
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
OC::$CLASSPATH['OC_Filestorage_FTP']='apps/files_remote/lib/ftp.php';
OC::$CLASSPATH['OC_Filestorage_DAV']='apps/files_remote/lib/webdav.php';
OC::$CLASSPATH['OC_Filestorage_Google']='apps/files_remote/lib/google.php';

View File

@ -1,10 +0,0 @@
<?xml version="1.0"?>
<info>
<id>files_remote</id>
<name>Remote storage support</name>
<description>Mount remote storage sources</description>
<version>0.1</version>
<licence>AGPL</licence>
<author>Robin Appelman</author>
<require>3</require>
</info>

View File

@ -7,21 +7,23 @@ OC_JSON::checkLoggedIn();
OC_JSON::checkAppEnabled('files_sharing');
$users = array();
$ocusers = OC_User::getUsers();
$groups = array();
$self = OC_User::getUser();
$groups = OC_Group::getUserGroups($self);
$userGroups = OC_Group::getUserGroups($self);
$users[] = "<optgroup label='Users'>";
foreach ($ocusers as $user) {
if ($user != $self) {
$users[] = "<option value='".$user."'>".$user."</option>";
$groups[] = "<optgroup label='Groups'>";
foreach ($userGroups as $group) {
$groupUsers = OC_Group::usersInGroup($group);
foreach ($groupUsers as $user) {
if ($user != $self) {
$users[] = "<option value='".$user."'>".$user."</option>";
}
}
$groups[] = "<option value='".$group."'>".$group."</option>";
}
$users[] = "</optgroup>";
$users[] = "<optgroup label='Groups'>";
foreach ($groups as $group) {
$users[] = "<option value='".$group."'>".$group."</option>";
}
$users[] = "</optgroup>";
$groups[] = "</optgroup>";
$users = array_merge($users, $groups);
OC_JSON::encodedPrint($users);
?>

View File

@ -8,4 +8,7 @@
<author>Michael Gapczynski</author>
<require>2</require>
<default_enable/>
<types>
<filesystem/>
</types>
</info>

View File

@ -52,8 +52,18 @@ class OC_Share {
// Remove the owner from the list of users in the group
$uid_shared_with = array_diff($uid_shared_with, array($uid_owner));
} else if (OC_User::userExists($uid_shared_with)) {
$gid = null;
$uid_shared_with = array($uid_shared_with);
$userGroups = OC_Group::getUserGroups($uid_owner);
// Check if the user is in one of the owner's groups
foreach ($userGroups as $group) {
if ($inGroup = OC_Group::inGroup($uid_shared_with, $group)) {
$gid = null;
$uid_shared_with = array($uid_shared_with);
break;
}
}
if (!$inGroup) {
throw new Exception("You can't share with ".$uid_shared_with);
}
} else {
throw new Exception($uid_shared_with." is not a user");
}

View File

@ -76,7 +76,7 @@ function showControls(filename,writeperms){
function bindControlEvents(){
$("#editor_save").die('click',doFileSave).live('click',doFileSave);
$('#editor_close').die('click',hideFileEditor).live('click',hideFileEditor);
$('#editor_close').die('click',closeBtnClick).live('click',closeBtnClick);
$('#gotolineval').die('keyup', goToLine).live('keyup', goToLine);
$('#editorsearchval').die('keyup', doSearch).live('keyup', doSearch);
$('#clearsearchbtn').die('click', resetSearch).live('click', resetSearch);
@ -141,31 +141,38 @@ function doSearch(){
// Tries to save the file.
function doFileSave(){
if(editorIsShown()){
// Get file path
var path = $('#editor').attr('data-dir')+'/'+$('#editor').attr('data-filename');
// Get original mtime
var mtime = $('#editor').attr('data-mtime');
// Show saving spinner
$("#editor_save").die('click',doFileSave);
$('#save_result').remove();
$('#editor_save').text(t('files_texteditor','Saving...'));
// Get the data
var filecontents = window.aceEditor.getSession().getValue();
// Send the data
$.post(OC.filePath('files_texteditor','ajax','savefile.php'), { filecontents: filecontents, path: path, mtime: mtime },function(jsondata){
if(jsondata.status!='success'){
// Save failed
$('#editor_save').text(t('files_texteditor','Save'));
$('#editor_save').after('<p id="save_result" style="float: left">Failed to save file</p>');
$("#editor_save").live('click',doFileSave);
} else {
// Save OK
// Update mtime
$('#editor').attr('data-mtime',jsondata.data.mtime);
$('#editor_save').text(t('files_texteditor','Save'));
$("#editor_save").live('click',doFileSave);
}
},'json');
// Changed contents?
if($('#editor').attr('data-edited')=='true'){
// Get file path
var path = $('#editor').attr('data-dir')+'/'+$('#editor').attr('data-filename');
// Get original mtime
var mtime = $('#editor').attr('data-mtime');
// Show saving spinner
$("#editor_save").die('click',doFileSave);
$('#save_result').remove();
$('#editor_save').text(t('files_texteditor','Saving...'));
// Get the data
var filecontents = window.aceEditor.getSession().getValue();
// Send the data
$.post(OC.filePath('files_texteditor','ajax','savefile.php'), { filecontents: filecontents, path: path, mtime: mtime },function(jsondata){
if(jsondata.status!='success'){
// Save failed
$('#editor_save').text(t('files_texteditor','Save'));
$('#editor_save').after('<p id="save_result" style="float: left">Failed to save file</p>');
$("#editor_save").live('click',doFileSave);
} else {
// Save OK
// Update mtime
$('#editor').attr('data-mtime',jsondata.data.mtime);
$('#editor_save').text(t('files_texteditor','Save'));
$("#editor_save").live('click',doFileSave);
// Update titles
$('#editor').attr('data-edited', 'false');
$('#breadcrumb_file').text($('#editor').attr('data-filename'));
document.title = $('#editor').attr('data-filename')+' - ownCloud';
}
},'json');
}
}
};
@ -192,10 +199,11 @@ function showFileEditor(dir,filename){
// Show the control bar
showControls(filename,result.data.write);
// Update document title
document.title = filename;
document.title = filename+' - ownCloud';
$('#editor').text(result.data.filecontents);
$('#editor').attr('data-dir', dir);
$('#editor').attr('data-filename', filename);
$('#editor').attr('data-edited', 'false');
window.aceEditor = ace.edit("editor");
aceEditor.setShowPrintMargin(false);
aceEditor.getSession().setUseWrapMode(true);
@ -207,10 +215,17 @@ function showFileEditor(dir,filename){
OC.addScript('files_texteditor','aceeditor/theme-clouds', function(){
window.aceEditor.setTheme("ace/theme/clouds");
});
window.aceEditor.getSession().on('change', function(){
if($('#editor').attr('data-edited')!='true'){
$('#editor').attr('data-edited', 'true');
$('#breadcrumb_file').text($('#breadcrumb_file').text()+' *');
document.title = $('#editor').attr('data-filename')+' * - ownCloud';
}
});
});
} else {
// Failed to get the file.
alert(result.data.message);
OC.dialogs.alert(result.data.message, t('files_texteditor','An error occurred!'));
}
// End success
}
@ -220,6 +235,19 @@ function showFileEditor(dir,filename){
}
}
function closeBtnClick(){
if($('#editor').attr('data-edited')=='true'){
// Show confirm
OC.dialogs.confirm(t('files_texteditor','You have unsaved changes that will be lost! Do you still want to close?'),t('files_texteditor','Really close?'),function(close){
if(close){
hideFileEditor();
}
});
} else {
hideFileEditor();
}
}
// Fades out the editor.
function hideFileEditor(){
// Fades out editor controls
@ -287,4 +315,5 @@ $(document).ready(function(){
$('#editor').remove();
// Binds the save keyboard shortcut events
//$(document).unbind('keydown').bind('keydown',checkForSaveKeyPress);
});

View File

@ -127,6 +127,9 @@ function handleGetGallery($path) {
function handleShare($path, $share, $recursive) {
$recursive = $recursive == 'true' ? 1 : 0;
$owner = OC_User::getUser();
$root = OC_Preferences::getValue(OC_User::getUser(),'gallery', 'root', '/');
$path = utf8_decode(rtrim($root.$path,'/'));
if($path == '') $path = '/';
$r = OC_Gallery_Album::find($owner, null, $path);
if ($row = $r->fetchRow()) {
$albumId = $row['album_id'];

View File

@ -32,14 +32,14 @@ $l = new OC_L10N('gallery');
OC_App::register(array(
'order' => 20,
'id' => 'gallery',
'name' => 'Gallery'));
'name' => 'Pictures'));
OC_App::addNavigationEntry( array(
'id' => 'gallery_index',
'order' => 20,
'href' => OC_Helper::linkTo('gallery', 'index.php'),
'icon' => OC_Helper::imagePath('core', 'places/picture.svg'),
'name' => $l->t('Gallery')));
'name' => $l->t('Pictures')));
class OC_GallerySearchProvider implements OC_Search_Provider{
static function search($query){

View File

@ -1,11 +1,11 @@
<?xml version="1.0"?>
<info>
<id>gallery</id>
<name>Gallery</name>
<name>Pictures</name>
<version>0.4</version>
<licence>AGPL</licence>
<author>Bartek Przybylski</author>
<require>2</require>
<description>Gallery application for ownCloud</description>
<description>Dedicated pictures application</description>
<default_enable/>
</info>

View File

@ -43,8 +43,9 @@ function shareGallery() {
{text: 'Shared gallery address', name: 'address', type: 'text', value: existing_token}];
OC.dialogs.form(form_fields, t('gallery', 'Share gallery'), function(values){
var p = '';
for (var i in paths) p += '/'+paths[i];
for (var i in paths) p += paths[i]+'/';
if (p == '') p = '/';
alert(p);
$.getJSON(OC.filePath('gallery', 'ajax', 'galleryOp.php'), {operation: 'share', path: p, share: values[0].value, recursive: values[1].value}, function(r) {
if (r.status == 'success') {
Albums.shared = r.sharing;
@ -112,42 +113,28 @@ function scanForAlbums(cleanup) {
}
function settings() {
$( '#g-dialog-settings' ).dialog({
height: 180,
width: 350,
modal: false,
buttons: [
{
text: t('gallery', 'Apply'),
click: function() {
var scanning_root = $('#g-scanning-root').val();
var disp_order = $('#g-display-order option:selected').val();
OC.dialogs.form([{text: t('gallery', 'Scanning root'), name: 'root', type:'text', value:gallery_scanning_root},
{text: t('gallery', 'Default order'), name: 'order', type:'select', value:gallery_default_order, options:[
{text:t('gallery', 'Ascending'), value:'ASC'}, {text: t('gallery', 'Descending'), value:'DESC'} ]}],
t('gallery', 'Settings'),
function(values) {
var scanning_root = values[0].value;
var disp_order = values[1].value;
if (scanning_root == '') {
alert('Scanning root cannot be empty');
OC.dialogs.alert(t('gallery', 'Scanning root cannot be empty'), t('gallery', 'Error'));
return;
}
$.getJSON(OC.filePath('gallery','ajax','galleryOp.php'), {operation: 'store_settings', root: scanning_root, order: disp_order}, function(r) {
if (r.status == 'success') {
if (r.rescan == 'yes') {
$('#g-dialog-settings').dialog('close');
Albums.clear(document.getElementById('gallery_list'));
scanForAlbums(true);
return;
}
if (r.rescan == 'yes') {
Albums.clear(document.getElementById('gallery_list'));
scanForAlbums(true);
}
gallery_scanning_root = scanning_root;
} else {
alert('Error: ' + r.cause);
return;
OC.dialogs.alert(t('gallery', 'Error: ') + r.cause, t('gallery', 'Error'));
return;
}
$('#g-dialog-settings').dialog('close');
});
}
},
{
text: t('gallery', 'Cancel'),
click: function() {
$(this).dialog('close');
}
}
],
});
});
}

View File

@ -9,7 +9,7 @@ OC_Util::addScript('files_imageviewer', 'jquery.fancybox-1.3.4.pack');
OC_Util::addStyle( 'files_imageviewer', 'jquery.fancybox-1.3.4' );
$l = new OC_L10N('gallery');
?>
<script type="text/javascript">var gallery_scanning_root='<? echo OC_Preferences::getValue(OC_User::getUser(), 'gallery', 'root', '/'); ?>'; var gallery_default_order = '<? echo OC_Preferences::getValue(OC_User::getUser(), 'gallery', 'order', 'ASC'); ?>';</script>
<div id="controls">
<div id="scan">
<div id="scanprogressbar"></div>
@ -29,40 +29,3 @@ $l = new OC_L10N('gallery');
</div>
<div id="gallery_list">
</div>
<div id="dialog-confirm" title="<?php echo $l->t('Remove confirmation');?>" style="display: none">
<p><span class="ui-icon ui-icon-alert" style="float:left; margin:0 7px 20px 0;"></span><?php echo $l->t('Do you want to remove album');?> <span id="albumName"></span>?</p>
</div>
<div id="dialog-form" title="<?php echo $l->t('Change album name');?>" style="display:none">
<form>
<fieldset>
<label for="name"><?php echo $l->t('New album name');?></label>
<input type="text" name="name" id="name" class="text ui-widget-content ui-corner-all" />
</fieldset>
</form>
</div>
<div id="g-dialog-settings" title="<?php echo $l->t('Settings');?>" style="display:none">
<form>
<fieldset><?php $root = OC_Preferences::getValue(OC_User::getUser(), 'gallery', 'root', '/'); $order = OC_Preferences::getValue(OC_User::getUser(), 'gallery', 'order', 'ASC');?>
<label for="name"><?php echo $l->t('Scanning root');?></label>
<input type="text" name="g-scanning-root" id="g-scanning-root" class="text ui-widget-content ui-corner-all" value="<?php echo $root;?>" /><br/>
<label for="sort"><?php echo $l->t('Default sorting'); ?></label>
<select id="g-display-order">
<option value="ASC"<?php echo $order=='ASC'?'selected':'';?>><?php echo $l->t('Ascending'); ?></option>
<option value="DESC"<?php echo $order=='DESC'?'selected':'';?>><?php echo $l->t('Descending'); ?></option>
</select><br/>
<!--
<label for="sort"><?php echo $l->t('Thumbnails size'); ?></label>
<select>
<option value="100">100px</option>
<option value="150">150px</option>
<option value="200">200px</option>
</select>
-->
</fieldset>
</form>
</div>

View File

@ -22,6 +22,7 @@ div.jp-volume-bar-value { background:#ccc; width:0; height:0.4em; }
#leftcontent img.remove { display:none; float:right; cursor:pointer; opacity: 0; }
#leftcontent li:hover img.remove { display:inline; opacity: .3; }
#leftcontent li div.label { float: left; width: 200px; overflow: hidden; text-overflow: ellipsis; }
#rightcontent { overflow: auto; }
#playlist li { list-style-type:none; }
.template { display:none; }
.collection_playing { background:#eee; font-weight: bold; }

View File

@ -2,7 +2,7 @@
<info>
<id>remoteStorage</id>
<name>remoteStorage compatibility</name>
<description>Enables your users to use ownCloud as their remote storage for unhosted applications.</description>
<description>Enables you to use ownCloud as their remote storage for unhosted applications. This app requires the Webfinger app to be installed and enabled correctly. More info on <a href="http://unhosted.org">the website of the unhosted movement</a>.</description>
<version>0.6</version>
<licence>AGPL or MIT</licence>
<author>Michiel de Jong</author>

View File

@ -131,3 +131,9 @@ li.error { width:640px; margin:4em auto; padding:1em 1em 1em 4em; background:#ff
.separator { display: inline; border-left: 1px solid #d3d3d3; border-right: 1px solid #fff; height: 10px; width:0px; margin: 4px; }
a.bookmarklet { background-color: #ddd; border:1px solid #ccc; padding: 5px;padding-top: 0px;padding-bottom: 2px; text-decoration: none; margin-top: 5px }
/* ---- DIALOGS ---- */
#dirtree {width: 100%;}
#filelist {height: 270px; overflow:scroll; background-color: white;}
.filepicker_element_selected { background-color: lightblue;}

View File

@ -33,8 +33,12 @@
*/
OC.EventSource=function(src,data){
var dataStr='';
for(name in data){
dataStr+=name+'='+encodeURIComponent(data[name])+'&';
this.typelessListeners=[];
this.listeners={};
if(data){
for(name in data){
dataStr+=name+'='+encodeURIComponent(data[name])+'&';
}
}
if(!this.useFallBack && typeof EventSource !='undefined'){
this.source=new EventSource(src+'?'+dataStr);
@ -42,7 +46,7 @@ OC.EventSource=function(src,data){
for(var i=0;i<this.typelessListeners.length;i++){
this.typelessListeners[i](JSON.parse(e.data));
}
}
}.bind(this);
}else{
iframeId='oc_eventsource_iframe_'+OC.EventSource.iframeCount;
OC.EventSource.fallBackSources[OC.EventSource.iframeCount]=this;
@ -64,7 +68,7 @@ OC.EventSource=function(src,data){
OC.EventSource.fallBackSources=[];
OC.EventSource.iframeCount=0;//number of fallback iframes
OC.EventSource.fallBackCallBack=function(id,type,data){
OC.EventSource.fallBackSources[id].fallBackCallBack(type,JSON.parse(data));
OC.EventSource.fallBackSources[id].fallBackCallBack(type,data);
}
OC.EventSource.prototype={
typelessListeners:[],

View File

@ -126,7 +126,13 @@ OC={
});
}
},
dialogs:OCdialogs
dialogs:OCdialogs,
mtime2date:function(mtime) {
mtime = parseInt(mtime);
var date = new Date(1000*mtime);
var ret = date.getDate()+'.'+(date.getMonth()+1)+'.'+date.getFullYear()+', '+date.getHours()+':'+date.getMinutes();
return ret;
}
};
OC.search.customResults={};
OC.search.currentResult=-1;

View File

@ -17,7 +17,6 @@
* 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/>.
*
* todo(bartek): add select option in form
*/
/**
@ -30,9 +29,9 @@ OCdialogs = {
* @param title dialog title
* @param callback which will be triggered when user press OK
*/
alert:function(text, title, callback) {
alert:function(text, title, callback, modal) {
var content = '<p><span class="ui-icon ui-icon-alert"></span>'+text+'</p>';
OCdialogs.message(content, title, OCdialogs.ALERT_DIALOG, OCdialogs.OK_BUTTON, callback);
OCdialogs.message(content, title, OCdialogs.ALERT_DIALOG, OCdialogs.OK_BUTTON, callback, modal);
},
/**
* displays info dialog
@ -40,9 +39,9 @@ OCdialogs = {
* @param title dialog title
* @param callback which will be triggered when user press OK
*/
info:function(text, title, callback) {
info:function(text, title, callback, modal) {
var content = '<p><span class="ui-icon ui-icon-info"></span>'+text+'</p>';
OCdialogs.message(content, title, OCdialogs.ALERT_DIALOG, OCdialogs.OK_BUTTON, callback);
OCdialogs.message(content, title, OCdialogs.ALERT_DIALOG, OCdialogs.OK_BUTTON, callback, modal);
},
/**
* displays confirmation dialog
@ -50,9 +49,9 @@ OCdialogs = {
* @param title dialog title
* @param callback which will be triggered when user press YES or NO (true or false would be passed to callback respectively)
*/
confirm:function(text, title, callback) {
confirm:function(text, title, callback, modal) {
var content = '<p><span class="ui-icon ui-icon-notice"></span>'+text+'</p>';
OCdialogs.message(content, title, OCdialogs.ALERT_DIALOG, OCdialogs.YES_NO_BUTTONS, callback);
OCdialogs.message(content, title, OCdialogs.ALERT_DIALOG, OCdialogs.YES_NO_BUTTONS, callback, modal);
},
/**
* prompt for user input
@ -60,9 +59,9 @@ OCdialogs = {
* @param title dialog title
* @param callback which will be triggered when user press OK (input text will be passed to callback)
*/
prompt:function(text, title, default_value, callback) {
prompt:function(text, title, default_value, callback, modal) {
var content = '<p><span class="ui-icon ui-icon-pencil"></span>'+text+':<br/><input type="text" id="oc-dialog-prompt-input" value="'+default_value+'" style="width:90%"></p>';
OCdialogs.message(content, title, OCdialogs.PROMPT_DIALOG, OCdialogs.OK_CANCEL_BUTTONS, callback);
OCdialogs.message(content, title, OCdialogs.PROMPT_DIALOG, OCdialogs.OK_CANCEL_BUTTONS, callback, modal);
},
/**
* prompt user for input with custom form
@ -71,7 +70,7 @@ OCdialogs = {
* @param title dialog title
* @param callback which will be triggered when user press OK (user answers will be passed to callback in following format: [{name:'return name', value: 'user value'},...])
*/
form:function(fields, title, callback) {
form:function(fields, title, callback, modal) {
var content = '<table>';
for (var a in fields) {
content += '<tr><td>'+fields[a].text+'</td><td>';
@ -84,16 +83,63 @@ OCdialogs = {
} else content += '>';
} else if (type == 'text' || type == 'password' && fields[a].value)
content += ' value="'+fields[a].value+'">';
} else if (type == 'select') {
content += '<select name="'+fields[a].name+'"';
if (fields[a].value != undefined)
content += ' value="'+fields[a].value+'"';
content += '>';
for (var o in fields[a].options)
content += '<option value="'+fields[a].options[o].value+'">'+fields[a].options[o].text+'</option>';
content += '</select>';
}
content += "</td></tr>"
content += '</td></tr>';
}
content += "</table>";
OCdialogs.message(content, title, OCdialogs.FORM_DIALOG, OCdialogs.OK_CANCEL_BUTTONS, callback);
content += '</table>';
OCdialogs.message(content, title, OCdialogs.FORM_DIALOG, OCdialogs.OK_CANCEL_BUTTONS, callback, modal);
},
message:function(content, title, dialog_type, buttons, callback) {
filepicker:function(title, callback, multiselect, mimetype_filter, modal) {
var c_name = 'oc-dialog-'+OCdialogs.dialogs_counter+'-content';
var c_id = '#'+c_name;
var d = '<div id="'+c_name+'" title="'+title+'"><select id="dirtree"><option value="0">'+OC.currentUser+'</option></select><div id="filelist"></div></div>';
if (!modal) modal = false;
if (!multiselect) multiselect = false;
$('body').append(d);
$(c_id + ' #dirtree').focus(function() { var t = $(this); t.data('oldval', t.val())})
.change({dcid: c_id}, OC.dialogs.handleTreeListSelect);
$(c_id).ready(function(){
$.getJSON(OC.webroot+'/files/ajax/rawlist.php', function(r){OC.dialogs.fillFilePicker(r, c_id, callback)});
}).data('multiselect', multiselect);
// build buttons
var b = [
{text: t('dialogs', 'Choose'), click: function(){
if (callback != undefined) {
var p;
if ($(c_id).data('multiselect') == true) {
p = [];
$(c_id+' .filepicker_element_selected #filename').each(function(i, elem) {
p.push(($(c_id).data('path')?$(c_id).data('path'):'')+'/'+$(elem).text());
});
} else {
var p = $(c_id).data('path');
if (p == undefined) p = '';
p = p+'/'+$(c_id+' .filepicker_element_selected #filename').text()
}
callback(p);
$(c_id).dialog('close');
}
}
},
{text: t('dialogs', 'Cancel'), click: function(){$(c_id).dialog('close'); }}
];
$(c_id).dialog({width: 4*$(document).width()/9, height: 400, modal: modal, buttons: b});
OCdialogs.dialogs_counter++;
},
// guts, dont use, dont touch
message:function(content, title, dialog_type, buttons, callback, modal) {
var c_name = 'oc-dialog-'+OCdialogs.dialogs_counter+'-content';
var c_id = '#'+c_name;
var d = '<div id="'+c_name+'" title="'+title+'">'+content+'</div>';
if (modal == undefined) modal = false;
$('body').append(d);
var b = [];
switch (buttons) {
@ -107,7 +153,7 @@ OCdialogs = {
var f;
switch(dialog_type) {
case OCdialogs.ALERT_DIALOG:
f = function(){$(c_id).dialog('close'); };
f = function(){$(c_id).dialog('close'); callback();};
break;
case OCdialogs.PROMPT_DIALOG:
f = function(){OCdialogs.prompt_ok_handler(callback, c_id)};
@ -120,7 +166,7 @@ OCdialogs = {
break;
}
var possible_height = ($('tr', d).size()+1)*30;
$(c_id).dialog({width: 4*$(document).width()/9, height: possible_height + 120, modal: false, buttons: b});
$(c_id).dialog({width: 4*$(document).width()/9, height: possible_height + 120, modal: modal, buttons: b});
OCdialogs.dialogs_counter++;
},
// dialogs buttons types
@ -144,7 +190,7 @@ OCdialogs = {
if (callback != undefined) {
var r = [];
var c = 0;
$(c_id + ' input').each(function(i, elem) {
$(c_id + ' input, '+c_id+' select').each(function(i, elem) {
r[c] = {name: $(elem).attr('name'), value: OCdialogs.determineValue(elem)};
c++;
});
@ -153,5 +199,44 @@ OCdialogs = {
} else {
$(c_id).dialog('close');
}
},
fillFilePicker:function(r, dialog_content_id) {
var entry_template = '<div onclick="javascript:OC.dialogs.handlePickerClick(this, \'*ENTRYNAME*\',\''+dialog_content_id+'\')" data="*ENTRYTYPE*"><img src="*MIMETYPEICON*" style="margin-right:1em;"><span id="filename">*NAME*</span><div style="float:right;margin-right:1em;">*LASTMODDATE*</div></div>';
var names = '';
for (var a in r.data) {
names += entry_template.replace('*LASTMODDATE*', OC.mtime2date(r.data[a].mtime)).replace('*NAME*', r.data[a].name).replace('*MIMETYPEICON*', OC.webroot+'/core/img/filetypes/'+(r.data[a].type=='dir'?'folder':r.data[a].mimetype.replace('/','-'))+'.png').replace('*ENTRYNAME*', r.data[a].name).replace('*ENTRYTYPE*', r.data[a].type);
}
$(dialog_content_id + ' #filelist').html(names);
},
handleTreeListSelect:function(event) {
var newval = parseInt($(this).val());
var oldval = parseInt($(this).data('oldval'));
while (newval != oldval && oldval > 0) {
$('option:last', this).remove();
$('option:last', this).attr('selected','selected');
oldval--;
}
var skip_first = true;
var path = '';
$(this).children().each(function(i, element) { if (skip_first) {skip_first = false; return; }path += '/'+$(element).text(); });
$(event.data.dcid).data('path', path);
$.getJSON(OC.webroot+'/files/ajax/rawlist.php', {dir: path}, function(r){OC.dialogs.fillFilePicker(r, event.data.dcid)});
},
// this function is in early development state, please dont use it unlsess you know what you are doing
handlePickerClick:function(element, name, dcid) {
var p = $(dcid).data('path');
if (p == undefined) p = '';
p = p+'/'+name;
if ($(element).attr('data') == 'file'){
if ($(dcid).data('multiselect') != true)
$(dcid+' .filepicker_element_selected').removeClass('filepicker_element_selected');
$(element).toggleClass('filepicker_element_selected');
return;
}
$(dcid).data('path', p);
$(dcid + ' #dirtree option:last').removeAttr('selected');
var newval = parseInt($(dcid + ' #dirtree option:last').val())+1;
$(dcid + ' #dirtree').append('<option selected="selected" value="'+newval+'">'+name+'</option>');
$.getJSON(OC.webroot+'/files/ajax/rawlist.php', {dir: p}, function(r){OC.dialogs.fillFilePicker(r, dcid)});
}
};

View File

@ -1,3 +1,4 @@
<!--[if IE 8]><style>input[type="checkbox"]{padding:0;}</style><![endif]-->
<form action="index.php" method="post">
<fieldset>
<?php if(!empty($_['redirect'])) { echo '<input type="hidden" name="redirect_url" value="'.$_['redirect'].'" />'; } ?>
@ -6,7 +7,7 @@
<?php endif; ?>
<p class="infield">
<label for="user" class="infield"><?php echo $l->t( 'Username' ); ?></label>
<input type="text" name="user" id="user" value="<?php echo !empty($_POST['user'])?$_POST['user'].'"':'" autofocus'; ?> autocomplete="off" required />
<input type="text" name="user" id="user" value="<?php echo !empty($_POST['user'])?htmlentities($_POST['user']).'"':'" autofocus'; ?> autocomplete="off" required />
</p>
<p class="infield">
<label for="password" class="infield"><?php echo $l->t( 'Password' ); ?></label>

View File

@ -64,6 +64,14 @@
<length>512</length>
</field>
<field>
<name>path_hash</name>
<type>text</type>
<default></default>
<notnull>true</notnull>
<length>32</length>
</field>
<field>
<name>parent</name>
<type>integer</type>
@ -79,7 +87,7 @@
<default>
</default>
<notnull>true</notnull>
<length>512</length>
<length>300</length>
</field>
<field>
@ -159,14 +167,13 @@
<length>1</length>
</field>
<!--<index>
<name>fscache_path_index</name>
<unique>true</unique>
<index>
<name>fscache_path_hash_index</name>
<field>
<name>path</name>
<name>path_hash</name>
<sorting>ascending</sorting>
</field>
</index>-->
</index>
<index>
<name>parent_index</name>
@ -176,6 +183,14 @@
</field>
</index>
<index>
<name>name_index</name>
<field>
<name>name</name>
<sorting>ascending</sorting>
</field>
</index>
<index>
<name>parent_name_index</name>
<field>

View File

@ -21,6 +21,9 @@
*
*/
// only need filesystem apps
$RUNTIME_APPTYPES=array('filesystem');
// Init owncloud
require_once('../../lib/base.php');

View File

@ -1,5 +1,8 @@
<?php
// only need filesystem apps
$RUNTIME_APPTYPES=array('filesystem');
// Init owncloud
require_once('../../lib/base.php');

View File

@ -1,5 +1,8 @@
<?php
// no need for apps
$RUNTIME_NOAPPS=false;
// Init owncloud
require_once('../../lib/base.php');

23
files/ajax/rawlist.php Normal file
View File

@ -0,0 +1,23 @@
<?php
// only need filesystem apps
$RUNTIME_APPTYPES=array('filesystem');
// Init owncloud
require_once('../../lib/base.php');
OC_JSON::checkLoggedIn();
// Load the files
$dir = isset( $_GET['dir'] ) ? $_GET['dir'] : '';
// make filelist
$files = array();
foreach( OC_Files::getdirectorycontent( $dir ) as $i ){
$i["date"] = OC_Util::formatDate($i["mtime"] );
$files[] = $i;
}
OC_JSON::success(array('data' => $files));
?>

View File

@ -17,6 +17,7 @@ if($force or !OC_FileCache::inCache('')){
if(!$checkOnly){
OC_DB::beginTransaction();
OC_FileCache::scan('',$eventSource);
OC_FileCache::clean();
OC_DB::commit();
$eventSource->send('success',true);
}else{

View File

@ -64,8 +64,8 @@ table td.filename .nametext { width:60%; }
table td.filename form { float:left; font-size:.85em; }
table thead.fixed tr{ position:fixed; top:6.5em; z-index:49; -moz-box-shadow:0 -3px 7px #ddd; -webkit-box-shadow:0 -3px 7px #ddd; box-shadow:0 -3px 7px #ddd; }
table thead.fixed { height:2em; }
#fileList tr td.filename>input[type=checkbox]:first-child { opacity:0; float:left; margin:.7em 0 0 1em; /* bigger clickable area doesnt work in FF width:2.8em; height:2.4em;*/ -webkit-transition:opacity 500ms; -moz-transition:opacity 500ms; -o-transition:opacity 500ms; transition:opacity 500ms; }
#fileList tr td.filename>input[type="checkbox"]:hover:first-child { opacity:.8; }
#fileList tr td.filename>input[type=checkbox]:first-child { opacity:0; -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; float:left; margin:.7em 0 0 1em; /* bigger clickable area doesnt work in FF width:2.8em; height:2.4em;*/ -webkit-transition:opacity 500ms; -moz-transition:opacity 500ms; -o-transition:opacity 500ms; transition:opacity 500ms; }
#fileList tr td.filename>input[type="checkbox"]:hover:first-child { opacity:.8; -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=80)"; }
#fileList tr td.filename>input[type="checkbox"]:checked:first-child { opacity:1; }
#fileList tr td.filename { -webkit-transition:background-image 500ms; -moz-transition:background-image 500ms; -o-transition:background-image 500ms; transition:background-image 500ms; }
#select_all { float:left; margin:.3em 0.6em 0 .5em; }

View File

@ -98,7 +98,7 @@ $(document).ready(function() {
procesSelection();
});
$('td.filename input:checkbox').live('click',function(event) {
$('td.filename input:checkbox').live('change',function(event) {
if (event.shiftKey) {
var last = $(lastChecked).parent().parent().prevAll().length;
var first = $(this).parent().parent().prevAll().length;

View File

@ -1,3 +1,4 @@
<!--[if IE 8]><style>input[type="checkbox"]{padding:0;}table td{position:static !important;}</style><![endif]-->
<div id="controls">
<?php echo($_['breadcrumb']); ?>
<?php if (!isset($_['readonly']) || !$_['readonly']):?>
@ -62,12 +63,12 @@
</div>
<div id="scanning-message">
<h3>
<?php echo $l->t('Files are being scanned, please wait.');?> <span id='scan-count'></spann>
<?php echo $l->t('Files are being scanned, please wait.');?> <span id='scan-count'></span>
</h3>
<p>
<?php echo $l->t('Current scanning');?> <span id='scan-current'></spann>
<?php echo $l->t('Current scanning');?> <span id='scan-current'></span>
</p>
</div>
<!-- config hints for javascript -->
<input type="hidden" name="allowZipDownload" id="allowZipDownload" value="<?php echo $_['allowZipDownload']; ?>" />
<input type="hidden" name="allowZipDownload" id="allowZipDownload" value="<?php echo $_['allowZipDownload']; ?>" />

View File

@ -26,6 +26,9 @@
// Do not load FS ...
$RUNTIME_NOSETUPFS = true;
// only need filesystem apps
$RUNTIME_APPTYPES=array('filesystem');
require_once('../lib/base.php');
// Backends

View File

@ -34,16 +34,20 @@ class OC_App{
static private $settingsForms = array();
static private $adminForms = array();
static private $personalForms = array();
static private $appInfo = array();
/**
* @brief loads all apps
* @param array $types
* @returns true/false
*
* This function walks through the owncloud directory and loads all apps
* it can find. A directory contains an app if the file /appinfo/app.php
* exists.
*
* if $types is set, only apps of those types will be loaded
*/
public static function loadApps(){
public static function loadApps($types=null){
// Did we allready load everything?
if( self::$init ){
return true;
@ -51,13 +55,15 @@ class OC_App{
// Our very own core apps are hardcoded
foreach( array('files', 'settings') as $app ){
require( $app.'/appinfo/app.php' );
if(is_null($types)){
require( $app.'/appinfo/app.php' );
}
}
// The rest comes here
$apps = OC_Appconfig::getApps();
$apps = self::getEnabledApps();
foreach( $apps as $app ){
if( self::isEnabled( $app )){
if(is_null($types) or self::isType($app,$types)){
if(is_file(OC::$APPSROOT.'/apps/'.$app.'/appinfo/app.php')){
require( $app.'/appinfo/app.php' );
}
@ -70,6 +76,41 @@ class OC_App{
return true;
}
/**
* check if an app is of a sepcific type
* @param string $app
* @param string/array $types
*/
public static function isType($app,$types){
if(is_string($types)){
$types=array($types);
}
$appData=self::getAppInfo($app);
if(!isset($appData['types'])){
return false;
}
$appTypes=$appData['types'];
foreach($types as $type){
if(array_search($type,$appTypes)!==false){
return true;
}
}
return false;
}
/**
* get all enabled apps
*/
public static function getEnabledApps(){
$apps=array();
$query = OC_DB::prepare( 'SELECT appid FROM *PREFIX*appconfig WHERE configkey = \'enabled\' AND configvalue=\'yes\'' );
$result=$query->execute();
while($row=$result->fetchRow()){
$apps[]=$row['appid'];
}
return $apps;
}
/**
* @brief checks whether or not an app is enabled
* @param $app app
@ -265,24 +306,36 @@ class OC_App{
/**
* @brief Read app metadata from the info.xml file
* @param string $appid id of the app or the path of the info.xml file
* @param boolean path (optional)
* @returns array
*/
public static function getAppInfo($appid){
if(is_file($appid)){
public static function getAppInfo($appid,$path=false){
if($path){
$file=$appid;
}else{
$file=OC::$APPSROOT.'/apps/'.$appid.'/appinfo/info.xml';
if(!is_file($file)){
return array();
if(isset(self::$appInfo[$appid])){
return self::$appInfo[$appid];
}
$file=OC::$APPSROOT.'/apps/'.$appid.'/appinfo/info.xml';
}
$data=array();
$content=file_get_contents($file);
if(!$content){
return;
}
$xml = new SimpleXMLElement($content);
$data['info']=array();
foreach($xml->children() as $child){
$data[$child->getName()]=(string)$child;
if($child->getName()=='types'){
$data['types']=array();
foreach($child->children() as $type){
$data['types'][]=$type->getName();
}
}else{
$data[$child->getName()]=(string)$child;
}
}
self::$appInfo[$appid]=$data;
return $data;
}
@ -381,9 +434,8 @@ class OC_App{
*/
public static function updateApps(){
// The rest comes here
$apps = OC_Appconfig::getApps();
foreach( $apps as $app ){
$installedVersion=OC_Appconfig::getValue($app,'installed_version');
$versions = self::getAppVersions();
foreach( $versions as $app=>$installedVersion ){
$appInfo=OC_App::getAppInfo($app);
if (isset($appInfo['version'])) {
$currentVersion=$appInfo['version'];
@ -395,6 +447,19 @@ class OC_App{
}
}
/**
* get the installed version of all papps
*/
public static function getAppVersions(){
$versions=array();
$query = OC_DB::prepare( 'SELECT appid, configvalue FROM *PREFIX*appconfig WHERE configkey = \'installed_version\'' );
$result = $query->execute();
while($row = $result->fetchRow()){
$versions[$row['appid']]=$row['configvalue'];
}
return $versions;
}
/**
* update the database for the app and call the update script
* @param string appid

View File

@ -229,6 +229,39 @@ class OC{
}
}
public static function initTemplateEngine() {
// 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.16.custom.min" );
OC_Util::addScript( "jquery-showpassword" );
OC_Util::addScript( "jquery.infieldlabel.min" );
OC_Util::addScript( "jquery-tipsy" );
OC_Util::addScript( "oc-dialogs" );
OC_Util::addScript( "js" );
OC_Util::addScript( "eventsource" );
OC_Util::addScript( "config" );
//OC_Util::addScript( "multiselect" );
OC_Util::addScript('search','result');
OC_Util::addStyle( "styles" );
OC_Util::addStyle( "multiselect" );
OC_Util::addStyle( "jquery-ui-1.8.16.custom" );
OC_Util::addStyle( "jquery-tipsy" );
}
public static function initSession() {
ini_set('session.cookie_httponly','1;');
session_start();
}
public static function init(){
// register autoloader
spl_autoload_register(array('OC','autoload'));
@ -244,6 +277,24 @@ class OC{
date_default_timezone_set('Europe/Berlin');
ini_set('arg_separator.output','&amp;');
//try to configure php to enable big file uploads.
//this doesn´t work always depending on the webserver and php configuration.
//Let´s try to overwrite some defaults anyways
//try to set the maximum execution time to 60min
@set_time_limit(3600);
@ini_set('max_execution_time',3600);
@ini_set('max_input_time',3600);
//try to set the maximum filesize to 10G
@ini_set('upload_max_filesize','10G');
@ini_set('post_max_size','10G');
@ini_set('file_uploads','50');
//try to set the session lifetime to 60min
@ini_set('gc_maxlifetime','3600');
//set http auth headers for apache+php-cgi work around
if (isset($_SERVER['HTTP_AUTHORIZATION']) && preg_match('/Basic\s+(.*)$/i', $_SERVER['HTTP_AUTHORIZATION'], $matches))
{
@ -270,38 +321,11 @@ class OC{
self::checkInstalled();
self::checkSSL();
self::initSession();
self::initTemplateEngine();
self::checkUpgrade();
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.16.custom.min" );
OC_Util::addScript( "jquery-showpassword" );
OC_Util::addScript( "jquery.infieldlabel.min" );
OC_Util::addScript( "jquery-tipsy" );
OC_Util::addScript( "oc-dialogs" );
OC_Util::addScript( "js" );
OC_Util::addScript( "eventsource" );
OC_Util::addScript( "config" );
//OC_Util::addScript( "multiselect" );
OC_Util::addScript('search','result');
OC_Util::addStyle( "styles" );
OC_Util::addStyle( "multiselect" );
OC_Util::addStyle( "jquery-ui-1.8.16.custom" );
OC_Util::addStyle( "jquery-tipsy" );
$errors=OC_Util::checkServer();
if(count($errors)>0) {
OC_Template::printGuestPage('', 'error', array('errors' => $errors));
@ -333,8 +357,13 @@ class OC{
// Load Apps
// This includes plugins for users and filesystems as well
global $RUNTIME_NOAPPS;
global $RUNTIME_APPTYPES;
if(!$RUNTIME_NOAPPS ){
OC_App::loadApps();
if($RUNTIME_APPTYPES){
OC_App::loadApps($RUNTIME_APPTYPES);
}else{
OC_App::loadApps();
}
}
//make sure temporary files are cleaned up

View File

@ -318,9 +318,6 @@ class OC_DB {
// Make changes and save them to an in-memory file
$file2 = 'static://db_scheme';
if($file2 == ''){
die('could not create tempfile in get_temp_dir() - aborting');
}
$content = str_replace( '*dbname*', $CONFIG_DBNAME, $content );
$content = str_replace( '*dbprefix*', $CONFIG_DBTABLEPREFIX, $content );
if( $CONFIG_DBTYPE == 'pgsql' ){ //mysql support it too but sqlite doesn't

View File

@ -32,6 +32,7 @@ class OC_EventSource{
private $fallBackId=0;
public function __construct(){
@ob_end_clean();
header('Cache-Control: no-cache');
$this->fallback=isset($_GET['fallback']) and $_GET['fallback']=='true';
if($this->fallback){
@ -58,7 +59,7 @@ class OC_EventSource{
$type=null;
}
if($this->fallback){
$response='<script type="text/javascript">window.parent.OC.EventSource.fallBackCallBack('.$this->fallBackId.',"'.$type.'","'.json_encode($data).'")</script>'.PHP_EOL;
$response='<script type="text/javascript">window.parent.OC.EventSource.fallBackCallBack('.$this->fallBackId.',"'.$type.'",'.json_encode($data).')</script>'.PHP_EOL;
echo $response;
}else{
if($type){

View File

@ -59,8 +59,8 @@ class OC_FileCache{
$root='';
}
$path=$root.$path;
$query=OC_DB::prepare('SELECT ctime,mtime,mimetype,size,encrypted,versioned,writable FROM *PREFIX*fscache WHERE path=?');
$result=$query->execute(array($path))->fetchRow();
$query=OC_DB::prepare('SELECT ctime,mtime,mimetype,size,encrypted,versioned,writable FROM *PREFIX*fscache WHERE path_hash=?');
$result=$query->execute(array(md5($path)))->fetchRow();
if(is_array($result)){
return $result;
}else{
@ -111,8 +111,8 @@ class OC_FileCache{
}
$mimePart=dirname($data['mimetype']);
$user=OC_User::getUser();
$query=OC_DB::prepare('INSERT INTO *PREFIX*fscache(parent, name, path, size, mtime, ctime, mimetype, mimepart,user,writable,encrypted,versioned) VALUES(?,?,?,?,?,?,?,?,?,?,?,?)');
$result=$query->execute(array($parent,basename($path),$path,$data['size'],$data['mtime'],$data['ctime'],$data['mimetype'],$mimePart,$user,$data['writable'],$data['encrypted'],$data['versioned']));
$query=OC_DB::prepare('INSERT INTO *PREFIX*fscache(parent, name, path, path_hash, size, mtime, ctime, mimetype, mimepart,user,writable,encrypted,versioned) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?)');
$result=$query->execute(array($parent,basename($path),$path,md5($path),$data['size'],$data['mtime'],$data['ctime'],$data['mimetype'],$mimePart,$user,$data['writable'],$data['encrypted'],$data['versioned']));
if(OC_DB::isError($result)){
OC_Log::write('files','error while writing file('.$path.') to cache',OC_Log::ERROR);
}
@ -162,8 +162,8 @@ class OC_FileCache{
$oldPath=$root.$oldPath;
$newPath=$root.$newPath;
$newParent=self::getParentId($newPath);
$query=OC_DB::prepare('UPDATE *PREFIX*fscache SET parent=? ,name=?, path=? WHERE path=?');
$query->execute(array($newParent,basename($newPath),$newPath,$oldPath));
$query=OC_DB::prepare('UPDATE *PREFIX*fscache SET parent=? ,name=?, path=?, path_hash=? WHERE path_hash=?');
$query->execute(array($newParent,basename($newPath),$newPath,md5($newPath),md5($oldPath)));
}
/**
@ -285,12 +285,12 @@ class OC_FileCache{
* @return int
*/
private static function getFileId($path){
$query=OC_DB::prepare('SELECT id FROM *PREFIX*fscache WHERE path=?');
$query=OC_DB::prepare('SELECT id FROM *PREFIX*fscache WHERE path_hash=?');
if(OC_DB::isError($query)){
OC_Log::write('files','error while getting file id of '.$path,OC_Log::ERROR);
return -1;
}
$result=$query->execute(array($path));
$result=$query->execute(array(md5($path)));
if(OC_DB::isError($result)){
OC_Log::write('files','error while getting file id of '.$path,OC_Log::ERROR);
return -1;
@ -367,8 +367,8 @@ class OC_FileCache{
}
}
$path=$root.$path;
$query=OC_DB::prepare('SELECT ctime,mtime,mimetype,size,encrypted,versioned,writable FROM *PREFIX*fscache WHERE path=?');
$result=$query->execute(array($path))->fetchRow();
$query=OC_DB::prepare('SELECT ctime,mtime,mimetype,size,encrypted,versioned,writable FROM *PREFIX*fscache WHERE path_hash=?');
$result=$query->execute(array(md5($path)))->fetchRow();
if(is_array($result)){
if(isset(self::$savedData[$path])){
$result=array_merge($result,self::$savedData[$path]);
@ -389,8 +389,8 @@ class OC_FileCache{
}
}
$path=$root.$path;
$query=OC_DB::prepare('SELECT size FROM *PREFIX*fscache WHERE path=?');
$result=$query->execute(array($path));
$query=OC_DB::prepare('SELECT size FROM *PREFIX*fscache WHERE path_hash=?');
$result=$query->execute(array(md5($path)));
if($row=$result->fetchRow()){
return $row['size'];
}else{//file not in cache
@ -469,6 +469,10 @@ class OC_FileCache{
* @param string root (optionak)
*/
public static function scan($path,$eventSource=false,&$count=0,$root=''){
if($eventSource){
$eventSource->send('scanning',array('file'=>$path,'count'=>$count));
}
$lastSend=$count;
if(!$root){
$view=OC_Filesystem::getView();
}else{
@ -482,13 +486,14 @@ class OC_FileCache{
if($filename != '.' and $filename != '..'){
$file=$path.'/'.$filename;
if($view->is_dir($file.'/')){
if($eventSource){
$eventSource->send('scanning',array('file'=>$file,'count'=>$count));
}
self::scan($file,$eventSource,$count,$root);
}else{
$totalSize+=self::scanFile($file,$root);
$count++;
if($count>$lastSend+25 and $eventSource){
$lastSend=$count;
$eventSource->send('scanning',array('file'=>$path,'count'=>$count));
}
}
}
}
@ -579,8 +584,8 @@ class OC_FileCache{
$mtime=$view->filemtime($path);
$isDir=$view->is_dir($path);
$path=$root.$path;
$query=OC_DB::prepare('SELECT mtime FROM *PREFIX*fscache WHERE path=?');
$result=$query->execute(array($path));
$query=OC_DB::prepare('SELECT mtime FROM *PREFIX*fscache WHERE path_hash=?');
$result=$query->execute(array(md5($path)));
if($row=$result->fetchRow()){
$cachedMTime=$row['mtime'];
return ($mtime>$cachedMTime);
@ -637,6 +642,14 @@ class OC_FileCache{
self::fileSystemWatcherWrite(array('path'=>$path),$root);
}
}
/**
* clean old pre-path_hash entries
*/
public static function clean(){
$query=OC_DB::prepare('DELETE FROM *PREFIX*fscache WHERE LENGTH(path_hash)<30');
$query->execute();
}
}
//watch for changes and try to keep the cache up to date

View File

@ -86,6 +86,10 @@ class OC_Filestorage_Local extends OC_Filestorage{
return $this->delTree($path);
}
public function rename($path1,$path2){
if (!$this->is_writable($path1)) {
OC_Log::write('core','unable to rename, file is not writable : '.$path1,OC_Log::ERROR);
return false;
}
if(! $this->file_exists($path1)){
OC_Log::write('core','unable to rename, file does not exists : '.$path1,OC_Log::ERROR);
return false;

View File

@ -137,13 +137,16 @@ class OC_FilesystemView {
}
public function readfile($path){
$handle=$this->fopen($path,'r');
$chunkSize = 1024*1024;// 1 MB chunks
while (!feof($handle)) {
echo fread($handle, $chunkSize);
@ob_flush();
flush();
if ($handle) {
$chunkSize = 1024*1024;// 1 MB chunks
while (!feof($handle)) {
echo fread($handle, $chunkSize);
@ob_flush();
flush();
}
return $this->filesize($path);
}
return $this->filesize($path);
return false;
}
public function is_readable($path){
return $this->basicOperation('is_readable',$path);
@ -189,7 +192,7 @@ class OC_FilesystemView {
return $this->basicOperation('unlink',$path,array('delete'));
}
public function rename($path1,$path2){
if(OC_FileProxy::runPreProxies('rename',$path1,$path2) and $this->is_writable($path1) and OC_Filesystem::isValidPath($path2)){
if(OC_FileProxy::runPreProxies('rename',$path1,$path2) and OC_Filesystem::isValidPath($path2)){
$run=true;
OC_Hook::emit( OC_Filesystem::CLASSNAME, OC_Filesystem::signal_rename, array( OC_Filesystem::signal_param_oldpath => $path1 , OC_Filesystem::signal_param_newpath=>$path2, OC_Filesystem::signal_param_run => &$run));
if($run){

View File

@ -432,6 +432,19 @@ class OC_Helper {
self::$tmpFiles[]=$file;
return $file;
}
/**
* create a temporary folder with an unique filename
* @return string
*
* temporary files are automatically cleaned up after the script is finished
*/
public static function tmpFolder(){
$path=get_temp_dir().'/'.md5(time().rand());
mkdir($path);
self::$tmpFiles[]=$path;
return $path.'/';
}
/**
* remove all files created by self::tmpFile
@ -439,7 +452,7 @@ class OC_Helper {
public static function cleanTmp(){
foreach(self::$tmpFiles as $file){
if(file_exists($file)){
unlink($file);
self::rmdirr($file);
}
}
}

View File

@ -62,7 +62,7 @@ class OC_Installer{
//download the file if necesary
if($data['source']=='http'){
$path=OC_Helper::tmpFile('.zip');
$path=OC_Helper::tmpFile();
if(!isset($data['href'])){
OC_Log::write('core','No href specified when installing app from http',OC_Log::ERROR);
return false;
@ -76,14 +76,24 @@ class OC_Installer{
$path=$data['path'];
}
//detect the archive type
$mime=OC_Helper::getMimeType($path);
if($mime=='application/zip'){
rename($path,$path.'.zip');
$path.='.zip';
}elseif($mime=='application/x-gzip'){
rename($path,$path.'.tgz');
$path.='.tgz';
}else{
OC_Log::write('core','Archives of type '.$mime.' are not supported',OC_Log::ERROR);
return false;
}
//extract the archive in a temporary folder
$extractDir=tempnam(get_temp_dir(),'oc_installer_uncompressed_');
unlink($extractDir);
$extractDir=OC_Helper::tmpFolder();
mkdir($extractDir);
$zip = new ZipArchive;
if($zip->open($path)===true){
$zip->extractTo($extractDir);
$zip->close();
if($archive=OC_Archive::open($path)){
$archive->extract($extractDir);
} else {
OC_Log::write('core','Failed to open archive when installing app',OC_Log::ERROR);
OC_Helper::rmdirr($extractDir);
@ -94,6 +104,17 @@ class OC_Installer{
}
//load the info.xml file of the app
if(!is_file($extractDir.'/appinfo/info.xml')){
//try to find it in a subdir
$dh=opendir($extractDir);
while($folder=readdir($dh)){
if(substr($folder,0,1)!='.' and is_dir($extractDir.'/'.$folder)){
if(is_file($extractDir.'/'.$folder.'/appinfo/info.xml')){
$extractDir.='/'.$folder;
}
}
}
}
if(!is_file($extractDir.'/appinfo/info.xml')){
OC_Log::write('core','App does not provide an info.xml file',OC_Log::ERROR);
OC_Helper::rmdirr($extractDir);
@ -102,7 +123,7 @@ class OC_Installer{
}
return false;
}
$info=OC_App::getAppInfo($extractDir.'/appinfo/info.xml');
$info=OC_App::getAppInfo($extractDir.'/appinfo/info.xml',true);
$basedir=OC::$APPSROOT.'/apps/'.$info['id'];
//check if an app with the same id is already installed
@ -275,7 +296,7 @@ class OC_Installer{
if(is_file(OC::$APPSROOT."/apps/$app/appinfo/install.php")){
include(OC::$APPSROOT."/apps/$app/appinfo/install.php");
}
$info=OC_App::getAppInfo(OC::$APPSROOT."/apps/$app/appinfo/info.xml");
$info=OC_App::getAppInfo($app);
OC_Appconfig::setValue($app,'installed_version',$info['version']);
return $info;
}

View File

@ -1,78 +1,39 @@
<?php
/**
* ownCloud
*
* @author Robin Appelman
* @copyright 2012 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/>.
*
* Copyright (c) 2012 Bart Visscher <bartv@thisnet.nl>
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
/**
*logging utilities
* logging utilities
*
* Log is saved at data/owncloud.log (on default)
* Log is saved by default at data/owncloud.log using OC_Log_Owncloud.
* Selecting other backend is done with a config option 'log_type'.
*/
class OC_Log{
class OC_Log {
const DEBUG=0;
const INFO=1;
const WARN=2;
const ERROR=3;
const FATAL=4;
static protected $class = null;
/**
* 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 write($app, $message, $level) {
if (!self::$class) {
self::$class = 'OC_Log_'.ucfirst(OC_Config::getValue('log_type', 'owncloud'));
call_user_func(array(self::$class, 'init'));
}
}
/**
* get entries from the log in reverse chronological order
* @param int limit
* @param int offset
* @return array
*/
public static function getEntries($limit=50,$offset=0){
$datadir=OC_Config::getValue( "datadirectory", OC::$SERVERROOT.'/data' );
$logFile=OC_Config::getValue( "logfile", $datadir.'/owncloud.log' );
$entries=array();
if(!file_exists($logFile)){
return array();
}
$contents=file($logFile);
if(!$contents){//error while reading log
return array();
}
$end=max(count($contents)-$offset-1,0);
$start=max($end-$limit,0);
for($i=$end;$i>$start;$i--){
$entries[]=json_decode($contents[$i]);
}
return $entries;
$log_class=self::$class;
$log_class::write($app, $message, $level);
}
}

79
lib/log/owncloud.php Normal file
View File

@ -0,0 +1,79 @@
<?php
/**
* ownCloud
*
* @author Robin Appelman
* @copyright 2012 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_Owncloud {
static protected $logFile;
/**
* Init class data
*/
public static function init() {
$datadir=OC_Config::getValue( "datadirectory", OC::$SERVERROOT.'/data' );
self::$logFile=OC_Config::getValue( "logfile", $datadir.'/owncloud.log' );
}
/**
* 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){
$entry=array('app'=>$app, 'message'=>$message, 'level'=>$level,'time'=>time());
$fh=fopen(self::$logFile, 'a');
fwrite($fh, json_encode($entry)."\n");
fclose($fh);
}
}
/**
* get entries from the log in reverse chronological order
* @param int limit
* @param int offset
* @return array
*/
public static function getEntries($limit=50, $offset=0){
self::init();
$entries=array();
if(!file_exists(self::$logFile)) {
return array();
}
$contents=file(self::$logFile);
if(!$contents) {//error while reading log
return array();
}
$end=max(count($contents)-$offset-1, 0);
$start=max($end-$limit,0);
for($i=$end;$i>$start;$i--) {
$entries[]=json_decode($contents[$i]);
}
return $entries;
}
}

37
lib/log/syslog.php Normal file
View File

@ -0,0 +1,37 @@
<?php
/**
* Copyright (c) 2012 Bart Visscher <bartv@thisnet.nl>
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
class OC_Log_Syslog {
static protected $levels = array(
OC_Log::DEBUG => LOG_DEBUG,
OC_Log::INFO => LOG_INFO,
OC_Log::WARN => LOG_WARNING,
OC_Log::ERROR => LOG_ERR,
OC_Log::FATAL => LOG_CRIT,
);
/**
* Init class data
*/
public static function init() {
openlog('ownCloud', LOG_PID | LOG_CONS, LOG_USER);
// Close at shutdown
register_shutdown_function('closelog');
}
/**
* write a message in the log
* @param string $app
* @param string $message
* @param int level
*/
public static function write($app, $message, $level) {
$syslog_level = self::$levels[$level];
syslog($syslog_level, '{'.$app.'} '.$message);
}
}

View File

@ -36,6 +36,7 @@ class OC_Updater{
$version['installed']=OC_Config::getValue('installedat');
$version['updated']=OC_Appconfig::getValue('core', 'lastupdatedat', OC_Config::getValue( 'lastupdatedat'));
$version['updatechannel']='stable';
$version['edition']=OC_Util::getEditionString();
$versionstring=implode('x',$version);
//fetch xml data from updater

View File

@ -66,7 +66,7 @@ class OC_Util {
* @return array
*/
public static function getVersion(){
return array(3,00,3);
return array(3,00,4);
}
/**
@ -77,6 +77,14 @@ class OC_Util {
return '3';
}
/**
* get the current installed edition of ownCloud. There is the community edition that just returns an empty string and the enterprise edition that returns "Enterprise".
* @return string
*/
public static function getEditionString(){
return '';
}
/**
* add a javascript file
*

View File

@ -13,5 +13,5 @@ OC_JSON::checkAdminUser();
$count=(isset($_GET['count']))?$_GET['count']:50;
$offset=(isset($_GET['offset']))?$_GET['offset']:0;
$entries=OC_Log::getEntries($count,$offset);
$entries=OC_Log_Owncloud::getEntries($count,$offset);
OC_JSON::success(array("data" => $entries));

View File

@ -28,7 +28,7 @@ OC_Util::addStyle( "settings", "settings" );
OC_Util::addScript( "settings", "apps" );
OC_App::setActiveNavigationEntry( "core_log" );
$entries=OC_Log::getEntries();
$entries=OC_Log_Owncloud::getEntries();
OC_Util::addScript('settings','log');
OC_Util::addStyle('settings','settings');

View File

@ -50,7 +50,7 @@
};?>
<p class="personalblock">
<strong>ownCloud</strong> <?php echo(OC_Util::getVersionString()); ?><br />
<strong>ownCloud</strong> <?php echo(OC_Util::getVersionString()); ?> <?php echo(OC_Util::getEditionString()); ?><br />
developed by the <a href="http://ownCloud.org/credits" target="_blank">ownCloud community</a><br />
<?php echo(OC_Updater::ShowUpdatingHint()); ?><br />
<a href="http://gitorious.org/owncloud" target="_blank">source code</a> licensed freely under <a href="http://www.gnu.org/licenses/agpl-3.0.html" target="_blank">AGPL</a>

View File

@ -26,7 +26,7 @@ $RUNTIME_NOAPPS = TRUE; //no apps, yet
require_once('lib/base.php');
if(OC_Config::getValue('installed')==1) $installed='true'; else $installed='false';
$values=array('installed'=>$installed,'version'=>implode('.',OC_Util::getVersion()),'versionstring'=>OC_Util::getVersionString());
$values=array('installed'=>$installed,'version'=>implode('.',OC_Util::getVersion()),'versionstring'=>OC_Util::getVersionString(),'edition'=>OC_Util::getEditionString());
echo(json_encode($values));

View File

@ -38,6 +38,7 @@ foreach($apps as $app){
}
function loadTests($dir=''){
$test=isset($_GET['test'])?$_GET['test']:false;
if($dh=opendir($dir)){
while($name=readdir($dh)){
if(substr($name,0,1)!='.'){//no hidden files, '.' or '..'
@ -45,10 +46,13 @@ function loadTests($dir=''){
if(is_dir($file)){
loadTests($file);
}elseif(substr($file,-4)=='.php' and $file!=__FILE__){
$testCase=new TestSuite(getTestName($file));
$testCase->addFile($file);
if($testCase->getSize()>0){
$testCase->run(new HtmlReporter());
$name=getTestName($file);
if($test===false or $test==$name or substr($name,0,strlen($test))==$test){
$testCase=new TestSuite($name);
$testCase->addFile($file);
if($testCase->getSize()>0){
$testCase->run(new HtmlReporter());
}
}
}
}