Merge branch 'master' into routing
Conflicts: lib/ocs.php
This commit is contained in:
commit
0040b7109f
65 changed files with 3411 additions and 1297 deletions
278
3rdparty/miniColors/GPL-LICENSE.txt
vendored
Normal file
278
3rdparty/miniColors/GPL-LICENSE.txt
vendored
Normal file
|
@ -0,0 +1,278 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
20
3rdparty/miniColors/MIT-LICENSE.txt
vendored
Normal file
20
3rdparty/miniColors/MIT-LICENSE.txt
vendored
Normal file
|
@ -0,0 +1,20 @@
|
|||
Copyright (c) Cory LaViska
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
BIN
3rdparty/miniColors/css/images/colors.png
vendored
Executable file
BIN
3rdparty/miniColors/css/images/colors.png
vendored
Executable file
Binary file not shown.
After Width: | Height: | Size: 12 KiB |
BIN
3rdparty/miniColors/css/images/trigger.png
vendored
Executable file
BIN
3rdparty/miniColors/css/images/trigger.png
vendored
Executable file
Binary file not shown.
After Width: | Height: | Size: 1.4 KiB |
81
3rdparty/miniColors/css/jquery.miniColors.css
vendored
Executable file
81
3rdparty/miniColors/css/jquery.miniColors.css
vendored
Executable file
|
@ -0,0 +1,81 @@
|
|||
.miniColors-trigger {
|
||||
height: 22px;
|
||||
width: 22px;
|
||||
background: url(images/trigger.png) center no-repeat;
|
||||
vertical-align: middle;
|
||||
margin: 0 .25em;
|
||||
display: inline-block;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.miniColors-selector {
|
||||
position: absolute;
|
||||
width: 175px;
|
||||
height: 150px;
|
||||
background: #FFF;
|
||||
border: solid 1px #BBB;
|
||||
-moz-box-shadow: 0 0 6px rgba(0, 0, 0, .25);
|
||||
-webkit-box-shadow: 0 0 6px rgba(0, 0, 0, .25);
|
||||
box-shadow: 0 0 6px rgba(0, 0, 0, .25);
|
||||
-moz-border-radius: 5px;
|
||||
-webkit-border-radius: 5px;
|
||||
border-radius: 5px;
|
||||
padding: 5px;
|
||||
z-index: 999999;
|
||||
}
|
||||
|
||||
.miniColors-selector.black {
|
||||
background: #000;
|
||||
border-color: #000;
|
||||
}
|
||||
|
||||
.miniColors-colors {
|
||||
position: absolute;
|
||||
top: 5px;
|
||||
left: 5px;
|
||||
width: 150px;
|
||||
height: 150px;
|
||||
background: url(images/colors.png) right no-repeat;
|
||||
cursor: crosshair;
|
||||
}
|
||||
|
||||
.miniColors-hues {
|
||||
position: absolute;
|
||||
top: 5px;
|
||||
left: 160px;
|
||||
width: 20px;
|
||||
height: 150px;
|
||||
background: url(images/colors.png) left no-repeat;
|
||||
cursor: crosshair;
|
||||
}
|
||||
|
||||
.miniColors-colorPicker {
|
||||
position: absolute;
|
||||
width: 9px;
|
||||
height: 9px;
|
||||
border: 1px solid #fff;
|
||||
-moz-border-radius: 11px;
|
||||
-webkit-border-radius: 11px;
|
||||
border-radius: 11px;
|
||||
}
|
||||
.miniColors-colorPicker-inner {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 7px;
|
||||
height: 7px;
|
||||
border: 1px solid #000;
|
||||
-moz-border-radius: 9px;
|
||||
-webkit-border-radius: 9px;
|
||||
border-radius: 9px;
|
||||
}
|
||||
|
||||
.miniColors-huePicker {
|
||||
position: absolute;
|
||||
left: -3px;
|
||||
width: 24px;
|
||||
height: 1px;
|
||||
border: 1px solid #fff;
|
||||
border-radius: 2px;
|
||||
background: #000;
|
||||
}
|
580
3rdparty/miniColors/js/jquery.miniColors.js
vendored
Executable file
580
3rdparty/miniColors/js/jquery.miniColors.js
vendored
Executable file
|
@ -0,0 +1,580 @@
|
|||
/*
|
||||
* jQuery miniColors: A small color selector
|
||||
*
|
||||
* Copyright 2011 Cory LaViska for A Beautiful Site, LLC. (http://abeautifulsite.net/)
|
||||
*
|
||||
* Dual licensed under the MIT or GPL Version 2 licenses
|
||||
*
|
||||
*/
|
||||
if(jQuery) (function($) {
|
||||
|
||||
$.extend($.fn, {
|
||||
|
||||
miniColors: function(o, data) {
|
||||
|
||||
var create = function(input, o, data) {
|
||||
//
|
||||
// Creates a new instance of the miniColors selector
|
||||
//
|
||||
|
||||
// Determine initial color (defaults to white)
|
||||
var color = expandHex(input.val());
|
||||
if( !color ) color = 'ffffff';
|
||||
var hsb = hex2hsb(color);
|
||||
|
||||
// Create trigger
|
||||
var trigger = $('<a class="miniColors-trigger" style="background-color: #' + color + '" href="#"></a>');
|
||||
trigger.insertAfter(input);
|
||||
|
||||
// Set input data and update attributes
|
||||
input
|
||||
.addClass('miniColors')
|
||||
.data('original-maxlength', input.attr('maxlength') || null)
|
||||
.data('original-autocomplete', input.attr('autocomplete') || null)
|
||||
.data('letterCase', 'uppercase')
|
||||
.data('trigger', trigger)
|
||||
.data('hsb', hsb)
|
||||
.data('change', o.change ? o.change : null)
|
||||
.data('close', o.close ? o.close : null)
|
||||
.data('open', o.open ? o.open : null)
|
||||
.attr('maxlength', 7)
|
||||
.attr('autocomplete', 'off')
|
||||
.val('#' + convertCase(color, o.letterCase));
|
||||
|
||||
// Handle options
|
||||
if( o.readonly ) input.prop('readonly', true);
|
||||
if( o.disabled ) disable(input);
|
||||
|
||||
// Show selector when trigger is clicked
|
||||
trigger.bind('click.miniColors', function(event) {
|
||||
event.preventDefault();
|
||||
if( input.val() === '' ) input.val('#');
|
||||
show(input);
|
||||
|
||||
});
|
||||
|
||||
// Show selector when input receives focus
|
||||
input.bind('focus.miniColors', function(event) {
|
||||
if( input.val() === '' ) input.val('#');
|
||||
show(input);
|
||||
});
|
||||
|
||||
// Hide on blur
|
||||
input.bind('blur.miniColors', function(event) {
|
||||
var hex = expandHex( hsb2hex(input.data('hsb')) );
|
||||
input.val( hex ? '#' + convertCase(hex, input.data('letterCase')) : '' );
|
||||
});
|
||||
|
||||
// Hide when tabbing out of the input
|
||||
input.bind('keydown.miniColors', function(event) {
|
||||
if( event.keyCode === 9 ) hide(input);
|
||||
});
|
||||
|
||||
// Update when color is typed in
|
||||
input.bind('keyup.miniColors', function(event) {
|
||||
setColorFromInput(input);
|
||||
});
|
||||
|
||||
// Handle pasting
|
||||
input.bind('paste.miniColors', function(event) {
|
||||
// Short pause to wait for paste to complete
|
||||
setTimeout( function() {
|
||||
setColorFromInput(input);
|
||||
}, 5);
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
var destroy = function(input) {
|
||||
//
|
||||
// Destroys an active instance of the miniColors selector
|
||||
//
|
||||
|
||||
hide();
|
||||
input = $(input);
|
||||
|
||||
// Restore to original state
|
||||
input.data('trigger').remove();
|
||||
input
|
||||
.attr('autocomplete', input.data('original-autocomplete'))
|
||||
.attr('maxlength', input.data('original-maxlength'))
|
||||
.removeData()
|
||||
.removeClass('miniColors')
|
||||
.unbind('.miniColors');
|
||||
$(document).unbind('.miniColors');
|
||||
};
|
||||
|
||||
var enable = function(input) {
|
||||
//
|
||||
// Enables the input control and the selector
|
||||
//
|
||||
input
|
||||
.prop('disabled', false)
|
||||
.data('trigger')
|
||||
.css('opacity', 1);
|
||||
};
|
||||
|
||||
var disable = function(input) {
|
||||
//
|
||||
// Disables the input control and the selector
|
||||
//
|
||||
hide(input);
|
||||
input
|
||||
.prop('disabled', true)
|
||||
.data('trigger')
|
||||
.css('opacity', 0.5);
|
||||
};
|
||||
|
||||
var show = function(input) {
|
||||
//
|
||||
// Shows the miniColors selector
|
||||
//
|
||||
if( input.prop('disabled') ) return false;
|
||||
|
||||
// Hide all other instances
|
||||
hide();
|
||||
|
||||
// Generate the selector
|
||||
var selector = $('<div class="miniColors-selector"></div>');
|
||||
selector
|
||||
.append('<div class="miniColors-colors" style="background-color: #FFF;"><div class="miniColors-colorPicker"><div class="miniColors-colorPicker-inner"></div></div>')
|
||||
.append('<div class="miniColors-hues"><div class="miniColors-huePicker"></div></div>')
|
||||
.css({
|
||||
top: input.is(':visible') ? input.offset().top + input.outerHeight() : input.data('trigger').offset().top + input.data('trigger').outerHeight(),
|
||||
left: input.is(':visible') ? input.offset().left : input.data('trigger').offset().left,
|
||||
display: 'none'
|
||||
})
|
||||
.addClass( input.attr('class') );
|
||||
|
||||
// Set background for colors
|
||||
var hsb = input.data('hsb');
|
||||
selector
|
||||
.find('.miniColors-colors')
|
||||
.css('backgroundColor', '#' + hsb2hex({ h: hsb.h, s: 100, b: 100 }));
|
||||
|
||||
// Set colorPicker position
|
||||
var colorPosition = input.data('colorPosition');
|
||||
if( !colorPosition ) colorPosition = getColorPositionFromHSB(hsb);
|
||||
selector.find('.miniColors-colorPicker')
|
||||
.css('top', colorPosition.y + 'px')
|
||||
.css('left', colorPosition.x + 'px');
|
||||
|
||||
// Set huePicker position
|
||||
var huePosition = input.data('huePosition');
|
||||
if( !huePosition ) huePosition = getHuePositionFromHSB(hsb);
|
||||
selector.find('.miniColors-huePicker').css('top', huePosition.y + 'px');
|
||||
|
||||
// Set input data
|
||||
input
|
||||
.data('selector', selector)
|
||||
.data('huePicker', selector.find('.miniColors-huePicker'))
|
||||
.data('colorPicker', selector.find('.miniColors-colorPicker'))
|
||||
.data('mousebutton', 0);
|
||||
|
||||
$('BODY').append(selector);
|
||||
selector.fadeIn(100);
|
||||
|
||||
// Prevent text selection in IE
|
||||
selector.bind('selectstart', function() { return false; });
|
||||
|
||||
$(document).bind('mousedown.miniColors touchstart.miniColors', function(event) {
|
||||
|
||||
input.data('mousebutton', 1);
|
||||
var testSubject = $(event.target).parents().andSelf();
|
||||
|
||||
if( testSubject.hasClass('miniColors-colors') ) {
|
||||
event.preventDefault();
|
||||
input.data('moving', 'colors');
|
||||
moveColor(input, event);
|
||||
}
|
||||
|
||||
if( testSubject.hasClass('miniColors-hues') ) {
|
||||
event.preventDefault();
|
||||
input.data('moving', 'hues');
|
||||
moveHue(input, event);
|
||||
}
|
||||
|
||||
if( testSubject.hasClass('miniColors-selector') ) {
|
||||
event.preventDefault();
|
||||
return;
|
||||
}
|
||||
|
||||
if( testSubject.hasClass('miniColors') ) return;
|
||||
|
||||
hide(input);
|
||||
});
|
||||
|
||||
$(document)
|
||||
.bind('mouseup.miniColors touchend.miniColors', function(event) {
|
||||
event.preventDefault();
|
||||
input.data('mousebutton', 0).removeData('moving');
|
||||
})
|
||||
.bind('mousemove.miniColors touchmove.miniColors', function(event) {
|
||||
event.preventDefault();
|
||||
if( input.data('mousebutton') === 1 ) {
|
||||
if( input.data('moving') === 'colors' ) moveColor(input, event);
|
||||
if( input.data('moving') === 'hues' ) moveHue(input, event);
|
||||
}
|
||||
});
|
||||
|
||||
// Fire open callback
|
||||
if( input.data('open') ) {
|
||||
input.data('open').call(input.get(0), '#' + hsb2hex(hsb), hsb2rgb(hsb));
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
var hide = function(input) {
|
||||
|
||||
//
|
||||
// Hides one or more miniColors selectors
|
||||
//
|
||||
|
||||
// Hide all other instances if input isn't specified
|
||||
if( !input ) input = '.miniColors';
|
||||
|
||||
$(input).each( function() {
|
||||
var selector = $(this).data('selector');
|
||||
$(this).removeData('selector');
|
||||
$(selector).fadeOut(100, function() {
|
||||
// Fire close callback
|
||||
if( input.data('close') ) {
|
||||
var hsb = input.data('hsb'), hex = hsb2hex(hsb);
|
||||
input.data('close').call(input.get(0), '#' + hex, hsb2rgb(hsb));
|
||||
}
|
||||
$(this).remove();
|
||||
});
|
||||
});
|
||||
|
||||
$(document).unbind('.miniColors');
|
||||
|
||||
};
|
||||
|
||||
var moveColor = function(input, event) {
|
||||
|
||||
var colorPicker = input.data('colorPicker');
|
||||
|
||||
colorPicker.hide();
|
||||
|
||||
var position = {
|
||||
x: event.pageX,
|
||||
y: event.pageY
|
||||
};
|
||||
|
||||
// Touch support
|
||||
if( event.originalEvent.changedTouches ) {
|
||||
position.x = event.originalEvent.changedTouches[0].pageX;
|
||||
position.y = event.originalEvent.changedTouches[0].pageY;
|
||||
}
|
||||
position.x = position.x - input.data('selector').find('.miniColors-colors').offset().left - 5;
|
||||
position.y = position.y - input.data('selector').find('.miniColors-colors').offset().top - 5;
|
||||
if( position.x <= -5 ) position.x = -5;
|
||||
if( position.x >= 144 ) position.x = 144;
|
||||
if( position.y <= -5 ) position.y = -5;
|
||||
if( position.y >= 144 ) position.y = 144;
|
||||
|
||||
input.data('colorPosition', position);
|
||||
colorPicker.css('left', position.x).css('top', position.y).show();
|
||||
|
||||
// Calculate saturation
|
||||
var s = Math.round((position.x + 5) * 0.67);
|
||||
if( s < 0 ) s = 0;
|
||||
if( s > 100 ) s = 100;
|
||||
|
||||
// Calculate brightness
|
||||
var b = 100 - Math.round((position.y + 5) * 0.67);
|
||||
if( b < 0 ) b = 0;
|
||||
if( b > 100 ) b = 100;
|
||||
|
||||
// Update HSB values
|
||||
var hsb = input.data('hsb');
|
||||
hsb.s = s;
|
||||
hsb.b = b;
|
||||
|
||||
// Set color
|
||||
setColor(input, hsb, true);
|
||||
};
|
||||
|
||||
var moveHue = function(input, event) {
|
||||
|
||||
var huePicker = input.data('huePicker');
|
||||
|
||||
huePicker.hide();
|
||||
|
||||
var position = {
|
||||
y: event.pageY
|
||||
};
|
||||
|
||||
// Touch support
|
||||
if( event.originalEvent.changedTouches ) {
|
||||
position.y = event.originalEvent.changedTouches[0].pageY;
|
||||
}
|
||||
|
||||
position.y = position.y - input.data('selector').find('.miniColors-colors').offset().top - 1;
|
||||
if( position.y <= -1 ) position.y = -1;
|
||||
if( position.y >= 149 ) position.y = 149;
|
||||
input.data('huePosition', position);
|
||||
huePicker.css('top', position.y).show();
|
||||
|
||||
// Calculate hue
|
||||
var h = Math.round((150 - position.y - 1) * 2.4);
|
||||
if( h < 0 ) h = 0;
|
||||
if( h > 360 ) h = 360;
|
||||
|
||||
// Update HSB values
|
||||
var hsb = input.data('hsb');
|
||||
hsb.h = h;
|
||||
|
||||
// Set color
|
||||
setColor(input, hsb, true);
|
||||
|
||||
};
|
||||
|
||||
var setColor = function(input, hsb, updateInput) {
|
||||
input.data('hsb', hsb);
|
||||
var hex = hsb2hex(hsb);
|
||||
if( updateInput ) input.val( '#' + convertCase(hex, input.data('letterCase')) );
|
||||
input.data('trigger').css('backgroundColor', '#' + hex);
|
||||
if( input.data('selector') ) input.data('selector').find('.miniColors-colors').css('backgroundColor', '#' + hsb2hex({ h: hsb.h, s: 100, b: 100 }));
|
||||
|
||||
// Fire change callback
|
||||
if( input.data('change') ) {
|
||||
if( hex === input.data('lastChange') ) return;
|
||||
input.data('change').call(input.get(0), '#' + hex, hsb2rgb(hsb));
|
||||
input.data('lastChange', hex);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
var setColorFromInput = function(input) {
|
||||
|
||||
input.val('#' + cleanHex(input.val()));
|
||||
var hex = expandHex(input.val());
|
||||
if( !hex ) return false;
|
||||
|
||||
// Get HSB equivalent
|
||||
var hsb = hex2hsb(hex);
|
||||
|
||||
// If color is the same, no change required
|
||||
var currentHSB = input.data('hsb');
|
||||
if( hsb.h === currentHSB.h && hsb.s === currentHSB.s && hsb.b === currentHSB.b ) return true;
|
||||
|
||||
// Set colorPicker position
|
||||
var colorPosition = getColorPositionFromHSB(hsb);
|
||||
var colorPicker = $(input.data('colorPicker'));
|
||||
colorPicker.css('top', colorPosition.y + 'px').css('left', colorPosition.x + 'px');
|
||||
input.data('colorPosition', colorPosition);
|
||||
|
||||
// Set huePosition position
|
||||
var huePosition = getHuePositionFromHSB(hsb);
|
||||
var huePicker = $(input.data('huePicker'));
|
||||
huePicker.css('top', huePosition.y + 'px');
|
||||
input.data('huePosition', huePosition);
|
||||
|
||||
setColor(input, hsb);
|
||||
|
||||
return true;
|
||||
|
||||
};
|
||||
|
||||
var convertCase = function(string, letterCase) {
|
||||
if( letterCase === 'lowercase' ) return string.toLowerCase();
|
||||
if( letterCase === 'uppercase' ) return string.toUpperCase();
|
||||
return string;
|
||||
};
|
||||
|
||||
var getColorPositionFromHSB = function(hsb) {
|
||||
var x = Math.ceil(hsb.s / 0.67);
|
||||
if( x < 0 ) x = 0;
|
||||
if( x > 150 ) x = 150;
|
||||
var y = 150 - Math.ceil(hsb.b / 0.67);
|
||||
if( y < 0 ) y = 0;
|
||||
if( y > 150 ) y = 150;
|
||||
return { x: x - 5, y: y - 5 };
|
||||
};
|
||||
|
||||
var getHuePositionFromHSB = function(hsb) {
|
||||
var y = 150 - (hsb.h / 2.4);
|
||||
if( y < 0 ) h = 0;
|
||||
if( y > 150 ) h = 150;
|
||||
return { y: y - 1 };
|
||||
};
|
||||
|
||||
var cleanHex = function(hex) {
|
||||
return hex.replace(/[^A-F0-9]/ig, '');
|
||||
};
|
||||
|
||||
var expandHex = function(hex) {
|
||||
hex = cleanHex(hex);
|
||||
if( !hex ) return null;
|
||||
if( hex.length === 3 ) hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2];
|
||||
return hex.length === 6 ? hex : null;
|
||||
};
|
||||
|
||||
var hsb2rgb = function(hsb) {
|
||||
var rgb = {};
|
||||
var h = Math.round(hsb.h);
|
||||
var s = Math.round(hsb.s*255/100);
|
||||
var v = Math.round(hsb.b*255/100);
|
||||
if(s === 0) {
|
||||
rgb.r = rgb.g = rgb.b = v;
|
||||
} else {
|
||||
var t1 = v;
|
||||
var t2 = (255 - s) * v / 255;
|
||||
var t3 = (t1 - t2) * (h % 60) / 60;
|
||||
if( h === 360 ) h = 0;
|
||||
if( h < 60 ) { rgb.r = t1; rgb.b = t2; rgb.g = t2 + t3; }
|
||||
else if( h < 120 ) {rgb.g = t1; rgb.b = t2; rgb.r = t1 - t3; }
|
||||
else if( h < 180 ) {rgb.g = t1; rgb.r = t2; rgb.b = t2 + t3; }
|
||||
else if( h < 240 ) {rgb.b = t1; rgb.r = t2; rgb.g = t1 - t3; }
|
||||
else if( h < 300 ) {rgb.b = t1; rgb.g = t2; rgb.r = t2 + t3; }
|
||||
else if( h < 360 ) {rgb.r = t1; rgb.g = t2; rgb.b = t1 - t3; }
|
||||
else { rgb.r = 0; rgb.g = 0; rgb.b = 0; }
|
||||
}
|
||||
return {
|
||||
r: Math.round(rgb.r),
|
||||
g: Math.round(rgb.g),
|
||||
b: Math.round(rgb.b)
|
||||
};
|
||||
};
|
||||
|
||||
var rgb2hex = function(rgb) {
|
||||
var hex = [
|
||||
rgb.r.toString(16),
|
||||
rgb.g.toString(16),
|
||||
rgb.b.toString(16)
|
||||
];
|
||||
$.each(hex, function(nr, val) {
|
||||
if (val.length === 1) hex[nr] = '0' + val;
|
||||
});
|
||||
return hex.join('');
|
||||
};
|
||||
|
||||
var hex2rgb = function(hex) {
|
||||
hex = parseInt(((hex.indexOf('#') > -1) ? hex.substring(1) : hex), 16);
|
||||
|
||||
return {
|
||||
r: hex >> 16,
|
||||
g: (hex & 0x00FF00) >> 8,
|
||||
b: (hex & 0x0000FF)
|
||||
};
|
||||
};
|
||||
|
||||
var rgb2hsb = function(rgb) {
|
||||
var hsb = { h: 0, s: 0, b: 0 };
|
||||
var min = Math.min(rgb.r, rgb.g, rgb.b);
|
||||
var max = Math.max(rgb.r, rgb.g, rgb.b);
|
||||
var delta = max - min;
|
||||
hsb.b = max;
|
||||
hsb.s = max !== 0 ? 255 * delta / max : 0;
|
||||
if( hsb.s !== 0 ) {
|
||||
if( rgb.r === max ) {
|
||||
hsb.h = (rgb.g - rgb.b) / delta;
|
||||
} else if( rgb.g === max ) {
|
||||
hsb.h = 2 + (rgb.b - rgb.r) / delta;
|
||||
} else {
|
||||
hsb.h = 4 + (rgb.r - rgb.g) / delta;
|
||||
}
|
||||
} else {
|
||||
hsb.h = -1;
|
||||
}
|
||||
hsb.h *= 60;
|
||||
if( hsb.h < 0 ) {
|
||||
hsb.h += 360;
|
||||
}
|
||||
hsb.s *= 100/255;
|
||||
hsb.b *= 100/255;
|
||||
return hsb;
|
||||
};
|
||||
|
||||
var hex2hsb = function(hex) {
|
||||
var hsb = rgb2hsb(hex2rgb(hex));
|
||||
// Zero out hue marker for black, white, and grays (saturation === 0)
|
||||
if( hsb.s === 0 ) hsb.h = 360;
|
||||
return hsb;
|
||||
};
|
||||
|
||||
var hsb2hex = function(hsb) {
|
||||
return rgb2hex(hsb2rgb(hsb));
|
||||
};
|
||||
|
||||
|
||||
// Handle calls to $([selector]).miniColors()
|
||||
switch(o) {
|
||||
|
||||
case 'readonly':
|
||||
|
||||
$(this).each( function() {
|
||||
if( !$(this).hasClass('miniColors') ) return;
|
||||
$(this).prop('readonly', data);
|
||||
});
|
||||
|
||||
return $(this);
|
||||
|
||||
case 'disabled':
|
||||
|
||||
$(this).each( function() {
|
||||
if( !$(this).hasClass('miniColors') ) return;
|
||||
if( data ) {
|
||||
disable($(this));
|
||||
} else {
|
||||
enable($(this));
|
||||
}
|
||||
});
|
||||
|
||||
return $(this);
|
||||
|
||||
case 'value':
|
||||
|
||||
// Getter
|
||||
if( data === undefined ) {
|
||||
if( !$(this).hasClass('miniColors') ) return;
|
||||
var input = $(this),
|
||||
hex = expandHex(input.val());
|
||||
return hex ? '#' + convertCase(hex, input.data('letterCase')) : null;
|
||||
}
|
||||
|
||||
// Setter
|
||||
$(this).each( function() {
|
||||
if( !$(this).hasClass('miniColors') ) return;
|
||||
$(this).val(data);
|
||||
setColorFromInput($(this));
|
||||
});
|
||||
|
||||
return $(this);
|
||||
|
||||
case 'destroy':
|
||||
|
||||
$(this).each( function() {
|
||||
if( !$(this).hasClass('miniColors') ) return;
|
||||
destroy($(this));
|
||||
});
|
||||
|
||||
return $(this);
|
||||
|
||||
default:
|
||||
|
||||
if( !o ) o = {};
|
||||
|
||||
$(this).each( function() {
|
||||
|
||||
// Must be called on an input element
|
||||
if( $(this)[0].tagName.toLowerCase() !== 'input' ) return;
|
||||
|
||||
// If a trigger is present, the control was already created
|
||||
if( $(this).data('trigger') ) return;
|
||||
|
||||
// Create the control
|
||||
create($(this), o, data);
|
||||
|
||||
});
|
||||
|
||||
return $(this);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
})(jQuery);
|
9
3rdparty/miniColors/js/jquery.miniColors.min.js
vendored
Executable file
9
3rdparty/miniColors/js/jquery.miniColors.min.js
vendored
Executable file
File diff suppressed because one or more lines are too long
18
apps/calendar/ajax/import/calendarcheck.php
Normal file
18
apps/calendar/ajax/import/calendarcheck.php
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
/**
|
||||
* Copyright (c) 2012 Georg Ehrke <ownclouddev at georgswebsite dot de>
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later.
|
||||
* See the COPYING-README file.
|
||||
*/
|
||||
OCP\JSON::checkLoggedIn();
|
||||
OCP\App::checkAppEnabled('calendar');
|
||||
$calname = strip_tags($_POST['calname']);
|
||||
$calendars = OC_Calendar_Calendar::allCalendars(OCP\User::getUser());
|
||||
foreach($calendars as $calendar){
|
||||
if($calendar['displayname'] == $calname){
|
||||
OCP\JSON::success(array('message'=>'exists'));
|
||||
exit;
|
||||
}
|
||||
}
|
||||
OCP\JSON::error();
|
|
@ -5,8 +5,6 @@
|
|||
* later.
|
||||
* See the COPYING-README file.
|
||||
*/
|
||||
|
||||
|
||||
OCP\JSON::checkLoggedIn();
|
||||
OCP\App::checkAppEnabled('calendar');
|
||||
$tmpl = new OCP\Template('calendar', 'part.import');
|
||||
|
|
|
@ -1,73 +1,32 @@
|
|||
<?php
|
||||
/**
|
||||
* Copyright (c) 2012 Georg Ehrke <ownclouddev@georgswebsite.de>
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later.
|
||||
* See the COPYING-README file.
|
||||
*/
|
||||
$data = $_POST['data'];
|
||||
$data = explode(',', $data);
|
||||
$data = end($data);
|
||||
$data = base64_decode($data);
|
||||
OCP\JSON::checkLoggedIn();
|
||||
OCP\App::checkAppEnabled('calendar');
|
||||
$nl="\r\n";
|
||||
$comps = array('VEVENT'=>true, 'VTODO'=>true, 'VJOURNAL'=>true);
|
||||
$data = str_replace(array("\r","\n\n"), array("\n","\n"), $data);
|
||||
$lines = explode("\n", $data);
|
||||
unset($data);
|
||||
$comp=$uid=$cal=false;
|
||||
$cals=$uids=array();
|
||||
$i = 0;
|
||||
foreach($lines as $line) {
|
||||
if(strpos($line, ':')!==false) {
|
||||
list($attr, $val) = explode(':', strtoupper($line));
|
||||
if ($attr == 'BEGIN' && $val == 'VCALENDAR') {
|
||||
$cal = $i;
|
||||
$cals[$cal] = array('first'=>$i,'last'=>$i,'end'=>$i);
|
||||
} elseif ($attr =='BEGIN' && $cal!==false && isset($comps[$val])) {
|
||||
$comp = $val;
|
||||
$beginNo = $i;
|
||||
} elseif ($attr == 'END' && $cal!==false && $val == 'VCALENDAR') {
|
||||
if($comp!==false) {
|
||||
unset($cals[$cal]); // corrupt calendar, unset it
|
||||
} else {
|
||||
$cals[$cal]['end'] = $i;
|
||||
}
|
||||
$comp=$uid=$cal=false; // reset calendar
|
||||
} elseif ($attr == 'END' && $comp!==false && $val == $comp) {
|
||||
if(! $uid) {
|
||||
$uid = OC_Calendar_Object::createUID();
|
||||
}
|
||||
$uids[$uid][$beginNo] = array('end'=>$i, 'cal'=>$cal);
|
||||
if ($cals[$cal]['first'] == $cal) {
|
||||
$cals[$cal]['first'] = $beginNo;
|
||||
}
|
||||
$cals[$cal]['last'] = $i;
|
||||
$comp=$uid=false; // reset component
|
||||
} elseif ($attr =="UID" && $comp!==false) {
|
||||
list($attr, $uid) = explode(':', $line);
|
||||
}
|
||||
}
|
||||
$i++;
|
||||
$import = new OC_Calendar_Import($data);
|
||||
$import->setUserID(OCP\User::getUser());
|
||||
$import->setTimeZone(OC_Calendar_App::$tz);
|
||||
$import->disableProgressCache();
|
||||
if(!$import->isValid()){
|
||||
OCP\JSON::error();
|
||||
exit;
|
||||
}
|
||||
$calendars = OC_Calendar_Calendar::allCalendars(OCP\USER::getUser(), true);
|
||||
$id = $calendars[0]['id'];
|
||||
foreach($uids as $uid) {
|
||||
$prefix=$suffix=$content=array();
|
||||
foreach($uid as $begin=>$details) {
|
||||
$cal = $details['cal'];
|
||||
if(!isset($cals[$cal])) {
|
||||
continue; // from corrupt/incomplete calendar
|
||||
}
|
||||
$cdata = $cals[$cal];
|
||||
// if we have multiple components from different calendar objects,
|
||||
// we should really merge their elements (enhancement?) -- 1st one wins for now.
|
||||
if(! count($prefix)) {
|
||||
$prefix = array_slice($lines, $cal, $cdata['first'] - $cal);
|
||||
}
|
||||
if(! count($suffix)) {
|
||||
$suffix = array_slice($lines, $cdata['last']+1, $cdata['end'] - $cdata['last']);
|
||||
}
|
||||
$content = array_merge($content, array_slice($lines, $begin, $details['end'] - $begin + 1));
|
||||
}
|
||||
if(count($content)) {
|
||||
$import = join($nl, array_merge($prefix, $content, $suffix)) . $nl;
|
||||
OC_Calendar_Object::add($id, $import);
|
||||
}
|
||||
}
|
||||
OCP\JSON::success();
|
||||
$newcalendarname = strip_tags($import->createCalendarName());
|
||||
$newid = OC_Calendar_Calendar::addCalendar(OCP\User::getUser(),$newcalendarname,'VEVENT,VTODO,VJOURNAL',null,0,$import->createCalendarColor());
|
||||
$import->setCalendarID($newid);
|
||||
$import->import();
|
||||
$count = $import->getCount();
|
||||
if($count == 0){
|
||||
OC_Calendar_Calendar::deleteCalendar($newid);
|
||||
OCP\JSON::error(array('message'=>OC_Calendar_App::$l10n->t('The file contained either no events or all events are already saved in your calendar.')));
|
||||
}else{
|
||||
OCP\JSON::success(array('message'=>$count . ' ' . OC_Calendar_App::$l10n->t('events has been saved in the new calendar') . ' ' . $newcalendarname, 'eventSource'=>OC_Calendar_Calendar::getEventSourceInfo(OC_Calendar_Calendar::find($newid))));
|
||||
}
|
|
@ -5,42 +5,71 @@
|
|||
* later.
|
||||
* See the COPYING-README file.
|
||||
*/
|
||||
//check for calendar rights or create new one
|
||||
ob_start();
|
||||
|
||||
OCP\JSON::checkLoggedIn();
|
||||
OCP\App::checkAppEnabled('calendar');
|
||||
OCP\JSON::callCheck();
|
||||
session_write_close();
|
||||
|
||||
$nl="\r\n";
|
||||
$comps = array('VEVENT'=>true, 'VTODO'=>true, 'VJOURNAL'=>true);
|
||||
|
||||
global $progresskey;
|
||||
$progresskey = 'calendar.import-' . $_POST['progresskey'];
|
||||
|
||||
if (isset($_POST['progress']) && $_POST['progress']) {
|
||||
echo OC_Cache::get($progresskey);
|
||||
die;
|
||||
if (isset($_POST['progresskey']) && isset($_POST['getprogress'])) {
|
||||
echo OCP\JSON::success(array('percent'=>OC_Cache::get($_POST['progresskey'])));
|
||||
exit;
|
||||
}
|
||||
|
||||
function writeProgress($pct) {
|
||||
global $progresskey;
|
||||
OC_Cache::set($progresskey, $pct, 300);
|
||||
}
|
||||
writeProgress('10');
|
||||
$file = OC_Filesystem::file_get_contents($_POST['path'] . '/' . $_POST['file']);
|
||||
if(!$file){
|
||||
OCP\JSON::error(array('error'=>'404'));
|
||||
}
|
||||
$import = new OC_Calendar_Import($file);
|
||||
$import->setUserID(OCP\User::getUser());
|
||||
$import->setTimeZone(OC_Calendar_App::$tz);
|
||||
$import->enableProgressCache();
|
||||
$import->setProgresskey($_POST['progresskey']);
|
||||
if(!$import->isValid()){
|
||||
OCP\JSON::error(array('error'=>'notvalid'));
|
||||
exit;
|
||||
}
|
||||
$newcal = false;
|
||||
if($_POST['method'] == 'new'){
|
||||
$id = OC_Calendar_Calendar::addCalendar(OCP\USER::getUser(), $_POST['calname']);
|
||||
OC_Calendar_Calendar::setCalendarActive($id, 1);
|
||||
$calendars = OC_Calendar_Calendar::allCalendars(OCP\User::getUser());
|
||||
foreach($calendars as $calendar){
|
||||
if($calendar['displayname'] == $_POST['calname']){
|
||||
$id = $calendar['id'];
|
||||
$newcal = false;
|
||||
break;
|
||||
}
|
||||
$newcal = true;
|
||||
}
|
||||
if($newcal){
|
||||
$id = OC_Calendar_Calendar::addCalendar(OCP\USER::getUser(), strip_tags($_POST['calname']),'VEVENT,VTODO,VJOURNAL',null,0,strip_tags($_POST['calcolor']));
|
||||
OC_Calendar_Calendar::setCalendarActive($id, 1);
|
||||
}
|
||||
}else{
|
||||
$calendar = OC_Calendar_App::getCalendar($_POST['id']);
|
||||
if($calendar['userid'] != OCP\USER::getUser()){
|
||||
OCP\JSON::error();
|
||||
OCP\JSON::error(array('error'=>'missingcalendarrights'));
|
||||
exit();
|
||||
}
|
||||
$id = $_POST['id'];
|
||||
}
|
||||
$import->setCalendarID($id);
|
||||
try{
|
||||
$import->import();
|
||||
}catch (Exception $e) {
|
||||
OCP\JSON::error(array('message'=>OC_Calendar_App::$l10n->t('Import failed'), 'debug'=>$e->getMessage()));
|
||||
//write some log
|
||||
}
|
||||
$count = $import->getCount();
|
||||
if($count == 0){
|
||||
if($newcal){
|
||||
OC_Calendar_Calendar::deleteCalendar($id);
|
||||
}
|
||||
OCP\JSON::error(array('message'=>OC_Calendar_App::$l10n->t('The file contained either no events or all events are already saved in your calendar.')));
|
||||
}else{
|
||||
if($newcal){
|
||||
OCP\JSON::success(array('message'=>$count . ' ' . OC_Calendar_App::$l10n->t('events has been saved in the new calendar') . ' ' . strip_tags($_POST['calname'])));
|
||||
}else{
|
||||
OCP\JSON::success(array('message'=>$count . ' ' . OC_Calendar_App::$l10n->t('events has been saved in your calendar')));
|
||||
}
|
||||
}
|
||||
/* //////////////////////////// Attention: following code is quite painfull !!! ///////////////////////
|
||||
writeProgress('20');
|
||||
// normalize the newlines
|
||||
$file = str_replace(array("\r","\n\n"), array("\n","\n"), $file);
|
||||
|
@ -92,7 +121,6 @@ foreach($lines as $line) {
|
|||
// import the calendar
|
||||
writeProgress('60');
|
||||
foreach($uids as $uid) {
|
||||
|
||||
$prefix=$suffix=$content=array();
|
||||
foreach($uid as $begin=>$details) {
|
||||
|
||||
|
@ -120,4 +148,4 @@ foreach($uids as $uid) {
|
|||
writeProgress('100');
|
||||
sleep(3);
|
||||
OC_Cache::remove($progresskey);
|
||||
OCP\JSON::success();
|
||||
OCP\JSON::success();*/
|
||||
|
|
|
@ -9,6 +9,7 @@ OC::$CLASSPATH['OC_Calendar_Repeat'] = 'apps/calendar/lib/repeat.php';
|
|||
OC::$CLASSPATH['OC_Calendar_Share'] = 'apps/calendar/lib/share.php';
|
||||
OC::$CLASSPATH['OC_Search_Provider_Calendar'] = 'apps/calendar/lib/search.php';
|
||||
OC::$CLASSPATH['OC_Calendar_Export'] = 'apps/calendar/lib/export.php';
|
||||
OC::$CLASSPATH['OC_Calendar_Import'] = 'apps/calendar/lib/import.php';
|
||||
//General Hooks
|
||||
OCP\Util::connectHook('OC_User', 'post_createUser', 'OC_Calendar_Hooks', 'createUser');
|
||||
OCP\Util::connectHook('OC_User', 'post_deleteUser', 'OC_Calendar_Hooks', 'deleteUser');
|
||||
|
@ -24,6 +25,8 @@ OCP\Util::connectHook('OC_Calendar', 'deleteCalendar', 'OC_Calendar_Share', 'pos
|
|||
OCP\Util::addscript('calendar','loader');
|
||||
OCP\Util::addscript("3rdparty", "chosen/chosen.jquery.min");
|
||||
OCP\Util::addStyle("3rdparty", "chosen/chosen");
|
||||
OCP\Util::addStyle('3rdparty/miniColors', 'jquery.miniColors');
|
||||
OCP\Util::addscript('3rdparty/miniColors', 'jquery.miniColors.min');
|
||||
OCP\App::addNavigationEntry( array(
|
||||
'id' => 'calendar_index',
|
||||
'order' => 10,
|
||||
|
|
14
apps/calendar/css/import.css
vendored
Normal file
14
apps/calendar/css/import.css
vendored
Normal file
|
@ -0,0 +1,14 @@
|
|||
/**
|
||||
* Copyright (c) 2012 Georg Ehrke <ownclouddev at georgswebsite dot de>
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later.
|
||||
* See the COPYING-README file.
|
||||
*/
|
||||
#calendar_import_newcalform, #calendar_import_mergewarning, #calendar_import_process, #calendar_import_done{display:none;}
|
||||
#calendar_import_process_message, #calendar_import_status, #calendar_import_form_message, #calendar_import_mergewarning{text-align:center;}
|
||||
#calendar_import_form_message{font-weight: bold;}
|
||||
#calendar_import_newcalendar{width:415px;float:right;}
|
||||
#calendar_import_mergewarning{clear: both;}
|
||||
#calendar_import_defaultcolors{clear:both;margin: 0 auto;text-align: center;}
|
||||
.calendar_import_warning{border-color: #fc3333;}
|
||||
.calendar-colorpicker-color{display:inline-block;width:20px;height:5px;margin: 0 auto;cursor:pointer;border:2px solid transparent;}
|
|
@ -622,18 +622,11 @@ Calendar={
|
|||
drop:function(e){
|
||||
var files = e.dataTransfer.files;
|
||||
for(var i = 0;i < files.length;i++){
|
||||
var file = files[i]
|
||||
var file = files[i];
|
||||
reader = new FileReader();
|
||||
reader.onload = function(event){
|
||||
if(file.type != 'text/calendar'){
|
||||
$('#notification').html('At least one file don\'t seems to be a calendar file. File skipped.');
|
||||
$('#notification').slideDown();
|
||||
window.setTimeout(function(){$('#notification').slideUp();}, 5000);
|
||||
return false;
|
||||
}else{
|
||||
Calendar.UI.Drop.import(event.target.result);
|
||||
$('#calendar_holder').fullCalendar('refetchEvents');
|
||||
}
|
||||
Calendar.UI.Drop.import(event.target.result);
|
||||
$('#calendar_holder').fullCalendar('refetchEvents');
|
||||
}
|
||||
reader.readAsDataURL(file);
|
||||
}
|
||||
|
@ -641,9 +634,13 @@ Calendar={
|
|||
import:function(data){
|
||||
$.post(OC.filePath('calendar', 'ajax/import', 'dropimport.php'), {'data':data},function(result) {
|
||||
if(result.status == 'success'){
|
||||
$('#calendar_holder').fullCalendar('addEventSource', result.eventSource);
|
||||
$('#notification').html(result.message);
|
||||
$('#notification').slideDown();
|
||||
window.setTimeout(function(){$('#notification').slideUp();}, 5000);
|
||||
return true;
|
||||
}else{
|
||||
$('#notification').html('ownCloud wasn\'t able to import at least one file. File skipped.');
|
||||
$('#notification').html(result.message);
|
||||
$('#notification').slideDown();
|
||||
window.setTimeout(function(){$('#notification').slideUp();}, 5000);
|
||||
}
|
||||
|
|
|
@ -5,77 +5,175 @@
|
|||
* See the COPYING-README file.
|
||||
*/
|
||||
Calendar_Import={
|
||||
importdialog: function(filename){
|
||||
var path = $('#dir').val();
|
||||
$('body').append('<div id="calendar_import"></div>');
|
||||
$('#calendar_import').load(OC.filePath('calendar', 'ajax/import', 'dialog.php'), {filename:filename, path:path}, function(){Calendar_Import.initdialog(filename);});
|
||||
Store:{
|
||||
file: '',
|
||||
path: '',
|
||||
id: 0,
|
||||
method: '',
|
||||
calname: '',
|
||||
calcolor: '',
|
||||
progresskey: '',
|
||||
percentage: 0
|
||||
},
|
||||
initdialog: function(filename){
|
||||
$('#calendar_import_dialog').dialog({
|
||||
width : 500,
|
||||
close : function() {
|
||||
$(this).dialog('destroy').remove();
|
||||
$('#calendar_import').remove();
|
||||
}
|
||||
});
|
||||
$('#import_done_button').click(function(){
|
||||
$('#calendar_import_dialog').dialog('destroy').remove();
|
||||
$('#calendar_import').remove();
|
||||
});
|
||||
$('#progressbar').progressbar({value: 0});
|
||||
$('#startimport').click(function(){
|
||||
var filename = $('#filename').val();
|
||||
var path = $('#path').val();
|
||||
var calid = $('#calendar option:selected').val();
|
||||
if($('#calendar option:selected').val() == 'newcal'){
|
||||
var method = 'new';
|
||||
var calname = $('#newcalendar').val();
|
||||
var calname = $.trim(calname);
|
||||
if(calname == ''){
|
||||
$('#newcalendar').css('background-color', '#FF2626');
|
||||
$('#newcalendar').focus(function(){
|
||||
$('#newcalendar').css('background-color', '#F8F8F8');
|
||||
});
|
||||
return false;
|
||||
}
|
||||
}else{
|
||||
var method = 'old';
|
||||
}
|
||||
$('#newcalendar').attr('readonly', 'readonly');
|
||||
$('#calendar').attr('disabled', 'disabled');
|
||||
var progresskey = $('#progresskey').val();
|
||||
$.post(OC.filePath('calendar', 'ajax/import', 'import.php'), {progresskey: progresskey, method: String (method), calname: String (calname), path: String (path), file: String (filename), id: String (calid)}, function(data){
|
||||
if(data.status == 'success'){
|
||||
$('#progressbar').progressbar('option', 'value', 100);
|
||||
$('#import_done').css('display', 'block');
|
||||
Dialog:{
|
||||
open: function(filename){
|
||||
OC.addStyle('calendar', 'import');
|
||||
Calendar_Import.Store.file = filename;
|
||||
Calendar_Import.Store.path = $('#dir').val();
|
||||
$('body').append('<div id="calendar_import"></div>');
|
||||
$('#calendar_import').load(OC.filePath('calendar', 'ajax/import', 'dialog.php'), {filename:Calendar_Import.Store.file, path:Calendar_Import.Store.path},function(){
|
||||
Calendar_Import.Dialog.init();
|
||||
});
|
||||
},
|
||||
close: function(){
|
||||
Calendar_Import.reset();
|
||||
$(this).dialog('destroy').remove();
|
||||
$('#calendar_import_dialog').remove();
|
||||
},
|
||||
init: function(){
|
||||
//init dialog
|
||||
$('#calendar_import_dialog').dialog({
|
||||
width : 500,
|
||||
resizable: false,
|
||||
close : function() {
|
||||
Calendar_Import.Dialog.close();
|
||||
}
|
||||
});
|
||||
$('#form_container').css('display', 'none');
|
||||
$('#progressbar_container').css('display', 'block');
|
||||
window.setTimeout('Calendar_Import.getimportstatus(\'' + progresskey + '\')', 500);
|
||||
});
|
||||
$('#calendar').change(function(){
|
||||
if($('#calendar option:selected').val() == 'newcal'){
|
||||
$('#newcalform').slideDown('slow');
|
||||
}else{
|
||||
$('#newcalform').slideUp('slow');
|
||||
//init buttons
|
||||
$('#calendar_import_done').click(function(){
|
||||
Calendar_Import.Dialog.close();
|
||||
});
|
||||
$('#calendar_import_submit').click(function(){
|
||||
Calendar_Import.Core.process();
|
||||
});
|
||||
$('#calendar_import_mergewarning').click(function(){
|
||||
$('#calendar_import_newcalendar').attr('value', $('#calendar_import_availablename').val());
|
||||
Calendar_Import.Dialog.mergewarning($('#calendar_import_newcalendar').val());
|
||||
});
|
||||
$('#calendar_import_calendar').change(function(){
|
||||
if($('#calendar_import_calendar option:selected').val() == 'newcal'){
|
||||
$('#calendar_import_newcalform').slideDown('slow');
|
||||
Calendar_Import.Dialog.mergewarning($('#calendar_import_newcalendar').val());
|
||||
}else{
|
||||
$('#calendar_import_newcalform').slideUp('slow');
|
||||
$('#calendar_import_mergewarning').slideUp('slow');
|
||||
}
|
||||
});
|
||||
$('#calendar_import_newcalendar').keyup(function(){
|
||||
Calendar_Import.Dialog.mergewarning($.trim($('#calendar_import_newcalendar').val()));
|
||||
});
|
||||
$('#calendar_import_newcalendar_color').miniColors({
|
||||
letterCase: 'uppercase'
|
||||
});
|
||||
$('.calendar-colorpicker-color').click(function(){
|
||||
var str = $(this).attr('rel');
|
||||
str = str.substr(1);
|
||||
$('#calendar_import_newcalendar_color').attr('value', str);
|
||||
$(".color-picker").miniColors('value', '#' + str);
|
||||
});
|
||||
//init progressbar
|
||||
$('#calendar_import_progressbar').progressbar({value: Calendar_Import.Store.percentage});
|
||||
Calendar_Import.Store.progresskey = $('#calendar_import_progresskey').val();
|
||||
},
|
||||
mergewarning: function(newcalname){
|
||||
$.post(OC.filePath('calendar', 'ajax/import', 'calendarcheck.php'), {calname: newcalname}, function(data){
|
||||
if(data.message == 'exists'){
|
||||
$('#calendar_import_mergewarning').slideDown('slow');
|
||||
}else{
|
||||
$('#calendar_import_mergewarning').slideUp('slow');
|
||||
}
|
||||
});
|
||||
},
|
||||
update: function(){
|
||||
if(Calendar_Import.Store.percentage == 100){
|
||||
return false;
|
||||
}
|
||||
});
|
||||
$.post(OC.filePath('calendar', 'ajax/import', 'import.php'), {progresskey: Calendar_Import.Store.progresskey, getprogress: true}, function(data){
|
||||
if(data.status == 'success'){
|
||||
if(data.percent == null){
|
||||
return false;
|
||||
}
|
||||
Calendar_Import.Store.percentage = parseInt(data.percent);
|
||||
$('#calendar_import_progressbar').progressbar('option', 'value', parseInt(data.percent));
|
||||
if(data.percent < 100 ){
|
||||
window.setTimeout('Calendar_Import.Dialog.update()', 250);
|
||||
}else{
|
||||
$('#calendar_import_done').css('display', 'block');
|
||||
}
|
||||
}else{
|
||||
$('#calendar_import_progressbar').progressbar('option', 'value', 100);
|
||||
$('#calendar_import_progressbar > div').css('background-color', '#FF2626');
|
||||
$('#calendar_import_status').html(data.message);
|
||||
}
|
||||
});
|
||||
return 0;
|
||||
},
|
||||
warning: function(selector){
|
||||
$(selector).addClass('calendar_import_warning');
|
||||
$(selector).focus(function(){
|
||||
$(selector).removeClass('calendar_import_warning');
|
||||
});
|
||||
}
|
||||
},
|
||||
getimportstatus: function(progresskey){
|
||||
$.post(OC.filePath('calendar', 'ajax/import', 'import.php'), {progress:1,progresskey: progresskey}, function(percent){
|
||||
$('#progressbar').progressbar('option', 'value', parseInt(percent));
|
||||
if(percent < 100){
|
||||
window.setTimeout('Calendar_Import.getimportstatus(\'' + progresskey + '\')', 500);
|
||||
}else{
|
||||
$('#import_done').css('display', 'block');
|
||||
Core:{
|
||||
process: function(){
|
||||
var validation = Calendar_Import.Core.prepare();
|
||||
if(validation){
|
||||
$('#calendar_import_form').css('display', 'none');
|
||||
$('#calendar_import_process').css('display', 'block');
|
||||
$('#calendar_import_newcalendar').attr('readonly', 'readonly');
|
||||
$('#calendar_import_calendar').attr('disabled', 'disabled');
|
||||
Calendar_Import.Core.send();
|
||||
window.setTimeout('Calendar_Import.Dialog.update()', 250);
|
||||
}
|
||||
});
|
||||
},
|
||||
send: function(){
|
||||
$.post(OC.filePath('calendar', 'ajax/import', 'import.php'),
|
||||
{progresskey: Calendar_Import.Store.progresskey, method: String (Calendar_Import.Store.method), calname: String (Calendar_Import.Store.calname), path: String (Calendar_Import.Store.path), file: String (Calendar_Import.Store.file), id: String (Calendar_Import.Store.id), calcolor: String (Calendar_Import.Store.calcolor)}, function(data){
|
||||
if(data.status == 'success'){
|
||||
$('#calendar_import_progressbar').progressbar('option', 'value', 100);
|
||||
Calendar_Import.Store.percentage = 100;
|
||||
$('#calendar_import_done').css('display', 'block');
|
||||
$('#calendar_import_status').html(data.message);
|
||||
}else{
|
||||
$('#calendar_import_progressbar').progressbar('option', 'value', 100);
|
||||
$('#calendar_import_progressbar > div').css('background-color', '#FF2626');
|
||||
$('#calendar_import_status').html(data.message);
|
||||
}
|
||||
});
|
||||
},
|
||||
prepare: function(){
|
||||
Calendar_Import.Store.id = $('#calendar_import_calendar option:selected').val();
|
||||
if($('#calendar_import_calendar option:selected').val() == 'newcal'){
|
||||
Calendar_Import.Store.method = 'new';
|
||||
Calendar_Import.Store.calname = $.trim($('#calendar_import_newcalendar').val());
|
||||
if(Calendar_Import.Store.calname == ''){
|
||||
Calendar_Import.Dialog.warning('#calendar_import_newcalendar');
|
||||
return false;
|
||||
}
|
||||
Calendar_Import.Store.calcolor = $.trim($('#calendar_import_newcalendar_color').val());
|
||||
if(Calendar_Import.Store.calcolor == ''){
|
||||
Calendar_Import.Store.calcolor = $('.calendar-colorpicker-color:first').attr('rel');
|
||||
}
|
||||
}else{
|
||||
Calendar_Import.Store.method = 'old';
|
||||
}
|
||||
return true;
|
||||
}
|
||||
},
|
||||
reset: function(){
|
||||
Calendar_Import.Store.file = '';
|
||||
Calendar_Import.Store.path = '';
|
||||
Calendar_Import.Store.id = 0;
|
||||
Calendar_Import.Store.method = '';
|
||||
Calendar_Import.Store.calname = '';
|
||||
Calendar_Import.Store.progresskey = '';
|
||||
Calendar_Import.Store.percentage = 0;
|
||||
}
|
||||
}
|
||||
$(document).ready(function(){
|
||||
if(typeof FileActions !== 'undefined'){
|
||||
FileActions.register('text/calendar','importcal', '', Calendar_Import.importdialog);
|
||||
FileActions.setDefault('text/calendar','importcal');
|
||||
FileActions.register('text/calendar','importCalendar', '', Calendar_Import.Dialog.open);
|
||||
FileActions.setDefault('text/calendar','importCalendar');
|
||||
};
|
||||
});
|
||||
|
|
|
@ -34,6 +34,7 @@ $(document).ready(function(){
|
|||
$.getJSON(OC.filePath('calendar', 'ajax/settings', 'timeformat.php'), function(jsondata, status) {
|
||||
$('#' + jsondata.timeformat).attr('selected',true);
|
||||
$('#timeformat').chosen();
|
||||
$('#timeformat_chzn').css('width', '100px');
|
||||
});
|
||||
$.getJSON(OC.filePath('calendar', 'ajax/settings', 'gettimezonedetection.php'), function(jsondata, status){
|
||||
if(jsondata.detection == 'true'){
|
||||
|
@ -43,6 +44,7 @@ $(document).ready(function(){
|
|||
$.getJSON(OC.filePath('calendar', 'ajax/settings', 'getfirstday.php'), function(jsondata, status) {
|
||||
$('#' + jsondata.firstday).attr('selected',true);
|
||||
$('#firstday').chosen();
|
||||
$('#firstday_chzn').css('width', '100px');
|
||||
});
|
||||
$('#cleancalendarcache').click(function(){
|
||||
$.getJSON(OC.filePath('calendar', 'ajax/cache', 'rescan.php'), function(){
|
||||
|
@ -55,7 +57,7 @@ function calendarcachecheck(){
|
|||
$.getJSON(OC.filePath('calendar', 'ajax/cache', 'status.php'), function(jsondata, status) {
|
||||
$('#cleancalendarcache').attr('title', jsondata.l10n.text);
|
||||
if(jsondata.status == 'success'){
|
||||
$('#cleancalendarcache').css('background', '#90EE90');
|
||||
$('#cleancalendarcache').css('background', '#F8F8F8');
|
||||
$('#cleancalendarcache').css('color', '#333');
|
||||
$('#cleancalendarcache').css('text-shadow', '#fff 0 1px 0');
|
||||
}else{
|
||||
|
|
|
@ -267,8 +267,42 @@ class OC_Calendar_Calendar{
|
|||
'url' => OCP\Util::linkTo('calendar', 'ajax/events.php').'?calendar_id='.$calendar['id'],
|
||||
'backgroundColor' => $calendar['calendarcolor'],
|
||||
'borderColor' => '#888',
|
||||
'textColor' => 'black',
|
||||
'textColor' => self::generateTextColor($calendar['calendarcolor']),
|
||||
'cache' => true,
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief checks if a calendar name is available for a user
|
||||
* @param string $calendarname
|
||||
* @param string $userid
|
||||
* @return boolean
|
||||
*/
|
||||
public static function isCalendarNameavailable($calendarname, $userid){
|
||||
$calendars = self::allCalendars($userid);
|
||||
foreach($calendars as $calendar){
|
||||
if($calendar['displayname'] == $calendarname){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief generates the text color for the calendar
|
||||
* @param string $calendarcolor rgb calendar color code in hex format (with or without the leading #)
|
||||
* (this function doesn't pay attention on the alpha value of rgba color codes)
|
||||
* @return boolean
|
||||
*/
|
||||
public static function generateTextColor($calendarcolor){
|
||||
if(substr_count($calendarcolor, '#') == 1){
|
||||
$calendarcolor = substr($calendarcolor,1);
|
||||
}
|
||||
$red = hexdec(substr($calendarcolor,0,2));
|
||||
$green = hexdec(substr($calendarcolor,2,2));
|
||||
$blue = hexdec(substr($calendarcolor,2,2));
|
||||
//recommendation by W3C
|
||||
$computation = ((($red * 299) + ($green * 587) + ($blue * 114)) / 1000);
|
||||
return ($computation > 130)?'#000000':'#FAFAFA';
|
||||
}
|
||||
}
|
||||
|
|
334
apps/calendar/lib/import.php
Normal file
334
apps/calendar/lib/import.php
Normal file
|
@ -0,0 +1,334 @@
|
|||
<?php
|
||||
/**
|
||||
* Copyright (c) 2012 Georg Ehrke <ownclouddev@georgswebsite.de>
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later.
|
||||
* See the COPYING-README file.
|
||||
*/
|
||||
/*
|
||||
* This class does import and converts all times to the users current timezone
|
||||
*/
|
||||
class OC_Calendar_Import{
|
||||
/*
|
||||
* @brief counts the absolute number of parsed elements
|
||||
*/
|
||||
private $abscount;
|
||||
|
||||
/*
|
||||
* @brief var saves if the percentage should be saved with OC_Cache
|
||||
*/
|
||||
private $cacheprogress;
|
||||
|
||||
/*
|
||||
* @brief Sabre_VObject_Component_VCalendar object - for documentation see http://code.google.com/p/sabredav/wiki/Sabre_VObject_Component_VCalendar
|
||||
*/
|
||||
private $calobject;
|
||||
|
||||
/*
|
||||
* @brief var counts the number of imported elements
|
||||
*/
|
||||
private $count;
|
||||
|
||||
/*
|
||||
* @brief var to check if errors happend while initialization
|
||||
*/
|
||||
private $error;
|
||||
|
||||
/*
|
||||
* @brief var saves the ical string that was submitted with the __construct function
|
||||
*/
|
||||
private $ical;
|
||||
|
||||
/*
|
||||
* @brief calendar id for import
|
||||
*/
|
||||
private $id;
|
||||
|
||||
/*
|
||||
* @brief var saves the percentage of the import's progress
|
||||
*/
|
||||
private $progress;
|
||||
|
||||
/*
|
||||
* @brief var saves the key for the percentage of the import's progress
|
||||
*/
|
||||
private $progresskey;
|
||||
|
||||
/*
|
||||
* @brief var saves the timezone the events shell converted to
|
||||
*/
|
||||
private $tz;
|
||||
|
||||
/*
|
||||
* @brief var saves the userid
|
||||
*/
|
||||
private $userid;
|
||||
|
||||
/*
|
||||
* public methods
|
||||
*/
|
||||
|
||||
/*
|
||||
* @brief does general initialization for import object
|
||||
* @param string $calendar content of ical file
|
||||
* @param string $tz timezone of the user
|
||||
* @return boolean
|
||||
*/
|
||||
public function __construct($ical){
|
||||
$this->error = null;
|
||||
$this->ical = $ical;
|
||||
$this->abscount = 0;
|
||||
$this->count = 0;
|
||||
try{
|
||||
$this->calobject = OC_VObject::parse($this->ical);
|
||||
}catch(Exception $e){
|
||||
//MISSING: write some log
|
||||
$this->error = true;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief imports a calendar
|
||||
* @return boolean
|
||||
*/
|
||||
public function import(){
|
||||
if(!$this->isValid()){
|
||||
return false;
|
||||
}
|
||||
$numofcomponents = count($this->calobject->getComponents());
|
||||
foreach($this->calobject->getComponents() as $object){
|
||||
if(!($object instanceof Sabre_VObject_Component_VEvent) && !($object instanceof Sabre_VObject_Component_VJournal) && !($object instanceof Sabre_VObject_Component_VTodo)){
|
||||
continue;
|
||||
}
|
||||
$dtend = OC_Calendar_Object::getDTEndFromVEvent($object);
|
||||
$object->DTSTART->getDateTime()->setTimezone(new DateTimeZone($this->tz));
|
||||
$object->DTEND->setDateTime($dtend->getDateTime(), $object->DTSTART->getDateType());
|
||||
$object->DTEND->getDateTime()->setTimezone(new DateTimeZone($this->tz));
|
||||
$vcalendar = $this->createVCalendar($object->serialize());
|
||||
$insertid = OC_Calendar_Object::add($this->id, $vcalendar);
|
||||
$this->abscount++;
|
||||
if($this->isDuplicate($insertid)){
|
||||
OC_Calendar_Object::delete($insertid);
|
||||
}else{
|
||||
$this->count++;
|
||||
}
|
||||
$this->updateProgress(intval(($this->abscount / $numofcomponents)*100));
|
||||
}
|
||||
OC_Cache::remove($this->progresskey);
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief sets the timezone
|
||||
* @return boolean
|
||||
*/
|
||||
public function setTimeZone($tz){
|
||||
$this->tz = $tz;
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief sets the progresskey
|
||||
* @return boolean
|
||||
*/
|
||||
public function setProgresskey($progresskey){
|
||||
$this->progresskey = $progresskey;
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief checks if something went wrong while initialization
|
||||
* @return boolean
|
||||
*/
|
||||
public function isValid(){
|
||||
if(is_null($this->error)){
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief returns the percentage of progress
|
||||
* @return integer
|
||||
*/
|
||||
public function getProgress(){
|
||||
return $this->progress;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief enables the cache for the percentage of progress
|
||||
* @return boolean
|
||||
*/
|
||||
public function enableProgressCache(){
|
||||
$this->cacheprogress = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief disables the cache for the percentage of progress
|
||||
* @return boolean
|
||||
*/
|
||||
public function disableProgressCache(){
|
||||
$this->cacheprogress = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief generates a new calendar name
|
||||
* @return string
|
||||
*/
|
||||
public function createCalendarName(){
|
||||
$calendars = OC_Calendar_Calendar::allCalendars($this->userid);
|
||||
$calendarname = $guessedcalendarname = !is_null($this->guessCalendarName())?($this->guessCalendarName()):(OC_Calendar_App::$l10n->t('New Calendar'));
|
||||
$i = 1;
|
||||
while(!OC_Calendar_Calendar::isCalendarNameavailable($calendarname, $this->userid)){
|
||||
$calendarname = $guessedcalendarname . ' (' . $i . ')';
|
||||
$i++;
|
||||
}
|
||||
return $calendarname;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief generates a new calendar color
|
||||
* @return string
|
||||
*/
|
||||
public function createCalendarColor(){
|
||||
if(is_null($this->guessCalendarColor())){
|
||||
return '#9fc6e7';
|
||||
}
|
||||
return $this->guessCalendarColor();
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief sets the id for the calendar
|
||||
* @param integer $id of the calendar
|
||||
* @return boolean
|
||||
*/
|
||||
public function setCalendarID($id){
|
||||
$this->id = $id;
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief sets the userid to import the calendar
|
||||
* @param string $id of the user
|
||||
* @return boolean
|
||||
*/
|
||||
public function setUserID($userid){
|
||||
$this->userid = $userid;
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief returns the private
|
||||
* @param string $id of the user
|
||||
* @return boolean
|
||||
*/
|
||||
public function getCount(){
|
||||
return $this->count;
|
||||
}
|
||||
|
||||
/*
|
||||
* private methods
|
||||
*/
|
||||
|
||||
/*
|
||||
* @brief generates an unique ID
|
||||
* @return string
|
||||
*/
|
||||
//private function createUID(){
|
||||
// return substr(md5(rand().time()),0,10);
|
||||
//}
|
||||
|
||||
/*
|
||||
* @brief checks is the UID is already in use for another event
|
||||
* @param string $uid uid to check
|
||||
* @return boolean
|
||||
*/
|
||||
//private function isUIDAvailable($uid){
|
||||
//
|
||||
//}
|
||||
|
||||
/*
|
||||
* @brief generates a proper VCalendar string
|
||||
* @param string $vobject
|
||||
* @return string
|
||||
*/
|
||||
private function createVCalendar($vobject){
|
||||
if(is_object($vobject)){
|
||||
$vobject = @$vobject->serialize();
|
||||
}
|
||||
$vcalendar = "BEGIN:VCALENDAR\nVERSION:2.0\nPRODID:ownCloud Calendar " . OCP\App::getAppVersion('calendar') . "\n";
|
||||
$vcalendar .= $vobject;
|
||||
$vcalendar .= "END:VCALENDAR";
|
||||
return $vcalendar;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief checks if an event already exists in the user's calendars
|
||||
* @param integer $insertid id of the new object
|
||||
* @return boolean
|
||||
*/
|
||||
private function isDuplicate($insertid){
|
||||
$newobject = OC_Calendar_Object::find($insertid);
|
||||
$stmt = OCP\DB::prepare('SELECT COUNT(*) as count FROM *PREFIX*calendar_objects WHERE objecttype=? AND startdate=? AND enddate=? AND repeating=? AND summary=? AND calendardata=?');
|
||||
$result = $stmt->execute(array($newobject['objecttype'],$newobject['startdate'],$newobject['enddate'],$newobject['repeating'],$newobject['summary'],$newobject['calendardata']));
|
||||
$result = $result->fetchRow();
|
||||
if($result['count'] >= 2){
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief updates the progress var
|
||||
* @param integer $percentage
|
||||
* @return boolean
|
||||
*/
|
||||
private function updateProgress($percentage){
|
||||
$this->progress = $percentage;
|
||||
if($this->cacheprogress){
|
||||
OC_Cache::set($this->progresskey, $this->progress, 300);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* public methods for (pre)rendering of X-... Attributes
|
||||
*/
|
||||
|
||||
/*
|
||||
* @brief guesses the calendar color
|
||||
* @return mixed - string or boolean
|
||||
*/
|
||||
public function guessCalendarColor(){
|
||||
if(!is_null($this->calobject->__get('X-APPLE-CALENDAR-COLOR'))){
|
||||
return $this->calobject->__get('X-APPLE-CALENDAR-COLOR');
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief guesses the calendar description
|
||||
* @return mixed - string or boolean
|
||||
*/
|
||||
public function guessCalendarDescription(){
|
||||
if(!is_null($this->calobject->__get('X-WR-CALDESC'))){
|
||||
return $this->calobject->__get('X-WR-CALDESC');
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief guesses the calendar name
|
||||
* @return mixed - string or boolean
|
||||
*/
|
||||
public function guessCalendarName(){
|
||||
if(!is_null($this->calobject->__get('X-WR-CALNAME'))){
|
||||
return $this->calobject->__get('X-WR-CALNAME');
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -1,30 +1,58 @@
|
|||
<div id="calendar_import_dialog" title="<?php echo $l->t("Import a calendar file"); ?>">
|
||||
<div id="form_container">
|
||||
<input type="hidden" id="filename" value="<?php echo $_['filename'];?>">
|
||||
<input type="hidden" id="path" value="<?php echo $_['path'];?>">
|
||||
<input type="hidden" id="progresskey" value="<?php echo rand() ?>">
|
||||
<p style="text-align:center;"><b><?php echo $l->t('Please choose the calendar'); ?></b></p>
|
||||
<select style="width:100%;" id="calendar" name="calendar">
|
||||
<?php
|
||||
//Prerendering for iCalendar file
|
||||
$file = OC_Filesystem::file_get_contents($_['path'] . '/' . $_['filename']);
|
||||
if(!$file){
|
||||
OCP\JSON::error(array('error'=>'404'));
|
||||
}
|
||||
$import = new OC_Calendar_Import($file);
|
||||
$import->setUserID(OCP\User::getUser());
|
||||
$newcalendarname = strip_tags($import->createCalendarName());
|
||||
$guessedcalendarname = strip_tags($import->guessCalendarName());
|
||||
$calendarcolor = strip_tags($import->createCalendarColor());
|
||||
//loading calendars for select box
|
||||
$calendar_options = OC_Calendar_Calendar::allCalendars(OCP\USER::getUser());
|
||||
$calendar_options[] = array('id'=>'newcal', 'displayname'=>$l->t('create a new calendar'));
|
||||
for($i = 0;$i<count($calendar_options);$i++){
|
||||
$calendar_options[$i]['displayname'] = $calendar_options[$i]['displayname'];
|
||||
}
|
||||
echo OCP\html_select_options($calendar_options, $calendar_options[0]['id'], array('value'=>'id', 'label'=>'displayname'));
|
||||
$defaultcolors = OC_Calendar_Calendar::getCalendarColorOptions();
|
||||
?>
|
||||
</select>
|
||||
<div id="newcalform" style="display: none;">
|
||||
<input type="text" style="width: 97%;" placeholder="<?php echo $l->t('Name of new calendar'); ?>" id="newcalendar" name="newcalendar">
|
||||
</div>
|
||||
<input type="button" value="<?php echo $l->t("Import");?>!" id="startimport">
|
||||
</div>
|
||||
<div id="progressbar_container" style="display: none">
|
||||
<p style="text-align:center;"><b><?php echo $l->t('Importing calendar'); ?></b></p>
|
||||
<div id="progressbar"></div>
|
||||
<div id="import_done" style="display: none;">
|
||||
<p style="text-align:center;"><b><?php echo $l->t('Calendar imported successfully'); ?></b></p>
|
||||
<input type="button" value="<?php echo $l->t('Close Dialog'); ?>" id="import_done_button">
|
||||
<div id="calendar_import_dialog" title="<?php echo $l->t("Import a calendar file");?>">
|
||||
<div id="calendar_import_form">
|
||||
<form>
|
||||
<input type="hidden" id="calendar_import_filename" value="<?php echo $_['filename'];?>">
|
||||
<input type="hidden" id="calendar_import_path" value="<?php echo $_['path'];?>">
|
||||
<input type="hidden" id="calendar_import_progresskey" value="<?php echo rand() ?>">
|
||||
<input type="hidden" id="calendar_import_availablename" value="<?php echo $newcalendarname ?>">
|
||||
<div id="calendar_import_form_message"><?php echo $l->t('Please choose a calendar'); ?></div>
|
||||
<select style="width:100%;" id="calendar_import_calendar" name="calendar_import_calendar">
|
||||
<?php
|
||||
for($i = 0;$i<count($calendar_options);$i++){
|
||||
$calendar_options[$i]['displayname'] = $calendar_options[$i]['displayname'];
|
||||
}
|
||||
echo OCP\html_select_options($calendar_options, $calendar_options[0]['id'], array('value'=>'id', 'label'=>'displayname'));
|
||||
?>
|
||||
</select>
|
||||
<br><br>
|
||||
<div id="calendar_import_newcalform">
|
||||
<input id="calendar_import_newcalendar_color" class="color-picker" type="hidden" size="6" value="<?php echo substr($calendarcolor,1); ?>">
|
||||
<input id="calendar_import_newcalendar" class="" type="text" placeholder="<?php echo $l->t('Name of new calendar'); ?>" value="<?php echo $guessedcalendarname ?>"><br>
|
||||
<div id="calendar_import_defaultcolors">
|
||||
<?php
|
||||
foreach($defaultcolors as $color){
|
||||
echo '<span class="calendar-colorpicker-color" rel="' . $color . '" style="background-color: ' . $color . ';"></span>';
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
<!--<input id="calendar_import_generatename" type="button" class="button" value="<?php echo $l->t('Take an available name!'); ?>"><br>-->
|
||||
<div id="calendar_import_mergewarning" class="hint"><?php echo $l->t('A Calendar with this name already exists. If you continue anyhow, these calendars will be merged.'); ?></div>
|
||||
</div>
|
||||
<input id="calendar_import_submit" type="button" class="button" value="» <?php echo $l->t('Import'); ?> »" id="startimport">
|
||||
<form>
|
||||
</div>
|
||||
<div id="calendar_import_process">
|
||||
<div id="calendar_import_process_message"></div>
|
||||
<div id="calendar_import_progressbar"></div>
|
||||
<br>
|
||||
<div id="calendar_import_status" class="hint"></div>
|
||||
<br>
|
||||
<input id="calendar_import_done" type="button" value="<?php echo $l->t('Close Dialog'); ?>">
|
||||
</div>
|
||||
</div>
|
|
@ -1,46 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* ownCloud - Addressbook
|
||||
*
|
||||
* @author Thomas Tanghus
|
||||
* @copyright 2012 Thomas Tanghus <thomas@tanghus.net>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
// Check if we are a user
|
||||
OCP\JSON::checkLoggedIn();
|
||||
OCP\JSON::checkAppEnabled('contacts');
|
||||
|
||||
require_once 'loghandler.php';
|
||||
|
||||
$id = isset($_GET['id']) ? $_GET['id'] : '';
|
||||
$refresh = isset($_GET['refresh']) ? true : false;
|
||||
|
||||
if($id == '') {
|
||||
bailOut(OC_Contacts_App::$l10n->t('Missing contact id.'));
|
||||
}
|
||||
|
||||
$checksum = '';
|
||||
$vcard = OC_Contacts_App::getContactVCard( $id );
|
||||
foreach($vcard->children as $property){
|
||||
if($property->name == 'PHOTO') {
|
||||
$checksum = md5($property->serialize());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
OCP\JSON::success(array('data' => array('checksum'=>$checksum)));
|
||||
|
|
@ -125,3 +125,12 @@ input[type="checkbox"] { width: 20px; height: 20px; vertical-align: bottom; }
|
|||
.typelist[type="button"] { float: left; max-width: 10em; border: 0; background-color: #fff; color: #bbb} /* for multiselect */
|
||||
.typelist[type="button"]:hover { color: #777; } /* for multiselect */
|
||||
.addresslist { clear: both; font-weight: bold; }
|
||||
#ninjahelp { position: absolute; bottom: 0; left: 0; right: 0; padding: 1em; margin: 1em; border: thin solid #eee; border-radius: 5px; background-color: #DBDBDB; opacity: 0.9; }
|
||||
#ninjahelp .close { position: absolute; top: 5px; right: 5px; height: 20px; width: 20px; }
|
||||
#ninjahelp h2, .help-section h3 { width: 100%; font-weight: bold; text-align: center; }
|
||||
#ninjahelp h2 { font-size: 1.4em; }
|
||||
.help-section { width: 45%; min-width: 35em; float: left; }
|
||||
.help-section h3 { font-size: 1.2em; }
|
||||
.help-section dl { width: 100%; float: left; clear: right; margin: 0; padding: 0; cursor: normal; }
|
||||
.help-section dt { display: table-cell; clear: left; float: left; width: 35%; margin: 0; padding: 0.2em; text-align: right; text-overflow: ellipsis; vertical-align: text-bottom; font-weight: bold: }
|
||||
.help-section dd { display: table-cell; clear: right; float: left; margin: 0; padding: 0.2em; white-space: nowrap; vertical-align: text-bottom; }
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -78,9 +78,9 @@ Contacts_Import={
|
|||
}
|
||||
$(document).ready(function(){
|
||||
if(typeof FileActions !== 'undefined'){
|
||||
FileActions.register('text/vcard','importaddressbook', '', Contacts_Import.importdialog);
|
||||
FileActions.register('text/vcard','importaddressbook', '', Contacts_Import.importdialog);
|
||||
FileActions.setDefault('text/vcard','importaddressbook');
|
||||
FileActions.register('text/x-vcard','importaddressbook', '', Contacts_Import.importdialog);
|
||||
FileActions.register('text/x-vcard','importaddressbook', '', Contacts_Import.importdialog);
|
||||
FileActions.setDefault('text/x-vcard','importaddressbook');
|
||||
};
|
||||
});
|
|
@ -32,6 +32,38 @@
|
|||
echo $this->inc('part.no_contacts');
|
||||
}
|
||||
?>
|
||||
<div class="hidden" id="ninjahelp">
|
||||
<a class="close" tabindex="0" role="button">
|
||||
<img class="svg" src="core/img/actions/delete.svg" alt="<?php echo $l->t('Close'); ?>" />
|
||||
</a>
|
||||
<h2><?php echo $l->t('Keyboard shortcuts'); ?></h2>
|
||||
<div class="help-section">
|
||||
<h3><?php echo $l->t('Navigation'); ?></h3>
|
||||
<dl>
|
||||
<dt>j/Down/Space</dt>
|
||||
<dd><?php echo $l->t('Next contact in list'); ?></dd>
|
||||
<dt>k/Up/Shift-Space</dt>
|
||||
<dd><?php echo $l->t('Previous contact in list'); ?></dd>
|
||||
<dt>o/Enter</dt>
|
||||
<dd><?php echo $l->t('Expand/collapse current addressbook'); ?></dd>
|
||||
<dt>n/p</dt>
|
||||
<dd><?php echo $l->t('Next/previous addressbook'); ?></dd>
|
||||
</dl>
|
||||
</div>
|
||||
<div class="help-section">
|
||||
<h3><?php echo $l->t('Actions'); ?></h3>
|
||||
<dl>
|
||||
<dt>r</dt>
|
||||
<dd><?php echo $l->t('Refresh contacts list'); ?></dd>
|
||||
<dt>a</dt>
|
||||
<dd><?php echo $l->t('Add new contact'); ?></dd>
|
||||
<dt>Shift-a</dt>
|
||||
<dd><?php echo $l->t('Add new addressbook'); ?></dd>
|
||||
<dt>Shift-Delete</dt>
|
||||
<dd><?php echo $l->t('Delete current contact'); ?></dd>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Dialogs -->
|
||||
<div id="dialog_holder"></div>
|
||||
|
|
|
@ -1,16 +1,25 @@
|
|||
<?php
|
||||
|
||||
// Init owncloud
|
||||
global $eventSource;
|
||||
|
||||
if(!OC_User::isLoggedIn()){
|
||||
exit;
|
||||
}
|
||||
|
||||
OCP\JSON::checkLoggedIn();
|
||||
OCP\JSON::callCheck();
|
||||
session_write_close();
|
||||
|
||||
// Get the params
|
||||
$dir = isset( $_POST['dir'] ) ? stripslashes($_POST['dir']) : '';
|
||||
$filename = isset( $_POST['filename'] ) ? stripslashes($_POST['filename']) : '';
|
||||
$content = isset( $_POST['content'] ) ? $_POST['content'] : '';
|
||||
$source = isset( $_POST['source'] ) ? stripslashes($_POST['source']) : '';
|
||||
$dir = isset( $_REQUEST['dir'] ) ? stripslashes($_REQUEST['dir']) : '';
|
||||
$filename = isset( $_REQUEST['filename'] ) ? stripslashes($_REQUEST['filename']) : '';
|
||||
$content = isset( $_REQUEST['content'] ) ? $_REQUEST['content'] : '';
|
||||
$source = isset( $_REQUEST['source'] ) ? stripslashes($_REQUEST['source']) : '';
|
||||
|
||||
if($source){
|
||||
$eventSource=new OC_EventSource();
|
||||
}else{
|
||||
OC_JSON::callCheck();
|
||||
}
|
||||
|
||||
if($filename == '') {
|
||||
OCP\JSON::error(array("data" => array( "message" => "Empty Filename" )));
|
||||
|
@ -21,22 +30,49 @@ if(strpos($filename,'/')!==false){
|
|||
exit();
|
||||
}
|
||||
|
||||
function progress($notification_code, $severity, $message, $message_code, $bytes_transferred, $bytes_max){
|
||||
static $filesize = 0;
|
||||
static $lastsize = 0;
|
||||
global $eventSource;
|
||||
|
||||
switch($notification_code) {
|
||||
case STREAM_NOTIFY_FILE_SIZE_IS:
|
||||
$filesize = $bytes_max;
|
||||
break;
|
||||
|
||||
case STREAM_NOTIFY_PROGRESS:
|
||||
if ($bytes_transferred > 0) {
|
||||
if (!isset($filesize)) {
|
||||
} else {
|
||||
$progress = (int)(($bytes_transferred/$filesize)*100);
|
||||
if($progress>$lastsize){//limit the number or messages send
|
||||
$eventSource->send('progress',$progress);
|
||||
}
|
||||
$lastsize=$progress;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if($source){
|
||||
if(substr($source,0,8)!='https://' and substr($source,0,7)!='http://'){
|
||||
OCP\JSON::error(array("data" => array( "message" => "Not a valid source" )));
|
||||
exit();
|
||||
}
|
||||
$sourceStream=fopen($source,'rb');
|
||||
|
||||
$ctx = stream_context_create(null, array('notification' =>'progress'));
|
||||
$sourceStream=fopen($source,'rb', false, $ctx);
|
||||
$target=$dir.'/'.$filename;
|
||||
$result=OC_Filesystem::file_put_contents($target,$sourceStream);
|
||||
if($result){
|
||||
$mime=OC_Filesystem::getMimetype($target);
|
||||
OCP\JSON::success(array("data" => array('mime'=>$mime)));
|
||||
exit();
|
||||
$eventSource->send('success',$mime);
|
||||
}else{
|
||||
OCP\JSON::error(array("data" => array( "message" => "Error while downloading ".$source. ' to '.$target )));
|
||||
exit();
|
||||
$eventSource->send('error',"Error while downloading ".$source. ' to '.$target);
|
||||
}
|
||||
$eventSource->close();
|
||||
exit();
|
||||
}else{
|
||||
if($content){
|
||||
if(OC_Filesystem::file_put_contents($dir.'/'.$filename,$content)){
|
||||
|
|
|
@ -16,6 +16,11 @@ session_write_close();
|
|||
if($force or !OC_FileCache::inCache('')){
|
||||
if(!$checkOnly){
|
||||
OCP\DB::beginTransaction();
|
||||
|
||||
if(OC_Cache::isFast()){
|
||||
OC_Cache::clear('fileid/'); //make sure the old fileid's don't mess things up
|
||||
}
|
||||
|
||||
OC_FileCache::scan($dir,$eventSource);
|
||||
OC_FileCache::clean();
|
||||
OCP\DB::commit();
|
||||
|
|
|
@ -1,5 +1,16 @@
|
|||
<?php
|
||||
|
||||
// fix webdav properties, remove namespace information between curly bracket (update from OC4 to OC5)
|
||||
$installedVersion=OCP\Config::getAppValue('files', 'installed_version');
|
||||
if (version_compare($installedVersion, '1.1.4', '<')) {
|
||||
$query = OC_DB::prepare( "SELECT propertyname, propertypath, userid FROM `*PREFIX*properties`" );
|
||||
$result = $query->execute();
|
||||
while( $row = $result->fetchRow()){
|
||||
$query = OC_DB::prepare( 'UPDATE *PREFIX*properties SET propertyname = ? WHERE userid = ? AND propertypath = ?' );
|
||||
$query->execute( array( preg_replace("/^{.*}/", "", $row["propertyname"]),$row["userid"], $row["propertypath"] ));
|
||||
}
|
||||
}
|
||||
|
||||
//update from OC 3
|
||||
|
||||
//try to remove remaining files.
|
||||
|
|
|
@ -1 +1 @@
|
|||
1.1.3
|
||||
1.1.4
|
|
@ -497,23 +497,27 @@ $(document).ready(function() {
|
|||
localName=(localName.match(/:\/\/(.[^/]+)/)[1]).replace('www.','');
|
||||
}
|
||||
localName = getUniqueName(localName);
|
||||
$.post(
|
||||
OC.filePath('files','ajax','newfile.php'),
|
||||
{dir:$('#dir').val(),source:name,filename:localName},
|
||||
function(result){
|
||||
if(result.status == 'success'){
|
||||
var date=new Date();
|
||||
FileList.addFile(localName,0,date);
|
||||
var tr=$('tr').filterAttr('data-file',localName);
|
||||
tr.data('mime',result.data.mime);
|
||||
getMimeIcon(result.data.mime,function(path){
|
||||
tr.find('td.filename').attr('style','background-image:url('+path+')');
|
||||
});
|
||||
}else{
|
||||
$('#uploadprogressbar').progressbar({value:0});
|
||||
$('#uploadprogressbar').fadeIn();
|
||||
|
||||
}
|
||||
}
|
||||
);
|
||||
var eventSource=new OC.EventSource(OC.filePath('files','ajax','newfile.php'),{dir:$('#dir').val(),source:name,filename:localName});
|
||||
eventSource.listen('progress',function(progress){
|
||||
$('#uploadprogressbar').progressbar('value',progress);
|
||||
});
|
||||
eventSource.listen('success',function(mime){
|
||||
$('#uploadprogressbar').fadeOut();
|
||||
var date=new Date();
|
||||
FileList.addFile(localName,0,date);
|
||||
var tr=$('tr').filterAttr('data-file',localName);
|
||||
tr.data('mime',mime);
|
||||
getMimeIcon(mime,function(path){
|
||||
tr.find('td.filename').attr('style','background-image:url('+path+')');
|
||||
});
|
||||
});
|
||||
eventSource.listen('error',function(error){
|
||||
$('#uploadprogressbar').fadeOut();
|
||||
alert(error);
|
||||
});
|
||||
break;
|
||||
}
|
||||
var li=$(this).parent();
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
<?php } ?>
|
||||
<legend><strong><?php echo $l->t('Import user account');?></strong></legend>
|
||||
</p>
|
||||
<p><input type="file" id="owncloud_import" name="owncloud_import" style="width:180px;"><label for="owncloud_import"> <?php echo $l->t('ownCloud User Zip');?></label>
|
||||
<p><input type="file" id="owncloud_import" name="owncloud_import" style="width:280px;"><label for="owncloud_import"> <?php echo $l->t('ownCloud User Zip');?></label>
|
||||
</p>
|
||||
<input type="submit" name="user_import" value="<?php echo $l->t('Import'); ?>" />
|
||||
</fieldset>
|
||||
|
|
|
@ -19,7 +19,7 @@ OCP\Util::addHeader('link',array('rel'=>'openid.delegate', 'href'=>OCP\Util::lin
|
|||
|
||||
OCP\App::registerPersonal('user_openid','settings');
|
||||
|
||||
require_once 'apps/user_openid/user_openid.php';
|
||||
require_once 'openid/user_openid.php';
|
||||
|
||||
//active the openid backend
|
||||
OC_User::useBackend('openid');
|
||||
|
|
|
@ -44,4 +44,4 @@ if(!OCP\User::userExists($USERNAME)){
|
|||
}
|
||||
$IDENTITY=OCP\Util::linkToAbsolute( "user_openid", "user.php" ).'/'.$USERNAME;
|
||||
|
||||
require_once 'phpmyid.php';
|
||||
require_once 'openid/phpmyid.php';
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
*
|
||||
*/
|
||||
|
||||
require_once('class.openid.v3.php');
|
||||
require_once('openid/class.openid.v3.php');
|
||||
|
||||
/**
|
||||
* Class for user OpenId backend
|
||||
|
|
|
@ -139,6 +139,8 @@ li.error { width:640px; margin:4em auto; padding:1em 1em 1em 4em; background:#ff
|
|||
|
||||
a.bookmarklet { background-color: #ddd; border:1px solid #ccc; padding: 5px;padding-top: 0px;padding-bottom: 2px; text-decoration: none; margin-top: 5px }
|
||||
|
||||
.exception{color: #000000;}
|
||||
.exception textarea{width:95%;height: 200px;background:#ffe;border:0;}
|
||||
|
||||
/* ---- DIALOGS ---- */
|
||||
#dirtree {width: 100%;}
|
||||
|
|
|
@ -40,6 +40,7 @@ OC.EventSource=function(src,data){
|
|||
dataStr+=name+'='+encodeURIComponent(data[name])+'&';
|
||||
}
|
||||
}
|
||||
dataStr+='requesttoken='+OC.EventSource.requesttoken;
|
||||
if(!this.useFallBack && typeof EventSource !='undefined'){
|
||||
this.source=new EventSource(src+'?'+dataStr);
|
||||
this.source.onmessage=function(e){
|
||||
|
|
30
core/templates/exception.php
Normal file
30
core/templates/exception.php
Normal file
|
@ -0,0 +1,30 @@
|
|||
<ul>
|
||||
<li class='error'>
|
||||
<details>
|
||||
<summary class="error">We're sorry, but something went terribly wrong.<br></summary>
|
||||
<p class="exception">
|
||||
<?php
|
||||
if($_['showsysinfo'] == true){
|
||||
echo 'If you would like to support ownCloud\'s developers and report this error in our <a href="http://bugs.owncloud.org">Bugtracker</a>, please copy the following informations into the description. <br><br><textarea readonly>';
|
||||
echo 'Message: ' . $_['message'] . "\n";
|
||||
echo 'Error Code: ' . $_['code'] . "\n";
|
||||
echo 'File: ' . $_['file'] . "\n";
|
||||
echo 'Line: ' . $_['line'] . "\n\n";
|
||||
echo 'PHP: ' . $_['sysinfo']['phpversion'] . "\n";
|
||||
echo 'OS: ' . $_['sysinfo']['os'] . "\n";
|
||||
echo 'OS Release: ' . $_['sysinfo']['osrelease'] . "\n";
|
||||
echo 'OS Arch.: ' . $_['sysinfo']['osarchitecture'] . "\n";
|
||||
echo 'PHP-Server-Interface: ' . $_['sysinfo']['phpserverinterface'] . "\n";
|
||||
echo 'Protocol: ' . $_['sysinfo']['serverprotocol'] . "\n";
|
||||
echo 'HTTPS: ' . $_['sysinfo']['https'] . "\n";
|
||||
echo 'Request Method: ' . $_['sysinfo']['requestmethod'] . "\n";
|
||||
echo 'Database: ' . $_['sysinfo']['database'] . "\n";
|
||||
echo '</textarea>';
|
||||
}else{
|
||||
echo 'Your administrator has disabled systeminformations.';
|
||||
}
|
||||
?>
|
||||
</p>
|
||||
</details>
|
||||
</li>
|
||||
</ul>
|
|
@ -33,6 +33,7 @@
|
|||
<script type="text/javascript">
|
||||
$(function() {
|
||||
requesttoken = '<?php echo $_['requesttoken']; ?>';
|
||||
OC.EventSource.requesttoken=requesttoken;
|
||||
$(document).bind('ajaxSend', function(elm, xhr, s){
|
||||
if(requesttoken) {
|
||||
xhr.setRequestHeader('requesttoken', requesttoken);
|
||||
|
|
|
@ -195,7 +195,7 @@ class OC_App{
|
|||
// check if the app is compatible with this version of ownCloud
|
||||
$info=OC_App::getAppInfo($app);
|
||||
$version=OC_Util::getVersion();
|
||||
if(!isset($info['require']) or ($version[0]>$info['require'])){
|
||||
if(!isset($info['require']) or ($version[0]>$info['require'])){
|
||||
OC_Log::write('core','App "'.$info['name'].'" can\'t be installed because it is not compatible with this version of ownCloud',OC_Log::ERROR);
|
||||
return false;
|
||||
}else{
|
||||
|
@ -331,8 +331,8 @@ class OC_App{
|
|||
}
|
||||
|
||||
/**
|
||||
* Get the path where to install apps
|
||||
*/
|
||||
* Get the path where to install apps
|
||||
*/
|
||||
public static function getInstallPath() {
|
||||
if(OC_Config::getValue('appstoreenabled', true)==false) {
|
||||
return false;
|
||||
|
|
108
lib/cache.php
108
lib/cache.php
|
@ -7,48 +7,96 @@
|
|||
*/
|
||||
|
||||
class OC_Cache {
|
||||
/**
|
||||
* @var OC_Cache $user_cache
|
||||
*/
|
||||
static protected $user_cache;
|
||||
/**
|
||||
* @var OC_Cache $global_cache
|
||||
*/
|
||||
static protected $global_cache;
|
||||
/**
|
||||
* @var OC_Cache $global_cache_fast
|
||||
*/
|
||||
static protected $global_cache_fast;
|
||||
/**
|
||||
* @var OC_Cache $user_cache_fast
|
||||
*/
|
||||
static protected $user_cache_fast;
|
||||
static protected $isFast=null;
|
||||
|
||||
static public function getGlobalCache() {
|
||||
/**
|
||||
* get the global cache
|
||||
* @return OC_Cache
|
||||
*/
|
||||
static public function getGlobalCache($fast=false) {
|
||||
if (!self::$global_cache) {
|
||||
$fast_cache = null;
|
||||
if (!$fast_cache && function_exists('xcache_set')) {
|
||||
$fast_cache = new OC_Cache_XCache(true);
|
||||
self::$global_cache_fast = null;
|
||||
if (!self::$global_cache_fast && function_exists('xcache_set')) {
|
||||
self::$global_cache_fast = new OC_Cache_XCache(true);
|
||||
}
|
||||
if (!$fast_cache && function_exists('apc_store')) {
|
||||
$fast_cache = new OC_Cache_APC(true);
|
||||
if (!self::$global_cache_fast && function_exists('apc_store')) {
|
||||
self::$global_cache_fast = new OC_Cache_APC(true);
|
||||
}
|
||||
|
||||
self::$global_cache = new OC_Cache_FileGlobal();
|
||||
if ($fast_cache) {
|
||||
self::$global_cache = new OC_Cache_Broker($fast_cache, self::$global_cache);
|
||||
if (self::$global_cache_fast) {
|
||||
self::$global_cache = new OC_Cache_Broker(self::$global_cache_fast, self::$global_cache);
|
||||
}
|
||||
}
|
||||
if($fast){
|
||||
if(self::$global_cache_fast){
|
||||
return self::$global_cache_fast;
|
||||
}else{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return self::$global_cache;
|
||||
}
|
||||
|
||||
static public function getUserCache() {
|
||||
/**
|
||||
* get the user cache
|
||||
* @return OC_Cache
|
||||
*/
|
||||
static public function getUserCache($fast=false) {
|
||||
if (!self::$user_cache) {
|
||||
$fast_cache = null;
|
||||
if (!$fast_cache && function_exists('xcache_set')) {
|
||||
$fast_cache = new OC_Cache_XCache();
|
||||
self::$user_cache_fast = null;
|
||||
if (!self::$user_cache_fast && function_exists('xcache_set')) {
|
||||
self::$user_cache_fast = new OC_Cache_XCache();
|
||||
}
|
||||
if (!$fast_cache && function_exists('apc_store')) {
|
||||
$fast_cache = new OC_Cache_APC();
|
||||
if (!self::$user_cache_fast && function_exists('apc_store')) {
|
||||
self::$user_cache_fast = new OC_Cache_APC();
|
||||
}
|
||||
|
||||
self::$user_cache = new OC_Cache_File();
|
||||
if ($fast_cache) {
|
||||
self::$user_cache = new OC_Cache_Broker($fast_cache, self::$user_cache);
|
||||
if (self::$user_cache_fast) {
|
||||
self::$user_cache = new OC_Cache_Broker(self::$user_cache_fast, self::$user_cache);
|
||||
}
|
||||
}
|
||||
|
||||
if($fast){
|
||||
if(self::$user_cache_fast){
|
||||
return self::$user_cache_fast;
|
||||
}else{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return self::$user_cache;
|
||||
}
|
||||
|
||||
/**
|
||||
* get a value from the user cache
|
||||
* @return mixed
|
||||
*/
|
||||
static public function get($key) {
|
||||
$user_cache = self::getUserCache();
|
||||
return $user_cache->get($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* set a value in the user cache
|
||||
* @return bool
|
||||
*/
|
||||
static public function set($key, $value, $ttl=0) {
|
||||
if (empty($key)) {
|
||||
return false;
|
||||
|
@ -57,19 +105,43 @@ class OC_Cache {
|
|||
return $user_cache->set($key, $value, $ttl);
|
||||
}
|
||||
|
||||
/**
|
||||
* check if a value is set in the user cache
|
||||
* @return bool
|
||||
*/
|
||||
static public function hasKey($key) {
|
||||
$user_cache = self::getUserCache();
|
||||
return $user_cache->hasKey($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* remove an item from the user cache
|
||||
* @return bool
|
||||
*/
|
||||
static public function remove($key) {
|
||||
$user_cache = self::getUserCache();
|
||||
return $user_cache->remove($key);
|
||||
}
|
||||
|
||||
static public function clear() {
|
||||
/**
|
||||
* clear the user cache of all entries starting with a prefix
|
||||
* @param string prefix (optional)
|
||||
* @return bool
|
||||
*/
|
||||
static public function clear($prefix='') {
|
||||
$user_cache = self::getUserCache();
|
||||
return $user_cache->clear();
|
||||
return $user_cache->clear($prefix);
|
||||
}
|
||||
|
||||
/**
|
||||
* check if a fast memory based cache is available
|
||||
* @return true
|
||||
*/
|
||||
static public function isFast() {
|
||||
if(is_null(self::$isFast)){
|
||||
self::$isFast=function_exists('xcache_set') || function_exists('apc_store');
|
||||
}
|
||||
return self::$isFast;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
5
lib/cache/apc.php
vendored
5
lib/cache/apc.php
vendored
|
@ -43,14 +43,15 @@ class OC_Cache_APC {
|
|||
return apc_delete($this->getNamespace().$key);
|
||||
}
|
||||
|
||||
public function clear(){
|
||||
$ns = $this->getNamespace();
|
||||
public function clear($prefix=''){
|
||||
$ns = $this->getNamespace().$prefix;
|
||||
$cache = apc_cache_info('user');
|
||||
foreach($cache['cache_list'] as $entry) {
|
||||
if (strpos($entry['info'], $ns) === 0) {
|
||||
apc_delete($entry['info']);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if(!function_exists('apc_exists')) {
|
||||
|
|
6
lib/cache/broker.php
vendored
6
lib/cache/broker.php
vendored
|
@ -46,8 +46,8 @@ class OC_Cache_Broker {
|
|||
return $this->slow_cache->remove($key);
|
||||
}
|
||||
|
||||
public function clear(){
|
||||
$this->fast_cache->clear();
|
||||
$this->slow_cache->clear();
|
||||
public function clear($prefix=''){
|
||||
$this->fast_cache->clear($prefix);
|
||||
$this->slow_cache->clear($prefix);
|
||||
}
|
||||
}
|
||||
|
|
5
lib/cache/file.php
vendored
5
lib/cache/file.php
vendored
|
@ -62,15 +62,16 @@ class OC_Cache_File{
|
|||
return $storage->unlink($key);
|
||||
}
|
||||
|
||||
public function clear(){
|
||||
public function clear($prefix=''){
|
||||
$storage = $this->getStorage();
|
||||
if($storage and $storage->is_dir('/')){
|
||||
$dh=$storage->opendir('/');
|
||||
while($file=readdir($dh)){
|
||||
if($file!='.' and $file!='..'){
|
||||
if($file!='.' and $file!='..' and ($prefix==='' || strpos($file, $prefix) === 0)){
|
||||
$storage->unlink('/'.$file);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
5
lib/cache/xcache.php
vendored
5
lib/cache/xcache.php
vendored
|
@ -43,7 +43,8 @@ class OC_Cache_XCache {
|
|||
return xcache_unset($this->getNamespace().$key);
|
||||
}
|
||||
|
||||
public function clear(){
|
||||
return xcache_unset_by_prefix($this->getNamespace());
|
||||
public function clear($prefix=''){
|
||||
xcache_unset_by_prefix($this->getNamespace().$prefix);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -142,6 +142,7 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr
|
|||
public function updateProperties($properties) {
|
||||
$existing = $this->getProperties(array());
|
||||
foreach($properties as $propertyName => $propertyValue) {
|
||||
$propertyName = preg_replace("/^{.*}/", "", $propertyName); // remove leading namespace from property name
|
||||
// If it was null, we need to delete the property
|
||||
if (is_null($propertyValue)) {
|
||||
if(array_key_exists( $propertyName, $existing )){
|
||||
|
|
|
@ -368,9 +368,6 @@ class OC_DB {
|
|||
if( $definition instanceof MDB2_Schema_Error ){
|
||||
die( $definition->getMessage().': '.$definition->getUserInfo());
|
||||
}
|
||||
// if(OC_Config::getValue('dbtype','sqlite')=='sqlite'){
|
||||
// $definition['overwrite']=true;//always overwrite for sqlite
|
||||
// }
|
||||
$ret=self::$schema->createDatabase( $definition );
|
||||
|
||||
// Die in case something went wrong
|
||||
|
@ -527,8 +524,7 @@ class OC_DB {
|
|||
* @brief replaces the owncloud tables with a new set
|
||||
* @param $file string path to the MDB2 xml db export file
|
||||
*/
|
||||
public static function replaceDB( $file ){
|
||||
|
||||
public static function replaceDB( $file ){
|
||||
$apps = OC_App::getAllApps();
|
||||
self::beginTransaction();
|
||||
// Delete the old tables
|
||||
|
|
|
@ -42,6 +42,9 @@ class OC_EventSource{
|
|||
}else{
|
||||
header("Content-Type: text/event-stream");
|
||||
}
|
||||
if( !OC_Util::isCallRegistered()){
|
||||
exit();
|
||||
}
|
||||
flush();
|
||||
|
||||
}
|
||||
|
|
93
lib/exception.php
Normal file
93
lib/exception.php
Normal file
|
@ -0,0 +1,93 @@
|
|||
<?php
|
||||
/**
|
||||
* ownCloud
|
||||
*
|
||||
* @author Georg Ehrke
|
||||
* @copyright 2012 georg@owncloud.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/>.
|
||||
*
|
||||
*/
|
||||
class OC_Exception extends Exception{
|
||||
|
||||
function __construct($message = null, $code = 0, $file = null, $line = null){
|
||||
parent::__construct($message, $code);
|
||||
if(!is_null($file)){
|
||||
$this->file = $file;
|
||||
}
|
||||
if(!is_null($line)){
|
||||
$this->line = $line;
|
||||
}
|
||||
$this->writelog();
|
||||
}
|
||||
|
||||
private function writelog(){
|
||||
@OC_Log::write(OC_App::getCurrentApp(), $this->getMessage() . '-' . $this->getFile() . '-' . $this->getLine(), OC_Log::FATAL);
|
||||
}
|
||||
|
||||
private function generatesysinfo(){
|
||||
return array('phpversion' => PHP_VERSION,
|
||||
'os' => php_uname('s'),
|
||||
'osrelease' => php_uname('r'),
|
||||
'osarchitecture' => php_uname('m'),
|
||||
'phpserverinterface' => php_sapi_name(),
|
||||
'serverprotocol' => $_SERVER['SERVER_PROTOCOL'],
|
||||
'requestmethod' => $_SERVER['REQUEST_METHOD'],
|
||||
'https' => ($_SERVER['HTTPS']==''?'false':'true'),
|
||||
'database'=>(@OC_Config::getValue('dbtype')!=''?@OC_Config::getValue('dbtype'):'')
|
||||
);
|
||||
}
|
||||
|
||||
function __toString(){
|
||||
$tmpl = new OC_Template('core', 'exception', 'guest');
|
||||
$tmpl->assign('showsysinfo', true);
|
||||
$tmpl->assign('message', $this->getMessage());
|
||||
$tmpl->assign('code', $this->getCode());
|
||||
$tmpl->assign('file', $this->getFile());
|
||||
$tmpl->assign('line', $this->getLine());
|
||||
$tmpl->assign('sysinfo', $this->generatesysinfo());
|
||||
$tmpl->printPage();
|
||||
}
|
||||
}
|
||||
|
||||
function oc_exceptionhandler($exception){
|
||||
switch($exception->getCode()){
|
||||
case E_NOTICE:
|
||||
case E_DEPRECATED:
|
||||
case E_USER_NOTICE:
|
||||
case E_USER_DEPRECATED:
|
||||
break;
|
||||
default:
|
||||
throw new OC_Exception($exception->getMessage(), $exception->getCode(), $exception->getFile(), $exception->getLine());
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function oc_errorhandler($errno , $errstr , $errfile , $errline){
|
||||
switch($errno){
|
||||
case E_NOTICE:
|
||||
case E_DEPRECATED:
|
||||
case E_USER_NOTICE:
|
||||
case E_USER_DEPRECATED:
|
||||
break;
|
||||
default:
|
||||
throw new OC_Exception($errstr, $errno, $errfile, $errline);
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
set_exception_handler('oc_exceptionhandler');
|
||||
set_error_handler('oc_errorhandler');
|
||||
error_reporting(E_ERROR | E_WARNING | E_PARSE);
|
|
@ -98,6 +98,10 @@ class OC_FileCache{
|
|||
if(OC_DB::isError($result)){
|
||||
OC_Log::write('files','error while writing file('.$path.') to cache',OC_Log::ERROR);
|
||||
}
|
||||
|
||||
if($cache=OC_Cache::getUserCache(true)){
|
||||
$cache->remove('fileid/'.$path);//ensure we don't have -1 cached
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -146,6 +150,11 @@ class OC_FileCache{
|
|||
$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)));
|
||||
|
||||
if(($cache=OC_Cache::getUserCache(true)) && $cache->hasKey('fileid/'.$oldPath)){
|
||||
$cache->set('fileid/'.$newPath,$cache->get('fileid/'.$oldPath));
|
||||
$cache->remove('fileid/'.$oldPath);
|
||||
}
|
||||
|
||||
$query=OC_DB::prepare('SELECT path FROM *PREFIX*fscache WHERE path LIKE ?');
|
||||
$oldLength=strlen($oldPath);
|
||||
$updateQuery=OC_DB::prepare('UPDATE *PREFIX*fscache SET path=?, path_hash=? WHERE path_hash=?');
|
||||
|
@ -153,6 +162,11 @@ class OC_FileCache{
|
|||
$old=$row['path'];
|
||||
$new=$newPath.substr($old,$oldLength);
|
||||
$updateQuery->execute(array($new,md5($new),md5($old)));
|
||||
|
||||
if(($cache=OC_Cache::getUserCache(true)) && $cache->hasKey('fileid/'.$old)){
|
||||
$cache->set('fileid/'.$new,$cache->get('fileid/'.$old));
|
||||
$cache->remove('fileid/'.$old);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -171,6 +185,8 @@ class OC_FileCache{
|
|||
//delete everything inside the folder
|
||||
$query=OC_DB::prepare('DELETE FROM *PREFIX*fscache WHERE path LIKE ?');
|
||||
$query->execute(array($root.$path.'/%'));
|
||||
|
||||
OC_Cache::remove('fileid/'.$root.$path);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -245,9 +261,14 @@ class OC_FileCache{
|
|||
if($root===false){
|
||||
$root=OC_Filesystem::getRoot();
|
||||
}
|
||||
|
||||
$fullPath=$root.$path;
|
||||
if(($cache=OC_Cache::getUserCache(true)) && $cache->hasKey('fileid/'.$fullPath)){
|
||||
return $cache->get('fileid/'.$fullPath);
|
||||
}
|
||||
|
||||
$query=OC_DB::prepare('SELECT id FROM *PREFIX*fscache WHERE path_hash=?');
|
||||
$result=$query->execute(array(md5($root.$path)));
|
||||
$result=$query->execute(array(md5($fullPath)));
|
||||
if(OC_DB::isError($result)){
|
||||
OC_Log::write('files','error while getting file id of '.$path,OC_Log::ERROR);
|
||||
return -1;
|
||||
|
@ -255,10 +276,15 @@ class OC_FileCache{
|
|||
|
||||
$result=$result->fetchRow();
|
||||
if(is_array($result)){
|
||||
return $result['id'];
|
||||
$id=$result['id'];
|
||||
}else{
|
||||
return -1;
|
||||
$id=-1;
|
||||
}
|
||||
if($cache=OC_Cache::getUserCache(true)){
|
||||
$cache->set('fileid/'.$fullPath,$id);
|
||||
}
|
||||
|
||||
return $id;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -53,99 +53,99 @@ class OC_Filesystem{
|
|||
static private $defaultInstance;
|
||||
|
||||
|
||||
/**
|
||||
* classname which used for hooks handling
|
||||
* used as signalclass in OC_Hooks::emit()
|
||||
*/
|
||||
const CLASSNAME = 'OC_Filesystem';
|
||||
/**
|
||||
* classname which used for hooks handling
|
||||
* used as signalclass in OC_Hooks::emit()
|
||||
*/
|
||||
const CLASSNAME = 'OC_Filesystem';
|
||||
|
||||
/**
|
||||
* signalname emited before file renaming
|
||||
* @param oldpath
|
||||
* @param newpath
|
||||
*/
|
||||
const signal_rename = 'rename';
|
||||
/**
|
||||
* signalname emited before file renaming
|
||||
* @param oldpath
|
||||
* @param newpath
|
||||
*/
|
||||
const signal_rename = 'rename';
|
||||
|
||||
/**
|
||||
* signal emited after file renaming
|
||||
* @param oldpath
|
||||
* @param newpath
|
||||
*/
|
||||
const signal_post_rename = 'post_rename';
|
||||
|
||||
/**
|
||||
* signal emited before file/dir creation
|
||||
* @param path
|
||||
* @param run changing this flag to false in hook handler will cancel event
|
||||
*/
|
||||
const signal_create = 'create';
|
||||
/**
|
||||
* signal emited after file renaming
|
||||
* @param oldpath
|
||||
* @param newpath
|
||||
*/
|
||||
const signal_post_rename = 'post_rename';
|
||||
|
||||
/**
|
||||
* signal emited after file/dir creation
|
||||
* @param path
|
||||
* @param run changing this flag to false in hook handler will cancel event
|
||||
*/
|
||||
const signal_post_create = 'post_create';
|
||||
/**
|
||||
* signal emited before file/dir creation
|
||||
* @param path
|
||||
* @param run changing this flag to false in hook handler will cancel event
|
||||
*/
|
||||
const signal_create = 'create';
|
||||
|
||||
/**
|
||||
* signal emits before file/dir copy
|
||||
* @param oldpath
|
||||
* @param newpath
|
||||
* @param run changing this flag to false in hook handler will cancel event
|
||||
*/
|
||||
const signal_copy = 'copy';
|
||||
/**
|
||||
* signal emited after file/dir creation
|
||||
* @param path
|
||||
* @param run changing this flag to false in hook handler will cancel event
|
||||
*/
|
||||
const signal_post_create = 'post_create';
|
||||
|
||||
/**
|
||||
* signal emits after file/dir copy
|
||||
* @param oldpath
|
||||
* @param newpath
|
||||
*/
|
||||
const signal_post_copy = 'post_copy';
|
||||
/**
|
||||
* signal emits before file/dir copy
|
||||
* @param oldpath
|
||||
* @param newpath
|
||||
* @param run changing this flag to false in hook handler will cancel event
|
||||
*/
|
||||
const signal_copy = 'copy';
|
||||
|
||||
/**
|
||||
* signal emits before file/dir save
|
||||
* @param path
|
||||
* @param run changing this flag to false in hook handler will cancel event
|
||||
*/
|
||||
const signal_write = 'write';
|
||||
/**
|
||||
* signal emits after file/dir copy
|
||||
* @param oldpath
|
||||
* @param newpath
|
||||
*/
|
||||
const signal_post_copy = 'post_copy';
|
||||
|
||||
/**
|
||||
* signal emits after file/dir save
|
||||
* @param path
|
||||
*/
|
||||
const signal_post_write = 'post_write';
|
||||
|
||||
/**
|
||||
* signal emits when reading file/dir
|
||||
* @param path
|
||||
*/
|
||||
const signal_read = 'read';
|
||||
/**
|
||||
* signal emits before file/dir save
|
||||
* @param path
|
||||
* @param run changing this flag to false in hook handler will cancel event
|
||||
*/
|
||||
const signal_write = 'write';
|
||||
|
||||
/**
|
||||
* signal emits when removing file/dir
|
||||
* @param path
|
||||
*/
|
||||
const signal_delete = 'delete';
|
||||
/**
|
||||
* signal emits after file/dir save
|
||||
* @param path
|
||||
*/
|
||||
const signal_post_write = 'post_write';
|
||||
|
||||
/**
|
||||
* parameters definitions for signals
|
||||
*/
|
||||
const signal_param_path = 'path';
|
||||
const signal_param_oldpath = 'oldpath';
|
||||
const signal_param_newpath = 'newpath';
|
||||
/**
|
||||
* signal emits when reading file/dir
|
||||
* @param path
|
||||
*/
|
||||
const signal_read = 'read';
|
||||
|
||||
/**
|
||||
* run - changing this flag to false in hook handler will cancel event
|
||||
*/
|
||||
const signal_param_run = 'run';
|
||||
/**
|
||||
* signal emits when removing file/dir
|
||||
* @param path
|
||||
*/
|
||||
const signal_delete = 'delete';
|
||||
|
||||
/**
|
||||
* get the mountpoint of the storage object for a path
|
||||
( note: because a storage is not always mounted inside the fakeroot, the returned mountpoint is relative to the absolute root of the filesystem and doesn't take the chroot into account
|
||||
*
|
||||
* @param string path
|
||||
* @return string
|
||||
*/
|
||||
/**
|
||||
* parameters definitions for signals
|
||||
*/
|
||||
const signal_param_path = 'path';
|
||||
const signal_param_oldpath = 'oldpath';
|
||||
const signal_param_newpath = 'newpath';
|
||||
|
||||
/**
|
||||
* run - changing this flag to false in hook handler will cancel event
|
||||
*/
|
||||
const signal_param_run = 'run';
|
||||
|
||||
/**
|
||||
* get the mountpoint of the storage object for a path
|
||||
( note: because a storage is not always mounted inside the fakeroot, the returned mountpoint is relative to the absolute root of the filesystem and doesn't take the chroot into account
|
||||
*
|
||||
* @param string path
|
||||
* @return string
|
||||
*/
|
||||
static public function getMountPoint($path){
|
||||
OC_Hook::emit(self::CLASSNAME,'get_mountpoint',array('path'=>$path));
|
||||
if(!$path){
|
||||
|
|
|
@ -22,19 +22,19 @@
|
|||
|
||||
|
||||
/**
|
||||
* Class to provide access to ownCloud filesystem via a "view", and methods for
|
||||
* working with files within that view (e.g. read, write, delete, etc.). Each
|
||||
* view is restricted to a set of directories via a virtual root. The default view
|
||||
* uses the currently logged in user's data directory as root (parts of
|
||||
* Class to provide access to ownCloud filesystem via a "view", and methods for
|
||||
* working with files within that view (e.g. read, write, delete, etc.). Each
|
||||
* view is restricted to a set of directories via a virtual root. The default view
|
||||
* uses the currently logged in user's data directory as root (parts of
|
||||
* OC_Filesystem are merely a wrapper for OC_FilesystemView).
|
||||
*
|
||||
*
|
||||
* Apps that need to access files outside of the user data folders (to modify files
|
||||
* belonging to a user other than the one currently logged in, for example) should
|
||||
* use this class directly rather than using OC_Filesystem, or making use of PHP's
|
||||
* built-in file manipulation functions. This will ensure all hooks and proxies
|
||||
* built-in file manipulation functions. This will ensure all hooks and proxies
|
||||
* are triggered correctly.
|
||||
*
|
||||
* Filesystem functions are not called directly; they are passed to the correct
|
||||
* Filesystem functions are not called directly; they are passed to the correct
|
||||
* OC_Filestorage object
|
||||
*/
|
||||
|
||||
|
@ -43,11 +43,11 @@ class OC_FilesystemView {
|
|||
private $internal_path_cache=array();
|
||||
private $storage_cache=array();
|
||||
|
||||
public function __construct($root){
|
||||
public function __construct($root) {
|
||||
$this->fakeRoot=$root;
|
||||
}
|
||||
|
||||
public function getAbsolutePath($path){
|
||||
public function getAbsolutePath($path) {
|
||||
if(!$path){
|
||||
$path='/';
|
||||
}
|
||||
|
@ -63,9 +63,9 @@ class OC_FilesystemView {
|
|||
* @param string fakeRoot
|
||||
* @return bool
|
||||
*/
|
||||
public function chroot($fakeRoot){
|
||||
public function chroot($fakeRoot) {
|
||||
if(!$fakeRoot==''){
|
||||
if($fakeRoot[0]!=='/'){
|
||||
if($fakeRoot[0]!=='/') {
|
||||
$fakeRoot='/'.$fakeRoot;
|
||||
}
|
||||
}
|
||||
|
@ -76,7 +76,7 @@ class OC_FilesystemView {
|
|||
* get the fake root
|
||||
* @return string
|
||||
*/
|
||||
public function getRoot(){
|
||||
public function getRoot() {
|
||||
return $this->fakeRoot;
|
||||
}
|
||||
|
||||
|
@ -85,7 +85,7 @@ class OC_FilesystemView {
|
|||
* @param string path
|
||||
* @return bool
|
||||
*/
|
||||
public function getInternalPath($path){
|
||||
public function getInternalPath($path) {
|
||||
if (!isset($this->internal_path_cache[$path])) {
|
||||
$this->internal_path_cache[$path] = OC_Filesystem::getInternalPath($this->getAbsolutePath($path));
|
||||
}
|
||||
|
@ -97,23 +97,23 @@ class OC_FilesystemView {
|
|||
* @param string path
|
||||
* @return string
|
||||
*/
|
||||
public function getRelativePath($path){
|
||||
if($this->fakeRoot==''){
|
||||
public function getRelativePath($path) {
|
||||
if($this->fakeRoot=='') {
|
||||
return $path;
|
||||
}
|
||||
if(strpos($path,$this->fakeRoot)!==0){
|
||||
if(strpos($path, $this->fakeRoot)!==0) {
|
||||
return null;
|
||||
}else{
|
||||
return substr($path,strlen($this->fakeRoot));
|
||||
return substr($path, strlen($this->fakeRoot));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* get the storage object for a path
|
||||
* @param string path
|
||||
* @return OC_Filestorage
|
||||
*/
|
||||
public function getStorage($path){
|
||||
public function getStorage($path) {
|
||||
if (!isset($this->storage_cache[$path])) {
|
||||
$this->storage_cache[$path] = OC_Filesystem::getStorage($this->getAbsolutePath($path));
|
||||
}
|
||||
|
@ -127,7 +127,7 @@ class OC_FilesystemView {
|
|||
* @param string path
|
||||
* @return string
|
||||
*/
|
||||
public function getMountPoint($path){
|
||||
public function getMountPoint($path) {
|
||||
return OC_Filesystem::getMountPoint($this->getAbsolutePath($path));
|
||||
}
|
||||
|
||||
|
@ -137,55 +137,55 @@ class OC_FilesystemView {
|
|||
* @param string path
|
||||
* @return string
|
||||
*/
|
||||
public function getLocalFile($path){
|
||||
$parent=substr($path,0,strrpos($path,'/'));
|
||||
if(OC_Filesystem::isValidPath($parent) and $storage=$this->getStorage($path)){
|
||||
public function getLocalFile($path) {
|
||||
$parent=substr($path, 0, strrpos($path,'/'));
|
||||
if(OC_Filesystem::isValidPath($parent) and $storage=$this->getStorage($path)) {
|
||||
return $storage->getLocalFile($this->getInternalPath($path));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* the following functions operate with arguments and return values identical
|
||||
* to those of their PHP built-in equivalents. Mostly they are merely wrappers
|
||||
* the following functions operate with arguments and return values identical
|
||||
* to those of their PHP built-in equivalents. Mostly they are merely wrappers
|
||||
* for OC_Filestorage via basicOperation().
|
||||
*/
|
||||
public function mkdir($path){
|
||||
return $this->basicOperation('mkdir',$path,array('create','write'));
|
||||
public function mkdir($path) {
|
||||
return $this->basicOperation('mkdir', $path, array('create', 'write'));
|
||||
}
|
||||
public function rmdir($path){
|
||||
return $this->basicOperation('rmdir',$path,array('delete'));
|
||||
public function rmdir($path) {
|
||||
return $this->basicOperation('rmdir', $path, array('delete'));
|
||||
}
|
||||
public function opendir($path){
|
||||
return $this->basicOperation('opendir',$path,array('read'));
|
||||
public function opendir($path) {
|
||||
return $this->basicOperation('opendir', $path, array('read'));
|
||||
}
|
||||
public function readdir($handle){
|
||||
public function readdir($handle) {
|
||||
$fsLocal= new OC_Filestorage_Local( array( 'datadir' => '/' ) );
|
||||
return $fsLocal->readdir( $handle );
|
||||
}
|
||||
public function is_dir($path){
|
||||
public function is_dir($path) {
|
||||
if($path=='/'){
|
||||
return true;
|
||||
}
|
||||
return $this->basicOperation('is_dir',$path);
|
||||
return $this->basicOperation('is_dir', $path);
|
||||
}
|
||||
public function is_file($path){
|
||||
public function is_file($path) {
|
||||
if($path=='/'){
|
||||
return false;
|
||||
}
|
||||
return $this->basicOperation('is_file',$path);
|
||||
return $this->basicOperation('is_file', $path);
|
||||
}
|
||||
public function stat($path){
|
||||
return $this->basicOperation('stat',$path);
|
||||
public function stat($path) {
|
||||
return $this->basicOperation('stat', $path);
|
||||
}
|
||||
public function filetype($path){
|
||||
return $this->basicOperation('filetype',$path);
|
||||
public function filetype($path) {
|
||||
return $this->basicOperation('filetype', $path);
|
||||
}
|
||||
public function filesize($path){
|
||||
return $this->basicOperation('filesize',$path);
|
||||
public function filesize($path) {
|
||||
return $this->basicOperation('filesize', $path);
|
||||
}
|
||||
public function readfile($path){
|
||||
public function readfile($path) {
|
||||
@ob_end_clean();
|
||||
$handle=$this->fopen($path,'rb');
|
||||
$handle=$this->fopen($path, 'rb');
|
||||
if ($handle) {
|
||||
$chunkSize = 8192;// 8 MB chunks
|
||||
while (!feof($handle)) {
|
||||
|
@ -197,137 +197,210 @@ class OC_FilesystemView {
|
|||
}
|
||||
return false;
|
||||
}
|
||||
public function is_readable($path){
|
||||
return $this->basicOperation('is_readable',$path);
|
||||
public function is_readable($path) {
|
||||
return $this->basicOperation('is_readable', $path);
|
||||
}
|
||||
public function is_writable($path){
|
||||
return $this->basicOperation('is_writable',$path);
|
||||
public function is_writable($path) {
|
||||
return $this->basicOperation('is_writable', $path);
|
||||
}
|
||||
public function file_exists($path){
|
||||
public function file_exists($path) {
|
||||
if($path=='/'){
|
||||
return true;
|
||||
}
|
||||
return $this->basicOperation('file_exists',$path);
|
||||
return $this->basicOperation('file_exists', $path);
|
||||
}
|
||||
public function filectime($path){
|
||||
return $this->basicOperation('filectime',$path);
|
||||
public function filectime($path) {
|
||||
return $this->basicOperation('filectime', $path);
|
||||
}
|
||||
public function filemtime($path){
|
||||
return $this->basicOperation('filemtime',$path);
|
||||
public function filemtime($path) {
|
||||
return $this->basicOperation('filemtime', $path);
|
||||
}
|
||||
public function touch($path, $mtime=null){
|
||||
public function touch($path, $mtime=null) {
|
||||
return $this->basicOperation('touch', $path, array('write'), $mtime);
|
||||
}
|
||||
public function file_get_contents($path){
|
||||
return $this->basicOperation('file_get_contents',$path,array('read'));
|
||||
public function file_get_contents($path) {
|
||||
return $this->basicOperation('file_get_contents', $path, array('read'));
|
||||
}
|
||||
public function file_put_contents($path,$data){
|
||||
if(is_resource($data)){//not having to deal with streams in file_put_contents makes life easier
|
||||
$exists=$this->file_exists($path);
|
||||
$run=true;
|
||||
if(!$exists){
|
||||
OC_Hook::emit( OC_Filesystem::CLASSNAME, OC_Filesystem::signal_create, array( OC_Filesystem::signal_param_path => $path, OC_Filesystem::signal_param_run => &$run));
|
||||
public function file_put_contents($path, $data) {
|
||||
if(is_resource($data)) {//not having to deal with streams in file_put_contents makes life easier
|
||||
$exists = $this->file_exists($path);
|
||||
$run = true;
|
||||
if(!$exists) {
|
||||
OC_Hook::emit(
|
||||
OC_Filesystem::CLASSNAME,
|
||||
OC_Filesystem::signal_create,
|
||||
array(
|
||||
OC_Filesystem::signal_param_path => $path,
|
||||
OC_Filesystem::signal_param_run => &$run
|
||||
)
|
||||
);
|
||||
}
|
||||
OC_Hook::emit( OC_Filesystem::CLASSNAME, OC_Filesystem::signal_write, array( OC_Filesystem::signal_param_path => $path, OC_Filesystem::signal_param_run => &$run));
|
||||
if(!$run){
|
||||
OC_Hook::emit(
|
||||
OC_Filesystem::CLASSNAME,
|
||||
OC_Filesystem::signal_write,
|
||||
array(
|
||||
OC_Filesystem::signal_param_path => $path,
|
||||
OC_Filesystem::signal_param_run => &$run
|
||||
)
|
||||
);
|
||||
if(!$run) {
|
||||
return false;
|
||||
}
|
||||
$target=$this->fopen($path,'w');
|
||||
if($target){
|
||||
$count=OC_Helper::streamCopy($data,$target);
|
||||
$target=$this->fopen($path, 'w');
|
||||
if($target) {
|
||||
$count=OC_Helper::streamCopy($data, $target);
|
||||
fclose($target);
|
||||
fclose($data);
|
||||
if(!$exists){
|
||||
OC_Hook::emit( OC_Filesystem::CLASSNAME, OC_Filesystem::signal_post_create, array( OC_Filesystem::signal_param_path => $path));
|
||||
if(!$exists) {
|
||||
OC_Hook::emit(
|
||||
OC_Filesystem::CLASSNAME,
|
||||
OC_Filesystem::signal_post_create,
|
||||
array( OC_Filesystem::signal_param_path => $path)
|
||||
);
|
||||
}
|
||||
OC_Hook::emit( OC_Filesystem::CLASSNAME, OC_Filesystem::signal_post_write, array( OC_Filesystem::signal_param_path => $path));
|
||||
return $count>0;
|
||||
OC_Hook::emit(
|
||||
OC_Filesystem::CLASSNAME,
|
||||
OC_Filesystem::signal_post_write,
|
||||
array( OC_Filesystem::signal_param_path => $path)
|
||||
);
|
||||
return $count > 0;
|
||||
}else{
|
||||
return false;
|
||||
}
|
||||
}else{
|
||||
return $this->basicOperation('file_put_contents',$path,array('create','write'),$data);
|
||||
return $this->basicOperation('file_put_contents', $path, array('create', 'write'), $data);
|
||||
}
|
||||
}
|
||||
public function unlink($path){
|
||||
return $this->basicOperation('unlink',$path,array('delete'));
|
||||
public function unlink($path) {
|
||||
return $this->basicOperation('unlink', $path, array('delete'));
|
||||
}
|
||||
public function deleteAll( $directory, $empty = false ) {
|
||||
return $this->basicOperation( 'deleteAll', $directory, array('delete'), $empty );
|
||||
}
|
||||
public function rename($path1,$path2){
|
||||
$absolutePath1=$this->getAbsolutePath($path1);
|
||||
$absolutePath2=$this->getAbsolutePath($path2);
|
||||
if(OC_FileProxy::runPreProxies('rename',$absolutePath1,$absolutePath2) and OC_Filesystem::isValidPath($path2)){
|
||||
$path1=$this->getRelativePath($absolutePath1);
|
||||
$path2=$this->getRelativePath($absolutePath2);
|
||||
if($path1==null or $path2==null){
|
||||
public function rename($path1, $path2) {
|
||||
$absolutePath1 = $this->getAbsolutePath($path1);
|
||||
$absolutePath2 = $this->getAbsolutePath($path2);
|
||||
if(OC_FileProxy::runPreProxies('rename', $absolutePath1, $absolutePath2) and OC_Filesystem::isValidPath($path2)) {
|
||||
$path1 = $this->getRelativePath($absolutePath1);
|
||||
$path2 = $this->getRelativePath($absolutePath2);
|
||||
if($path1 == null or $path2 == null) {
|
||||
return false;
|
||||
}
|
||||
$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){
|
||||
$mp1=$this->getMountPoint($path1);
|
||||
$mp2=$this->getMountPoint($path2);
|
||||
if($mp1==$mp2){
|
||||
if($storage=$this->getStorage($path1)){
|
||||
$result=$storage->rename($this->getInternalPath($path1),$this->getInternalPath($path2));
|
||||
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) {
|
||||
$mp1 = $this->getMountPoint($path1);
|
||||
$mp2 = $this->getMountPoint($path2);
|
||||
if($mp1 == $mp2) {
|
||||
if($storage = $this->getStorage($path1)) {
|
||||
$result = $storage->rename($this->getInternalPath($path1), $this->getInternalPath($path2));
|
||||
}
|
||||
}else{
|
||||
$source=$this->fopen($path1,'r');
|
||||
$target=$this->fopen($path2,'w');
|
||||
$count=OC_Helper::streamCopy($source,$target);
|
||||
$storage1=$this->getStorage($path1);
|
||||
} else {
|
||||
$source = $this->fopen($path1, 'r');
|
||||
$target = $this->fopen($path2, 'w');
|
||||
$count = OC_Helper::streamCopy($source, $target);
|
||||
$storage1 = $this->getStorage($path1);
|
||||
$storage1->unlink($this->getInternalPath($path1));
|
||||
$result=$count>0;
|
||||
$result = $count>0;
|
||||
}
|
||||
OC_Hook::emit( OC_Filesystem::CLASSNAME, OC_Filesystem::signal_post_rename, array( OC_Filesystem::signal_param_oldpath => $path1, OC_Filesystem::signal_param_newpath=>$path2));
|
||||
OC_Hook::emit(
|
||||
OC_Filesystem::CLASSNAME,
|
||||
OC_Filesystem::signal_post_rename,
|
||||
array(
|
||||
OC_Filesystem::signal_param_oldpath => $path1,
|
||||
OC_Filesystem::signal_param_newpath => $path2
|
||||
)
|
||||
);
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
}
|
||||
public function copy($path1,$path2){
|
||||
$absolutePath1=$this->getAbsolutePath($path1);
|
||||
$absolutePath2=$this->getAbsolutePath($path2);
|
||||
if(OC_FileProxy::runPreProxies('copy',$absolutePath1,$absolutePath2) and OC_Filesystem::isValidPath($path2)){
|
||||
$path1=$this->getRelativePath($absolutePath1);
|
||||
$path2=$this->getRelativePath($absolutePath2);
|
||||
if($path1==null or $path2==null){
|
||||
public function copy($path1, $path2) {
|
||||
$absolutePath1 = $this->getAbsolutePath($path1);
|
||||
$absolutePath2 = $this->getAbsolutePath($path2);
|
||||
if(OC_FileProxy::runPreProxies('copy', $absolutePath1, $absolutePath2) and OC_Filesystem::isValidPath($path2)) {
|
||||
$path1 = $this->getRelativePath($absolutePath1);
|
||||
$path2 = $this->getRelativePath($absolutePath2);
|
||||
if($path1 == null or $path2 == null) {
|
||||
return false;
|
||||
}
|
||||
$run=true;
|
||||
OC_Hook::emit( OC_Filesystem::CLASSNAME, OC_Filesystem::signal_copy, array( OC_Filesystem::signal_param_oldpath => $path1 , OC_Filesystem::signal_param_newpath=>$path2, OC_Filesystem::signal_param_run => &$run));
|
||||
OC_Hook::emit(
|
||||
OC_Filesystem::CLASSNAME,
|
||||
OC_Filesystem::signal_copy,
|
||||
array(
|
||||
OC_Filesystem::signal_param_oldpath => $path1,
|
||||
OC_Filesystem::signal_param_newpath=>$path2,
|
||||
OC_Filesystem::signal_param_run => &$run
|
||||
)
|
||||
);
|
||||
$exists=$this->file_exists($path2);
|
||||
if($run and !$exists){
|
||||
OC_Hook::emit( OC_Filesystem::CLASSNAME, OC_Filesystem::signal_create, array( OC_Filesystem::signal_param_path => $path2, OC_Filesystem::signal_param_run => &$run));
|
||||
if($run and !$exists) {
|
||||
OC_Hook::emit(
|
||||
OC_Filesystem::CLASSNAME,
|
||||
OC_Filesystem::signal_create,
|
||||
array(
|
||||
OC_Filesystem::signal_param_path => $path2,
|
||||
OC_Filesystem::signal_param_run => &$run
|
||||
)
|
||||
);
|
||||
}
|
||||
if($run){
|
||||
OC_Hook::emit( OC_Filesystem::CLASSNAME, OC_Filesystem::signal_write, array( OC_Filesystem::signal_param_path => $path2, OC_Filesystem::signal_param_run => &$run));
|
||||
if($run) {
|
||||
OC_Hook::emit(
|
||||
OC_Filesystem::CLASSNAME,
|
||||
OC_Filesystem::signal_write,
|
||||
array(
|
||||
OC_Filesystem::signal_param_path => $path2,
|
||||
OC_Filesystem::signal_param_run => &$run
|
||||
)
|
||||
);
|
||||
}
|
||||
if($run){
|
||||
if($run) {
|
||||
$mp1=$this->getMountPoint($path1);
|
||||
$mp2=$this->getMountPoint($path2);
|
||||
if($mp1==$mp2){
|
||||
if($storage=$this->getStorage($path1)){
|
||||
$result=$storage->copy($this->getInternalPath($path1),$this->getInternalPath($path2));
|
||||
if($mp1 == $mp2){
|
||||
if($storage = $this->getStorage($path1)) {
|
||||
$result=$storage->copy($this->getInternalPath($path1), $this->getInternalPath($path2));
|
||||
}
|
||||
}else{
|
||||
$source=$this->fopen($path1,'r');
|
||||
$target=$this->fopen($path2,'w');
|
||||
$result=OC_Helper::streamCopy($source,$target);
|
||||
} else {
|
||||
$source = $this->fopen($path1, 'r');
|
||||
$target = $this->fopen($path2, 'w');
|
||||
$result = OC_Helper::streamCopy($source, $target);
|
||||
}
|
||||
OC_Hook::emit( OC_Filesystem::CLASSNAME, OC_Filesystem::signal_post_copy, array( OC_Filesystem::signal_param_oldpath => $path1 , OC_Filesystem::signal_param_newpath=>$path2));
|
||||
if(!$exists){
|
||||
OC_Hook::emit( OC_Filesystem::CLASSNAME, OC_Filesystem::signal_post_create, array( OC_Filesystem::signal_param_path => $path2));
|
||||
OC_Hook::emit(
|
||||
OC_Filesystem::CLASSNAME,
|
||||
OC_Filesystem::signal_post_copy,
|
||||
array(
|
||||
OC_Filesystem::signal_param_oldpath => $path1,
|
||||
OC_Filesystem::signal_param_newpath=>$path2
|
||||
)
|
||||
);
|
||||
if(!$exists) {
|
||||
OC_Hook::emit(
|
||||
OC_Filesystem::CLASSNAME,
|
||||
OC_Filesystem::signal_post_create,
|
||||
array(OC_Filesystem::signal_param_path => $path2)
|
||||
);
|
||||
}
|
||||
OC_Hook::emit( OC_Filesystem::CLASSNAME, OC_Filesystem::signal_post_write, array( OC_Filesystem::signal_param_path => $path2));
|
||||
OC_Hook::emit(
|
||||
OC_Filesystem::CLASSNAME,
|
||||
OC_Filesystem::signal_post_write,
|
||||
array( OC_Filesystem::signal_param_path => $path2)
|
||||
);
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
}
|
||||
public function fopen($path,$mode){
|
||||
public function fopen($path, $mode) {
|
||||
$hooks=array();
|
||||
switch($mode){
|
||||
switch($mode) {
|
||||
case 'r':
|
||||
case 'rb':
|
||||
$hooks[]='read';
|
||||
|
@ -355,49 +428,49 @@ class OC_FilesystemView {
|
|||
OC_Log::write('core','invalid mode ('.$mode.') for '.$path,OC_Log::ERROR);
|
||||
}
|
||||
|
||||
return $this->basicOperation('fopen',$path,$hooks,$mode);
|
||||
return $this->basicOperation('fopen', $path, $hooks, $mode);
|
||||
}
|
||||
public function toTmpFile($path){
|
||||
if(OC_Filesystem::isValidPath($path)){
|
||||
$source=$this->fopen($path,'r');
|
||||
if($source){
|
||||
public function toTmpFile($path) {
|
||||
if(OC_Filesystem::isValidPath($path)) {
|
||||
$source = $this->fopen($path, 'r');
|
||||
if($source) {
|
||||
$extension='';
|
||||
$extOffset=strpos($path,'.');
|
||||
$extOffset=strpos($path, '.');
|
||||
if($extOffset !== false) {
|
||||
$extension=substr($path,strrpos($path,'.'));
|
||||
$extension=substr($path, strrpos($path,'.'));
|
||||
}
|
||||
$tmpFile=OC_Helper::tmpFile($extension);
|
||||
file_put_contents($tmpFile,$source);
|
||||
$tmpFile = OC_Helper::tmpFile($extension);
|
||||
file_put_contents($tmpFile, $source);
|
||||
return $tmpFile;
|
||||
}
|
||||
}
|
||||
}
|
||||
public function fromTmpFile($tmpFile,$path){
|
||||
if(OC_Filesystem::isValidPath($path)){
|
||||
if(!$tmpFile){
|
||||
public function fromTmpFile($tmpFile, $path) {
|
||||
if(OC_Filesystem::isValidPath($path)) {
|
||||
if(!$tmpFile) {
|
||||
debug_print_backtrace();
|
||||
}
|
||||
$source=fopen($tmpFile,'r');
|
||||
if($source){
|
||||
$this->file_put_contents($path,$source);
|
||||
$source=fopen($tmpFile, 'r');
|
||||
if($source) {
|
||||
$this->file_put_contents($path, $source);
|
||||
unlink($tmpFile);
|
||||
return true;
|
||||
}else{
|
||||
} else {
|
||||
}
|
||||
}else{
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public function getMimeType($path){
|
||||
return $this->basicOperation('getMimeType',$path);
|
||||
public function getMimeType($path) {
|
||||
return $this->basicOperation('getMimeType', $path);
|
||||
}
|
||||
public function hash($type,$path){
|
||||
return $this->basicOperation('hash',$path,array('read'),$type);
|
||||
public function hash($type, $path) {
|
||||
return $this->basicOperation('hash', $path, array('read'), $type);
|
||||
}
|
||||
|
||||
public function free_space($path='/'){
|
||||
return $this->basicOperation('free_space',$path);
|
||||
public function free_space($path='/') {
|
||||
return $this->basicOperation('free_space', $path);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -407,41 +480,56 @@ class OC_FilesystemView {
|
|||
* @param array (optional) hooks
|
||||
* @param mixed (optional) $extraParam
|
||||
* @return mixed
|
||||
*
|
||||
* This method takes requests for basic filesystem functions (e.g. reading & writing
|
||||
* files), processes hooks and proxies, sanitises paths, and finally passes them on to
|
||||
*
|
||||
* This method takes requests for basic filesystem functions (e.g. reading & writing
|
||||
* files), processes hooks and proxies, sanitises paths, and finally passes them on to
|
||||
* OC_Filestorage for delegation to a storage backend for execution
|
||||
*/
|
||||
private function basicOperation($operation,$path,$hooks=array(),$extraParam=null){
|
||||
$absolutePath=$this->getAbsolutePath($path);
|
||||
if(OC_FileProxy::runPreProxies($operation,$absolutePath, $extraParam) and OC_Filesystem::isValidPath($path)){
|
||||
$path=$this->getRelativePath($absolutePath);
|
||||
if($path==null){
|
||||
private function basicOperation($operation, $path, $hooks=array(), $extraParam=null) {
|
||||
$absolutePath = $this->getAbsolutePath($path);
|
||||
if(OC_FileProxy::runPreProxies($operation, $absolutePath, $extraParam) and OC_Filesystem::isValidPath($path)) {
|
||||
$path = $this->getRelativePath($absolutePath);
|
||||
if($path == null) {
|
||||
return false;
|
||||
}
|
||||
$internalPath=$this->getInternalPath($path);
|
||||
$run=true;
|
||||
if(OC_Filesystem::$loaded and $this->fakeRoot==OC_Filesystem::getRoot()){
|
||||
foreach($hooks as $hook){
|
||||
if($hook!='read'){
|
||||
OC_Hook::emit( OC_Filesystem::CLASSNAME, $hook, array( OC_Filesystem::signal_param_path => $path, OC_Filesystem::signal_param_run => &$run));
|
||||
}else{
|
||||
OC_Hook::emit( OC_Filesystem::CLASSNAME, $hook, array( OC_Filesystem::signal_param_path => $path));
|
||||
$internalPath = $this->getInternalPath($path);
|
||||
$run = true;
|
||||
if(OC_Filesystem::$loaded and $this->fakeRoot==OC_Filesystem::getRoot()) {
|
||||
foreach($hooks as $hook) {
|
||||
if($hook!='read') {
|
||||
OC_Hook::emit(
|
||||
OC_Filesystem::CLASSNAME,
|
||||
$hook,
|
||||
array(
|
||||
OC_Filesystem::signal_param_path => $path,
|
||||
OC_Filesystem::signal_param_run => &$run
|
||||
)
|
||||
);
|
||||
} else {
|
||||
OC_Hook::emit(
|
||||
OC_Filesystem::CLASSNAME,
|
||||
$hook,
|
||||
array( OC_Filesystem::signal_param_path => $path)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
if($run and $storage=$this->getStorage($path)){
|
||||
if(!is_null($extraParam)){
|
||||
$result=$storage->$operation($internalPath,$extraParam);
|
||||
}else{
|
||||
$result=$storage->$operation($internalPath);
|
||||
if($run and $storage = $this->getStorage($path)) {
|
||||
if(!is_null($extraParam)) {
|
||||
$result = $storage->$operation($internalPath, $extraParam);
|
||||
} else {
|
||||
$result = $storage->$operation($internalPath);
|
||||
}
|
||||
$result=OC_FileProxy::runPostProxies($operation,$this->getAbsolutePath($path),$result);
|
||||
if(OC_Filesystem::$loaded and $this->fakeRoot==OC_Filesystem::getRoot()){
|
||||
if($operation!='fopen'){//no post hooks for fopen, the file stream is still open
|
||||
foreach($hooks as $hook){
|
||||
$result = OC_FileProxy::runPostProxies($operation, $this->getAbsolutePath($path), $result);
|
||||
if(OC_Filesystem::$loaded and $this->fakeRoot==OC_Filesystem::getRoot()) {
|
||||
if($operation!='fopen') {//no post hooks for fopen, the file stream is still open
|
||||
foreach($hooks as $hook) {
|
||||
if($hook!='read'){
|
||||
OC_Hook::emit( OC_Filesystem::CLASSNAME, 'post_'.$hook, array( OC_Filesystem::signal_param_path => $path));
|
||||
OC_Hook::emit(
|
||||
OC_Filesystem::CLASSNAME,
|
||||
'post_'.$hook,
|
||||
array( OC_Filesystem::signal_param_path => $path)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -457,7 +545,7 @@ class OC_FilesystemView {
|
|||
* @param int $time
|
||||
* @return bool
|
||||
*/
|
||||
public function hasUpdated($path,$time){
|
||||
return $this->basicOperation('hasUpdated',$path,array(),$time);
|
||||
public function hasUpdated($path, $time) {
|
||||
return $this->basicOperation('hasUpdated', $path, array(), $time);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -175,10 +175,8 @@ class OC_Helper {
|
|||
*/
|
||||
public static function mimetypeIcon( $mimetype ){
|
||||
$alias=array('application/xml'=>'code/xml');
|
||||
// echo $mimetype;
|
||||
if(isset($alias[$mimetype])){
|
||||
$mimetype=$alias[$mimetype];
|
||||
// echo $mimetype;
|
||||
}
|
||||
// Replace slash with a minus
|
||||
$mimetype = str_replace( "/", "-", $mimetype );
|
||||
|
@ -345,18 +343,24 @@ class OC_Helper {
|
|||
*/
|
||||
static function getMimeType($path){
|
||||
$isWrapped=(strpos($path,'://')!==false) and (substr($path,0,7)=='file://');
|
||||
$mimeType='application/octet-stream';
|
||||
if ($mimeType=='application/octet-stream') {
|
||||
self::$mimetypes = include('mimetypes.fixlist.php');
|
||||
$extension=strtolower(strrchr(basename($path), "."));
|
||||
$extension=substr($extension,1);//remove leading .
|
||||
$mimeType=(isset(self::$mimetypes[$extension]))?self::$mimetypes[$extension]:'application/octet-stream';
|
||||
|
||||
}
|
||||
if (@is_dir($path)) {
|
||||
// directories are easy
|
||||
return "httpd/unix-directory";
|
||||
}
|
||||
|
||||
if(strpos($path,'.')){
|
||||
//try to guess the type by the file extension
|
||||
if(!self::$mimetypes || self::$mimetypes != include('mimetypes.list.php')){
|
||||
self::$mimetypes=include('mimetypes.list.php');
|
||||
}
|
||||
$extension=strtolower(strrchr(basename($path), "."));
|
||||
$extension=substr($extension,1);//remove leading .
|
||||
$mimeType=(isset(self::$mimetypes[$extension]))?self::$mimetypes[$extension]:'application/octet-stream';
|
||||
}else{
|
||||
$mimeType='application/octet-stream';
|
||||
}
|
||||
|
||||
if($mimeType=='application/octet-stream' and function_exists('finfo_open') and function_exists('finfo_file') and $finfo=finfo_open(FILEINFO_MIME)){
|
||||
$info = @strtolower(finfo_file($finfo,$path));
|
||||
if($info){
|
||||
|
@ -385,15 +389,6 @@ class OC_Helper {
|
|||
}
|
||||
|
||||
}
|
||||
if ($mimeType=='application/octet-stream') {
|
||||
// Fallback solution: (try to guess the type by the file extension
|
||||
if(!self::$mimetypes || self::$mimetypes != include('mimetypes.list.php')){
|
||||
self::$mimetypes=include('mimetypes.list.php');
|
||||
}
|
||||
$extension=strtolower(strrchr(basename($path), "."));
|
||||
$extension=substr($extension,1);//remove leading .
|
||||
$mimeType=(isset(self::$mimetypes[$extension]))?self::$mimetypes[$extension]:'application/octet-stream';
|
||||
}
|
||||
return $mimeType;
|
||||
}
|
||||
|
||||
|
|
|
@ -23,12 +23,12 @@
|
|||
|
||||
//From user comments at http://dk2.php.net/manual/en/function.exif-imagetype.php
|
||||
if ( ! function_exists( 'exif_imagetype' ) ) {
|
||||
function exif_imagetype ( $filename ) {
|
||||
if ( ( $info = getimagesize( $filename ) ) !== false ) {
|
||||
return $info[2];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
function exif_imagetype ( $filename ) {
|
||||
if ( ( $info = getimagesize( $filename ) ) !== false ) {
|
||||
return $info[2];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function ellipsis($str, $maxlen) {
|
||||
|
@ -66,7 +66,6 @@ class OC_Image {
|
|||
public function __construct($imageref = null) {
|
||||
//OC_Log::write('core',__METHOD__.'(): start', OC_Log::DEBUG);
|
||||
if(!extension_loaded('gd') || !function_exists('gd_info')) {
|
||||
//if(!function_exists('imagecreatefromjpeg')) {
|
||||
OC_Log::write('core',__METHOD__.'(): GD module not installed', OC_Log::ERROR);
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -126,19 +126,19 @@ class OC_Installer{
|
|||
return false;
|
||||
}
|
||||
$info=OC_App::getAppInfo($extractDir.'/appinfo/info.xml',true);
|
||||
// check the code for not allowed calls
|
||||
if(!OC_Installer::checkCode($info['id'],$extractDir)){
|
||||
// check the code for not allowed calls
|
||||
if(!OC_Installer::checkCode($info['id'],$extractDir)){
|
||||
OC_Log::write('core','App can\'t be installed because of not allowed code in the App',OC_Log::ERROR);
|
||||
OC_Helper::rmdirr($extractDir);
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
// check if the app is compatible with this version of ownCloud
|
||||
// check if the app is compatible with this version of ownCloud
|
||||
$version=OC_Util::getVersion();
|
||||
if(!isset($info['require']) or ($version[0]>$info['require'])){
|
||||
if(!isset($info['require']) or ($version[0]>$info['require'])){
|
||||
OC_Log::write('core','App can\'t be installed because it is not compatible with this version of ownCloud',OC_Log::ERROR);
|
||||
OC_Helper::rmdirr($extractDir);
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
//check if an app with the same id is already installed
|
||||
|
@ -339,12 +339,12 @@ class OC_Installer{
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* check the code of an app with some static code checks
|
||||
* @param string $folder the folder of the app to check
|
||||
* @returns true for app is o.k. and false for app is not o.k.
|
||||
*/
|
||||
public static function checkCode($appname,$folder){
|
||||
/**
|
||||
* check the code of an app with some static code checks
|
||||
* @param string $folder the folder of the app to check
|
||||
* @returns true for app is o.k. and false for app is not o.k.
|
||||
*/
|
||||
public static function checkCode($appname,$folder){
|
||||
|
||||
$blacklist=array(
|
||||
'exec(',
|
||||
|
@ -377,9 +377,7 @@ class OC_Installer{
|
|||
return true;
|
||||
|
||||
}else{
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
14
lib/json.php
14
lib/json.php
|
@ -94,12 +94,12 @@ class OC_JSON{
|
|||
* Encode and print $data in json format
|
||||
*/
|
||||
public static function encodedPrint($data,$setContentType=true){
|
||||
// Disable mimesniffing, don't move this to setContentTypeHeader!
|
||||
header( 'X-Content-Type-Options: nosniff' );
|
||||
if($setContentType){
|
||||
self::setContentTypeHeader();
|
||||
}
|
||||
array_walk_recursive($data, array('OC_JSON', 'to_string'));
|
||||
echo json_encode($data);
|
||||
// Disable mimesniffing, don't move this to setContentTypeHeader!
|
||||
header( 'X-Content-Type-Options: nosniff' );
|
||||
if($setContentType){
|
||||
self::setContentTypeHeader();
|
||||
}
|
||||
array_walk_recursive($data, array('OC_JSON', 'to_string'));
|
||||
echo json_encode($data);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,22 +0,0 @@
|
|||
<?php
|
||||
return array(
|
||||
'ics'=>'text/calendar',
|
||||
'ical'=>'text/calendar',
|
||||
'js'=>'application/javascript',
|
||||
'odt'=>'application/vnd.oasis.opendocument.text',
|
||||
'ods'=>'application/vnd.oasis.opendocument.spreadsheet',
|
||||
'odg'=>'application/vnd.oasis.opendocument.graphics',
|
||||
'odp'=>'application/vnd.oasis.opendocument.presentation',
|
||||
'pl'=>'text/x-script.perl',
|
||||
'py'=>'text/x-script.phyton',
|
||||
'vcf' => 'text/vcard',
|
||||
'vcard' => 'text/vcard',
|
||||
'doc'=>'application/msword',
|
||||
'docx'=>'application/msword',
|
||||
'xls'=>'application/msexcel',
|
||||
'xlsx'=>'application/msexcel',
|
||||
'ppt'=>'application/mspowerpoint',
|
||||
'pptx'=>'application/mspowerpoint',
|
||||
'sgf' => 'application/sgf',
|
||||
'cdr' => 'application/coreldraw'
|
||||
);
|
|
@ -78,5 +78,16 @@ return array(
|
|||
'mpeg'=>'video/mpeg',
|
||||
'mov'=>'video/quicktime',
|
||||
'webm'=>'video/webm',
|
||||
'wmv'=>'video/x-ms-asf'
|
||||
'wmv'=>'video/x-ms-asf',
|
||||
'py'=>'text/x-script.phyton',
|
||||
'vcf' => 'text/vcard',
|
||||
'vcard' => 'text/vcard',
|
||||
'doc'=>'application/msword',
|
||||
'docx'=>'application/msword',
|
||||
'xls'=>'application/msexcel',
|
||||
'xlsx'=>'application/msexcel',
|
||||
'ppt'=>'application/mspowerpoint',
|
||||
'pptx'=>'application/mspowerpoint',
|
||||
'sgf' => 'application/sgf',
|
||||
'cdr' => 'application/coreldraw',
|
||||
);
|
||||
|
|
|
@ -46,3 +46,13 @@ abstract class OC_Minimizer {
|
|||
echo $out;
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('gzdecode')) {
|
||||
function gzdecode($data,$maxlength=null,&$filename='',&$error='')
|
||||
{
|
||||
if (strcmp(substr($data,0,9),"\x1f\x8b\x8\0\0\0\0\0\0")) {
|
||||
return null; // Not the GZIP format we expect (See RFC 1952)
|
||||
}
|
||||
return gzinflate(substr($data,10,-8));
|
||||
}
|
||||
}
|
||||
|
|
890
lib/ocs.php
890
lib/ocs.php
|
@ -4,7 +4,9 @@
|
|||
* ownCloud
|
||||
*
|
||||
* @author Frank Karlitschek
|
||||
* @author Michael Gapczynski
|
||||
* @copyright 2012 Frank Karlitschek frank@owncloud.org
|
||||
* @copyright 2012 Michael Gapczynski mtgap@owncloud.com
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
|
@ -27,431 +29,476 @@
|
|||
*/
|
||||
class OC_OCS {
|
||||
|
||||
/**
|
||||
* reads input date from get/post/cookies and converts the date to a special data-type
|
||||
*
|
||||
* @param variable $key
|
||||
* @param variable-type $type
|
||||
* @param priority $getpriority
|
||||
* @param default $default
|
||||
* @return data
|
||||
*/
|
||||
public static function readData($key,$type='raw',$getpriority=false,$default='') {
|
||||
if($getpriority) {
|
||||
if(isset($_GET[$key])) {
|
||||
$data=$_GET[$key];
|
||||
} elseif(isset($_POST[$key])) {
|
||||
$data=$_POST[$key];
|
||||
} else {
|
||||
if($default=='') {
|
||||
if(($type=='int') or ($type=='float')) $data=0; else $data='';
|
||||
} else {
|
||||
$data=$default;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if(isset($_POST[$key])) {
|
||||
$data=$_POST[$key];
|
||||
} elseif(isset($_GET[$key])) {
|
||||
$data=$_GET[$key];
|
||||
} elseif(isset($_COOKIE[$key])) {
|
||||
$data=$_COOKIE[$key];
|
||||
} else {
|
||||
if($default=='') {
|
||||
if(($type=='int') or ($type=='float')) $data=0; else $data='';
|
||||
} else {
|
||||
$data=$default;
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* reads input date from get/post/cookies and converts the date to a special data-type
|
||||
*
|
||||
* @param string HTTP method to read the key from
|
||||
* @param string Parameter to read
|
||||
* @param string Variable type to format data
|
||||
* @param mixed Default value to return if the key is not found
|
||||
* @return mixed Data or if the key is not found and no default is set it will exit with a 400 Bad request
|
||||
*/
|
||||
public static function readData($method, $key, $type = 'raw', $default = null) {
|
||||
if ($method == 'get') {
|
||||
if (isset($_GET[$key])) {
|
||||
$data = $_GET[$key];
|
||||
} else if (isset($default)) {
|
||||
return $default;
|
||||
} else {
|
||||
$data = false;
|
||||
}
|
||||
} else if ($method == 'post') {
|
||||
if (isset($_POST[$key])) {
|
||||
$data = $_POST[$key];
|
||||
} else if (isset($default)) {
|
||||
return $default;
|
||||
} else {
|
||||
$data = false;
|
||||
}
|
||||
}
|
||||
if ($data === false) {
|
||||
echo self::generateXml('', 'fail', 400, 'Bad request. Please provide a valid '.$key);
|
||||
exit();
|
||||
} else {
|
||||
// NOTE: Is the raw type necessary? It might be a little risky without sanitization
|
||||
if ($type == 'raw') return $data;
|
||||
elseif ($type == 'text') return OC_Util::sanitizeHTML($data);
|
||||
elseif ($type == 'int') return (int) $data;
|
||||
elseif ($type == 'float') return (float) $data;
|
||||
elseif ($type == 'array') return OC_Util::sanitizeHTML($data);
|
||||
else return OC_Util::sanitizeHTML($data);
|
||||
}
|
||||
}
|
||||
|
||||
if($type=='raw') return($data);
|
||||
elseif($type=='text') return(addslashes(strip_tags($data)));
|
||||
elseif($type=='int') { $data = (int) $data; return($data); }
|
||||
elseif($type=='float') { $data = (float) $data; return($data); }
|
||||
elseif($type=='array') { $data = $data; return($data); }
|
||||
}
|
||||
/**
|
||||
main function to handle the REST request
|
||||
**/
|
||||
public static function handle() {
|
||||
// overwrite the 404 error page returncode
|
||||
header("HTTP/1.0 200 OK");
|
||||
|
||||
|
||||
/**
|
||||
main function to handle the REST request
|
||||
**/
|
||||
public static function handle() {
|
||||
if($_SERVER['REQUEST_METHOD'] == 'GET') {
|
||||
$method='get';
|
||||
}elseif($_SERVER['REQUEST_METHOD'] == 'PUT') {
|
||||
$method='put';
|
||||
parse_str(file_get_contents("php://input"),$put_vars);
|
||||
}elseif($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||
$method='post';
|
||||
}else{
|
||||
echo('internal server error: method not supported');
|
||||
exit();
|
||||
}
|
||||
|
||||
// overwrite the 404 error page returncode
|
||||
header("HTTP/1.0 200 OK");
|
||||
// preprocess url
|
||||
$url = strtolower($_SERVER['REQUEST_URI']);
|
||||
$format = self::readData($method, 'format', 'text', '');
|
||||
|
||||
$router = new OC_Router();
|
||||
$router->useCollection('ocs');
|
||||
// CONFIG
|
||||
$router->create('config', '/config.{format}')
|
||||
->defaults(array('format'=>''))
|
||||
->action('OC_OCS', 'apiConfig')
|
||||
->requirements(array('format'=>'xml|json'));
|
||||
$router = new OC_Router();
|
||||
$router->useCollection('ocs');
|
||||
// CONFIG
|
||||
$router->create('config', '/config.{format}')
|
||||
->defaults(array('format' => $format))
|
||||
->action('OC_OCS', 'apiConfig')
|
||||
->requirements(array('format'=>'xml|json'));
|
||||
|
||||
// PERSON
|
||||
$router->create('person_check', '/person/check.{format}')
|
||||
->post()
|
||||
->defaults(array('format'=>''))
|
||||
->action(function ($parameters) {
|
||||
$format = $parameters['format'] ? $parameters['format'] : OC_OCS::readdata('format','text');
|
||||
$login=OC_OCS::readdata('login','text');
|
||||
$passwd=OC_OCS::readdata('password','text');
|
||||
OC_OCS::personcheck($format,$login,$passwd);
|
||||
})
|
||||
->requirements(array('format'=>'xml|json'));
|
||||
// PERSON
|
||||
$router->create('person_check', '/person/check.{format}')
|
||||
->post()
|
||||
->defaults(array('format' => $format))
|
||||
->action(function ($parameters) {
|
||||
$format = $parameters['format'];
|
||||
$login = OC_OCS::readData('post', 'login', 'text');
|
||||
$passwd = OC_OCS::readData('post', 'password', 'text');
|
||||
OC_OCS::personCheck($format,$login,$passwd);
|
||||
})
|
||||
->requirements(array('format'=>'xml|json'));
|
||||
|
||||
// ACTIVITY
|
||||
// activityget - GET ACTIVITY page,pagesize als urlparameter
|
||||
$router->create('activity_get', '/activity.{format}')
|
||||
->defaults(array('format'=>''))
|
||||
->action(function ($parameters) {
|
||||
$format = $parameters['format'] ? $parameters['format'] : OC_OCS::readdata('format','text');
|
||||
$page=OC_OCS::readdata('page','int');
|
||||
$pagesize=OC_OCS::readdata('pagesize','int');
|
||||
if($pagesize<1 or $pagesize>100) $pagesize=10;
|
||||
OC_OCS::activityget($format,$page,$pagesize);
|
||||
})
|
||||
->requirements(array('format'=>'xml|json'));
|
||||
// activityput - POST ACTIVITY
|
||||
$router->create('activity_put', '/activity.{format}')
|
||||
->post()
|
||||
->defaults(array('format'=>''))
|
||||
->action(function ($parameters) {
|
||||
$format = $parameters['format'] ? $parameters['format'] : OC_OCS::readdata('format','text');
|
||||
$message=OC_OCS::readdata('message','text');
|
||||
OC_OCS::activityput($format,$message);
|
||||
})
|
||||
->requirements(array('format'=>'xml|json'));
|
||||
// ACTIVITY
|
||||
// activityget - GET ACTIVITY page,pagesize als urlparameter
|
||||
$router->create('activity_get', '/activity.{format}')
|
||||
->defaults(array('format' => $format))
|
||||
->action(function ($parameters) {
|
||||
$format = $parameters['format'];
|
||||
$page = OC_OCS::readData('get', 'page', 'int', 0);
|
||||
$pagesize = OC_OCS::readData('get', 'pagesize', 'int', 10);
|
||||
if($pagesize<1 or $pagesize>100) $pagesize=10;
|
||||
OC_OCS::activityGet($format, $page, $pagesize);
|
||||
})
|
||||
->requirements(array('format'=>'xml|json'));
|
||||
// activityput - POST ACTIVITY
|
||||
$router->create('activity_put', '/activity.{format}')
|
||||
->post()
|
||||
->defaults(array('format' => $format))
|
||||
->action(function ($parameters) {
|
||||
$format = $parameters['format'];
|
||||
$message = OC_OCS::readData('post', 'message', 'text');
|
||||
OC_OCS::activityPut($format,$message);
|
||||
})
|
||||
->requirements(array('format'=>'xml|json'));
|
||||
|
||||
// PRIVATEDATA
|
||||
// get - GET DATA
|
||||
$router->create('privatedata_get',
|
||||
'/privatedata/getattribute/{app}/{key}.{format}')
|
||||
->defaults(array('app' => '', 'key' => '', 'format' => ''))
|
||||
->action(function ($parameters) {
|
||||
$format = $parameters['format'] ? $parameters['format'] : OC_OCS::readdata('format','text');
|
||||
$app = addslashes(strip_tags($parameters['app']));
|
||||
$key = addslashes(strip_tags($parameters['key']));
|
||||
OC_OCS::privateDataGet($format, $app, $key);
|
||||
})
|
||||
->requirements(array('format'=>'xml|json'));
|
||||
// set - POST DATA
|
||||
$router->create('privatedata_set',
|
||||
'/privatedata/setattribute/{app}/{key}.{format}')
|
||||
->post()
|
||||
->defaults(array('format'=>''))
|
||||
->action(function ($parameters) {
|
||||
$format = $parameters['format'] ? $parameters['format'] : OC_OCS::readdata('format','text');
|
||||
$app = addslashes(strip_tags($parameters['app']));
|
||||
$key = addslashes(strip_tags($parameters['key']));
|
||||
$value=OC_OCS::readdata('value','text');
|
||||
OC_OCS::privateDataSet($format, $app, $key, $value);
|
||||
})
|
||||
->requirements(array('format'=>'xml|json'));
|
||||
// delete - POST DATA
|
||||
$router->create('privatedata_delete',
|
||||
'/privatedata/deleteattribute/{app}/{key}.{format}')
|
||||
->post()
|
||||
->defaults(array('format'=>''))
|
||||
->action(function ($parameters) {
|
||||
$format = $parameters['format'] ? $parameters['format'] : OC_OCS::readdata('format','text');
|
||||
$app = addslashes(strip_tags($parameters['app']));
|
||||
$key = addslashes(strip_tags($parameters['key']));
|
||||
OC_OCS::privateDataDelete($format, $app, $key);
|
||||
})
|
||||
->requirements(array('format'=>'xml|json'));
|
||||
// PRIVATEDATA
|
||||
// get - GET DATA
|
||||
$router->create('privatedata_get',
|
||||
'/privatedata/getattribute/{app}/{key}.{format}')
|
||||
->defaults(array('app' => '', 'key' => '', 'format' => $format))
|
||||
->action(function ($parameters) {
|
||||
$format = $parameters['format'];
|
||||
$app = addslashes(strip_tags($parameters['app']));
|
||||
$key = addslashes(strip_tags($parameters['key']));
|
||||
OC_OCS::privateDataGet($format, $app, $key);
|
||||
})
|
||||
->requirements(array('format'=>'xml|json'));
|
||||
// set - POST DATA
|
||||
$router->create('privatedata_set',
|
||||
'/privatedata/setattribute/{app}/{key}.{format}')
|
||||
->post()
|
||||
->defaults(array('format' => $format))
|
||||
->action(function ($parameters) {
|
||||
$format = $parameters['format'];
|
||||
$app = addslashes(strip_tags($parameters['app']));
|
||||
$key = addslashes(strip_tags($parameters['key']));
|
||||
$value=OC_OCS::readData('post', 'value', 'text');
|
||||
OC_OCS::privateDataSet($format, $app, $key, $value);
|
||||
})
|
||||
->requirements(array('format'=>'xml|json'));
|
||||
// delete - POST DATA
|
||||
$router->create('privatedata_delete',
|
||||
'/privatedata/deleteattribute/{app}/{key}.{format}')
|
||||
->post()
|
||||
->defaults(array('format' => $format))
|
||||
->action(function ($parameters) {
|
||||
$format = $parameters['format'];
|
||||
$app = addslashes(strip_tags($parameters['app']));
|
||||
$key = addslashes(strip_tags($parameters['key']));
|
||||
OC_OCS::privateDataDelete($format, $app, $key);
|
||||
})
|
||||
->requirements(array('format'=>'xml|json'));
|
||||
|
||||
try {
|
||||
$router->match($_SERVER['PATH_INFO']);
|
||||
} catch (ResourceNotFoundException $e) {
|
||||
$format=OC_OCS::readdata('format','text');
|
||||
$txt='Invalid query, please check the syntax. API specifications are here: http://www.freedesktop.org/wiki/Specifications/open-collaboration-services. DEBUG OUTPUT:'."\n";
|
||||
$txt.=OC_OCS::getdebugoutput();
|
||||
echo(OC_OCS::generatexml($format,'failed',999,$txt));
|
||||
}
|
||||
exit();
|
||||
}
|
||||
|
||||
/**
|
||||
* generated some debug information to make it easier to find faild API calls
|
||||
* @return debug data string
|
||||
*/
|
||||
private static function getDebugOutput() {
|
||||
$txt='';
|
||||
$txt.="debug output:\n";
|
||||
if(isset($_SERVER['REQUEST_METHOD'])) $txt.='http request method: '.$_SERVER['REQUEST_METHOD']."\n";
|
||||
if(isset($_SERVER['REQUEST_URI'])) $txt.='http request uri: '.$_SERVER['REQUEST_URI']."\n";
|
||||
if(isset($_GET)) foreach($_GET as $key=>$value) $txt.='get parameter: '.$key.'->'.$value."\n";
|
||||
if(isset($_POST)) foreach($_POST as $key=>$value) $txt.='post parameter: '.$key.'->'.$value."\n";
|
||||
return($txt);
|
||||
}
|
||||
|
||||
/**
|
||||
* checks if the user is authenticated
|
||||
* checks the IP whitlist, apikeys and login/password combination
|
||||
* if $forceuser is true and the authentication failed it returns an 401 http response.
|
||||
* if $forceuser is false and authentification fails it returns an empty username string
|
||||
* @param bool $forceuser
|
||||
* @return username string
|
||||
*/
|
||||
private static function checkPassword($forceuser=true) {
|
||||
//valid user account ?
|
||||
if(isset($_SERVER['PHP_AUTH_USER'])) $authuser=$_SERVER['PHP_AUTH_USER']; else $authuser='';
|
||||
if(isset($_SERVER['PHP_AUTH_PW'])) $authpw=$_SERVER['PHP_AUTH_PW']; else $authpw='';
|
||||
|
||||
if(empty($authuser)) {
|
||||
if($forceuser){
|
||||
header('WWW-Authenticate: Basic realm="your valid user account or api key"');
|
||||
header('HTTP/1.0 401 Unauthorized');
|
||||
exit;
|
||||
}else{
|
||||
$identifieduser='';
|
||||
}
|
||||
}else{
|
||||
if(!OC_User::login($authuser,$authpw)){
|
||||
if($forceuser){
|
||||
header('WWW-Authenticate: Basic realm="your valid user account or api key"');
|
||||
header('HTTP/1.0 401 Unauthorized');
|
||||
exit;
|
||||
}else{
|
||||
$identifieduser='';
|
||||
}
|
||||
}else{
|
||||
$identifieduser=$authuser;
|
||||
}
|
||||
}
|
||||
|
||||
return($identifieduser);
|
||||
}
|
||||
// CLOUD
|
||||
// quotaget
|
||||
$router->create('quota_get',
|
||||
'/cloud/user/{user}.{format}')
|
||||
->defaults(array('format' => $format))
|
||||
->action(function ($parameters) {
|
||||
$format = $parameters['format'];
|
||||
$user = $parameters['user'];
|
||||
OC_OCS::quotaGet($format, $user);
|
||||
})
|
||||
->requirements(array('format'=>'xml|json'));
|
||||
// quotaset
|
||||
$router->create('quota_set',
|
||||
'/cloud/user/{user}.{format}')
|
||||
->post()
|
||||
->defaults(array('format' => $format))
|
||||
->action(function ($parameters) {
|
||||
$format = $parameters['format'];
|
||||
$user = $parameters['user'];
|
||||
$quota = self::readData('post', 'quota', 'int');
|
||||
OC_OCS::quotaSet($format, $user, $quota);
|
||||
})
|
||||
->requirements(array('format'=>'xml|json'));
|
||||
|
||||
|
||||
/**
|
||||
* generates the xml or json response for the API call from an multidimenional data array.
|
||||
* @param string $format
|
||||
* @param string $status
|
||||
* @param string $statuscode
|
||||
* @param string $message
|
||||
* @param array $data
|
||||
* @param string $tag
|
||||
* @param string $tagattribute
|
||||
* @param int $dimension
|
||||
* @param int $itemscount
|
||||
* @param int $itemsperpage
|
||||
* @return string xml/json
|
||||
*/
|
||||
private static function generateXml($format,$status,$statuscode,$message,$data=array(),$tag='',$tagattribute='',$dimension=-1,$itemscount='',$itemsperpage='') {
|
||||
if($format=='json') {
|
||||
// add more calls here
|
||||
// please document all the call in the draft spec
|
||||
// http://www.freedesktop.org/wiki/Specifications/open-collaboration-services-1.7#CLOUD
|
||||
|
||||
$json=array();
|
||||
$json['status']=$status;
|
||||
$json['statuscode']=$statuscode;
|
||||
$json['message']=$message;
|
||||
$json['totalitems']=$itemscount;
|
||||
$json['itemsperpage']=$itemsperpage;
|
||||
$json['data']=$data;
|
||||
return(json_encode($json));
|
||||
// TODO:
|
||||
// users
|
||||
// groups
|
||||
// bookmarks
|
||||
// sharing
|
||||
// versioning
|
||||
// news (rss)
|
||||
try {
|
||||
$router->match($_SERVER['PATH_INFO']);
|
||||
} catch (ResourceNotFoundException $e) {
|
||||
$txt='Invalid query, please check the syntax. API specifications are here: http://www.freedesktop.org/wiki/Specifications/open-collaboration-services. DEBUG OUTPUT:'."\n";
|
||||
$txt.=OC_OCS::getdebugoutput();
|
||||
echo(OC_OCS::generatexml($format,'failed',999,$txt));
|
||||
}
|
||||
exit();
|
||||
}
|
||||
|
||||
/**
|
||||
* generated some debug information to make it easier to find faild API calls
|
||||
* @return debug data string
|
||||
*/
|
||||
private static function getDebugOutput() {
|
||||
$txt='';
|
||||
$txt.="debug output:\n";
|
||||
if(isset($_SERVER['REQUEST_METHOD'])) $txt.='http request method: '.$_SERVER['REQUEST_METHOD']."\n";
|
||||
if(isset($_SERVER['REQUEST_URI'])) $txt.='http request uri: '.$_SERVER['REQUEST_URI']."\n";
|
||||
if(isset($_GET)) foreach($_GET as $key=>$value) $txt.='get parameter: '.$key.'->'.$value."\n";
|
||||
if(isset($_POST)) foreach($_POST as $key=>$value) $txt.='post parameter: '.$key.'->'.$value."\n";
|
||||
return($txt);
|
||||
}
|
||||
|
||||
/**
|
||||
* checks if the user is authenticated
|
||||
* checks the IP whitlist, apikeys and login/password combination
|
||||
* if $forceuser is true and the authentication failed it returns an 401 http response.
|
||||
* if $forceuser is false and authentification fails it returns an empty username string
|
||||
* @param bool $forceuser
|
||||
* @return username string
|
||||
*/
|
||||
private static function checkPassword($forceuser=true) {
|
||||
//valid user account ?
|
||||
if(isset($_SERVER['PHP_AUTH_USER'])) $authuser=$_SERVER['PHP_AUTH_USER']; else $authuser='';
|
||||
if(isset($_SERVER['PHP_AUTH_PW'])) $authpw=$_SERVER['PHP_AUTH_PW']; else $authpw='';
|
||||
|
||||
if(empty($authuser)) {
|
||||
if($forceuser){
|
||||
header('WWW-Authenticate: Basic realm="your valid user account or api key"');
|
||||
header('HTTP/1.0 401 Unauthorized');
|
||||
exit;
|
||||
}else{
|
||||
$identifieduser='';
|
||||
}
|
||||
}else{
|
||||
if(!OC_User::login($authuser,$authpw)){
|
||||
if($forceuser){
|
||||
header('WWW-Authenticate: Basic realm="your valid user account or api key"');
|
||||
header('HTTP/1.0 401 Unauthorized');
|
||||
exit;
|
||||
}else{
|
||||
$identifieduser='';
|
||||
}
|
||||
}else{
|
||||
$identifieduser=$authuser;
|
||||
}
|
||||
}
|
||||
|
||||
return($identifieduser);
|
||||
}
|
||||
|
||||
|
||||
}else{
|
||||
$txt='';
|
||||
$writer = xmlwriter_open_memory();
|
||||
xmlwriter_set_indent( $writer, 2 );
|
||||
xmlwriter_start_document($writer );
|
||||
xmlwriter_start_element($writer,'ocs');
|
||||
xmlwriter_start_element($writer,'meta');
|
||||
xmlwriter_write_element($writer,'status',$status);
|
||||
xmlwriter_write_element($writer,'statuscode',$statuscode);
|
||||
xmlwriter_write_element($writer,'message',$message);
|
||||
if($itemscount<>'') xmlwriter_write_element($writer,'totalitems',$itemscount);
|
||||
if(!empty($itemsperpage)) xmlwriter_write_element($writer,'itemsperpage',$itemsperpage);
|
||||
xmlwriter_end_element($writer);
|
||||
if($dimension=='0') {
|
||||
// 0 dimensions
|
||||
xmlwriter_write_element($writer,'data',$data);
|
||||
/**
|
||||
* generates the xml or json response for the API call from an multidimenional data array.
|
||||
* @param string $format
|
||||
* @param string $status
|
||||
* @param string $statuscode
|
||||
* @param string $message
|
||||
* @param array $data
|
||||
* @param string $tag
|
||||
* @param string $tagattribute
|
||||
* @param int $dimension
|
||||
* @param int $itemscount
|
||||
* @param int $itemsperpage
|
||||
* @return string xml/json
|
||||
*/
|
||||
private static function generateXml($format,$status,$statuscode,$message,$data=array(),$tag='',$tagattribute='',$dimension=-1,$itemscount='',$itemsperpage='') {
|
||||
if($format=='json') {
|
||||
$json=array();
|
||||
$json['status']=$status;
|
||||
$json['statuscode']=$statuscode;
|
||||
$json['message']=$message;
|
||||
$json['totalitems']=$itemscount;
|
||||
$json['itemsperpage']=$itemsperpage;
|
||||
$json['data']=$data;
|
||||
return(json_encode($json));
|
||||
}else{
|
||||
$txt='';
|
||||
$writer = xmlwriter_open_memory();
|
||||
xmlwriter_set_indent( $writer, 2 );
|
||||
xmlwriter_start_document($writer );
|
||||
xmlwriter_start_element($writer,'ocs');
|
||||
xmlwriter_start_element($writer,'meta');
|
||||
xmlwriter_write_element($writer,'status',$status);
|
||||
xmlwriter_write_element($writer,'statuscode',$statuscode);
|
||||
xmlwriter_write_element($writer,'message',$message);
|
||||
if($itemscount<>'') xmlwriter_write_element($writer,'totalitems',$itemscount);
|
||||
if(!empty($itemsperpage)) xmlwriter_write_element($writer,'itemsperpage',$itemsperpage);
|
||||
xmlwriter_end_element($writer);
|
||||
if($dimension=='0') {
|
||||
// 0 dimensions
|
||||
xmlwriter_write_element($writer,'data',$data);
|
||||
|
||||
}elseif($dimension=='1') {
|
||||
xmlwriter_start_element($writer,'data');
|
||||
foreach($data as $key=>$entry) {
|
||||
xmlwriter_write_element($writer,$key,$entry);
|
||||
}
|
||||
xmlwriter_end_element($writer);
|
||||
}elseif($dimension=='1') {
|
||||
xmlwriter_start_element($writer,'data');
|
||||
foreach($data as $key=>$entry) {
|
||||
xmlwriter_write_element($writer,$key,$entry);
|
||||
}
|
||||
xmlwriter_end_element($writer);
|
||||
|
||||
}elseif($dimension=='2') {
|
||||
xmlwriter_start_element($writer,'data');
|
||||
foreach($data as $entry) {
|
||||
xmlwriter_start_element($writer,$tag);
|
||||
if(!empty($tagattribute)) {
|
||||
xmlwriter_write_attribute($writer,'details',$tagattribute);
|
||||
}
|
||||
foreach($entry as $key=>$value) {
|
||||
if(is_array($value)){
|
||||
foreach($value as $k=>$v) {
|
||||
xmlwriter_write_element($writer,$k,$v);
|
||||
}
|
||||
} else {
|
||||
xmlwriter_write_element($writer,$key,$value);
|
||||
}
|
||||
}
|
||||
xmlwriter_end_element($writer);
|
||||
}
|
||||
xmlwriter_end_element($writer);
|
||||
}elseif($dimension=='2') {
|
||||
xmlwriter_start_element($writer,'data');
|
||||
foreach($data as $entry) {
|
||||
xmlwriter_start_element($writer,$tag);
|
||||
if(!empty($tagattribute)) {
|
||||
xmlwriter_write_attribute($writer,'details',$tagattribute);
|
||||
}
|
||||
foreach($entry as $key=>$value) {
|
||||
if(is_array($value)){
|
||||
foreach($value as $k=>$v) {
|
||||
xmlwriter_write_element($writer,$k,$v);
|
||||
}
|
||||
} else {
|
||||
xmlwriter_write_element($writer,$key,$value);
|
||||
}
|
||||
}
|
||||
xmlwriter_end_element($writer);
|
||||
}
|
||||
xmlwriter_end_element($writer);
|
||||
|
||||
}elseif($dimension=='3') {
|
||||
xmlwriter_start_element($writer,'data');
|
||||
foreach($data as $entrykey=>$entry) {
|
||||
xmlwriter_start_element($writer,$tag);
|
||||
if(!empty($tagattribute)) {
|
||||
xmlwriter_write_attribute($writer,'details',$tagattribute);
|
||||
}
|
||||
foreach($entry as $key=>$value) {
|
||||
if(is_array($value)){
|
||||
xmlwriter_start_element($writer,$entrykey);
|
||||
foreach($value as $k=>$v) {
|
||||
xmlwriter_write_element($writer,$k,$v);
|
||||
}
|
||||
xmlwriter_end_element($writer);
|
||||
} else {
|
||||
xmlwriter_write_element($writer,$key,$value);
|
||||
}
|
||||
}
|
||||
xmlwriter_end_element($writer);
|
||||
}
|
||||
xmlwriter_end_element($writer);
|
||||
}elseif($dimension=='dynamic') {
|
||||
xmlwriter_start_element($writer,'data');
|
||||
OC_OCS::toxml($writer,$data,'comment');
|
||||
xmlwriter_end_element($writer);
|
||||
}
|
||||
}elseif($dimension=='3') {
|
||||
xmlwriter_start_element($writer,'data');
|
||||
foreach($data as $entrykey=>$entry) {
|
||||
xmlwriter_start_element($writer,$tag);
|
||||
if(!empty($tagattribute)) {
|
||||
xmlwriter_write_attribute($writer,'details',$tagattribute);
|
||||
}
|
||||
foreach($entry as $key=>$value) {
|
||||
if(is_array($value)){
|
||||
xmlwriter_start_element($writer,$entrykey);
|
||||
foreach($value as $k=>$v) {
|
||||
xmlwriter_write_element($writer,$k,$v);
|
||||
}
|
||||
xmlwriter_end_element($writer);
|
||||
} else {
|
||||
xmlwriter_write_element($writer,$key,$value);
|
||||
}
|
||||
}
|
||||
xmlwriter_end_element($writer);
|
||||
}
|
||||
xmlwriter_end_element($writer);
|
||||
}elseif($dimension=='dynamic') {
|
||||
xmlwriter_start_element($writer,'data');
|
||||
OC_OCS::toxml($writer,$data,'comment');
|
||||
xmlwriter_end_element($writer);
|
||||
}
|
||||
|
||||
xmlwriter_end_element($writer);
|
||||
xmlwriter_end_element($writer);
|
||||
|
||||
xmlwriter_end_document( $writer );
|
||||
$txt.=xmlwriter_output_memory( $writer );
|
||||
unset($writer);
|
||||
return($txt);
|
||||
}
|
||||
}
|
||||
xmlwriter_end_document( $writer );
|
||||
$txt.=xmlwriter_output_memory( $writer );
|
||||
unset($writer);
|
||||
return($txt);
|
||||
}
|
||||
}
|
||||
|
||||
public static function toXml($writer,$data,$node) {
|
||||
foreach($data as $key => $value) {
|
||||
if (is_numeric($key)) {
|
||||
$key = $node;
|
||||
}
|
||||
if (is_array($value)){
|
||||
xmlwriter_start_element($writer,$key);
|
||||
OC_OCS::toxml($writer,$value,$node);
|
||||
xmlwriter_end_element($writer);
|
||||
}else{
|
||||
xmlwriter_write_element($writer,$key,$value);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public static function toXml($writer,$data,$node) {
|
||||
foreach($data as $key => $value) {
|
||||
if (is_numeric($key)) {
|
||||
$key = $node;
|
||||
}
|
||||
if (is_array($value)){
|
||||
xmlwriter_start_element($writer,$key);
|
||||
OC_OCS::toxml($writer,$value,$node);
|
||||
xmlwriter_end_element($writer);
|
||||
}else{
|
||||
xmlwriter_write_element($writer,$key,$value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* return the config data of this server
|
||||
* @param string $format
|
||||
* @return string xml/json
|
||||
*/
|
||||
public static function apiConfig($parameters) {
|
||||
$format = $parameters['format'] ? $parameters['format'] : OC_OCS::readdata('format','text');
|
||||
$xml['version']='1.5';
|
||||
$xml['website']='ownCloud';
|
||||
$xml['host']=OCP\Util::getServerHost();
|
||||
$xml['contact']='';
|
||||
$xml['ssl']='false';
|
||||
echo(OC_OCS::generatexml($format,'ok',100,'',$xml,'config','',1));
|
||||
}
|
||||
/**
|
||||
* return the config data of this server
|
||||
* @param string $format
|
||||
* @return string xml/json
|
||||
*/
|
||||
public static function apiConfig($parameters) {
|
||||
$format = $parameters['format'];
|
||||
$user=OC_OCS::checkpassword(false);
|
||||
$url=substr(OCP\Util::getServerHost().$_SERVER['SCRIPT_NAME'],0,-11).'';
|
||||
|
||||
$xml['version']='1.7';
|
||||
$xml['website']='ownCloud';
|
||||
$xml['host']=OCP\Util::getServerHost();
|
||||
$xml['contact']='';
|
||||
$xml['ssl']='false';
|
||||
echo(OC_OCS::generatexml($format,'ok',100,'',$xml,'config','',1));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* check if the provided login/apikey/password is valid
|
||||
* @param string $format
|
||||
* @param string $login
|
||||
* @param string $passwd
|
||||
* @return string xml/json
|
||||
*/
|
||||
private static function personCheck($format,$login,$passwd) {
|
||||
if($login<>''){
|
||||
if(OC_User::login($login,$passwd)){
|
||||
$xml['person']['personid']=$login;
|
||||
echo(OC_OCS::generatexml($format,'ok',100,'',$xml,'person','check',2));
|
||||
}else{
|
||||
echo(OC_OCS::generatexml($format,'failed',102,'login not valid'));
|
||||
}
|
||||
}else{
|
||||
echo(OC_OCS::generatexml($format,'failed',101,'please specify all mandatory fields'));
|
||||
}
|
||||
}
|
||||
/**
|
||||
* check if the provided login/apikey/password is valid
|
||||
* @param string $format
|
||||
* @param string $login
|
||||
* @param string $passwd
|
||||
* @return string xml/json
|
||||
*/
|
||||
private static function personCheck($format,$login,$passwd) {
|
||||
if($login<>''){
|
||||
if(OC_User::login($login,$passwd)){
|
||||
$xml['person']['personid']=$login;
|
||||
echo(OC_OCS::generatexml($format,'ok',100,'',$xml,'person','check',2));
|
||||
}else{
|
||||
echo(OC_OCS::generatexml($format,'failed',102,'login not valid'));
|
||||
}
|
||||
}else{
|
||||
echo(OC_OCS::generatexml($format,'failed',101,'please specify all mandatory fields'));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ACTIVITY API #############################################
|
||||
// ACTIVITY API #############################################
|
||||
|
||||
/**
|
||||
* get my activities
|
||||
* @param string $format
|
||||
* @param string $page
|
||||
* @param string $pagesize
|
||||
* @return string xml/json
|
||||
*/
|
||||
private static function activityGet($format,$page,$pagesize) {
|
||||
$user=OC_OCS::checkpassword();
|
||||
|
||||
//TODO
|
||||
/**
|
||||
* get my activities
|
||||
* @param string $format
|
||||
* @param string $page
|
||||
* @param string $pagesize
|
||||
* @return string xml/json
|
||||
*/
|
||||
private static function activityGet($format,$page,$pagesize) {
|
||||
$user=OC_OCS::checkpassword();
|
||||
|
||||
$txt=OC_OCS::generatexml($format,'ok',100,'',$xml,'activity','full',2,$totalcount,$pagesize);
|
||||
echo($txt);
|
||||
}
|
||||
//TODO
|
||||
|
||||
/**
|
||||
* submit a activity
|
||||
* @param string $format
|
||||
* @param string $message
|
||||
* @return string xml/json
|
||||
*/
|
||||
private static function activityPut($format,$message) {
|
||||
// not implemented in ownCloud
|
||||
OC_OCS::checkpassword();
|
||||
echo(OC_OCS::generatexml($format,'ok',100,''));
|
||||
}
|
||||
$txt=OC_OCS::generatexml($format,'ok',100,'',$xml,'activity','full',2,$totalcount,$pagesize);
|
||||
echo($txt);
|
||||
}
|
||||
|
||||
// PRIVATEDATA API #############################################
|
||||
/**
|
||||
* submit a activity
|
||||
* @param string $format
|
||||
* @param string $message
|
||||
* @return string xml/json
|
||||
*/
|
||||
private static function activityPut($format,$message) {
|
||||
// not implemented in ownCloud
|
||||
$user=OC_OCS::checkpassword();
|
||||
echo(OC_OCS::generatexml($format,'ok',100,''));
|
||||
}
|
||||
|
||||
/**
|
||||
* get private data and create the xml for ocs
|
||||
* @param string $format
|
||||
* @param string $app
|
||||
* @param string $key
|
||||
* @return string xml/json
|
||||
*/
|
||||
private static function privateDataGet($format,$app="",$key="") {
|
||||
$user=OC_OCS::checkpassword();
|
||||
$result=OC_OCS::getData($user,$app,$key);
|
||||
$xml=array();
|
||||
foreach($result as $i=>$log) {
|
||||
$xml[$i]['key']=$log['key'];
|
||||
$xml[$i]['app']=$log['app'];
|
||||
$xml[$i]['value']=$log['value'];
|
||||
}
|
||||
// PRIVATEDATA API #############################################
|
||||
|
||||
/**
|
||||
* get private data and create the xml for ocs
|
||||
* @param string $format
|
||||
* @param string $app
|
||||
* @param string $key
|
||||
* @return string xml/json
|
||||
*/
|
||||
private static function privateDataGet($format,$app="",$key="") {
|
||||
$user=OC_OCS::checkpassword();
|
||||
$result=OC_OCS::getData($user,$app,$key);
|
||||
$xml=array();
|
||||
foreach($result as $i=>$log) {
|
||||
$xml[$i]['key']=$log['key'];
|
||||
$xml[$i]['app']=$log['app'];
|
||||
$xml[$i]['value']=$log['value'];
|
||||
}
|
||||
|
||||
|
||||
$txt=OC_OCS::generatexml($format, 'ok', 100, '', $xml, 'privatedata', 'full', 2, count($xml), 0);//TODO: replace 'privatedata' with 'attribute' once a new libattice has been released that works with it
|
||||
echo($txt);
|
||||
}
|
||||
$txt=OC_OCS::generatexml($format, 'ok', 100, '', $xml, 'privatedata', 'full', 2, count($xml), 0);//TODO: replace 'privatedata' with 'attribute' once a new libattice has been released that works with it
|
||||
echo($txt);
|
||||
}
|
||||
|
||||
/**
|
||||
* set private data referenced by $key to $value and generate the xml for ocs
|
||||
* @param string $format
|
||||
* @param string $app
|
||||
* @param string $key
|
||||
* @param string $value
|
||||
* @return string xml/json
|
||||
*/
|
||||
/**
|
||||
* set private data referenced by $key to $value and generate the xml for ocs
|
||||
* @param string $format
|
||||
* @param string $app
|
||||
* @param string $key
|
||||
* @param string $value
|
||||
* @return string xml/json
|
||||
*/
|
||||
private static function privateDataSet($format, $app, $key, $value) {
|
||||
$user=OC_OCS::checkpassword();
|
||||
if(OC_OCS::setData($user,$app,$key,$value)){
|
||||
|
@ -529,4 +576,71 @@ class OC_OCS {
|
|||
public static function deleteData($user, $app, $key) {
|
||||
return OC_Preferences::deleteKey($user,$app,$key);
|
||||
}
|
||||
|
||||
|
||||
// CLOUD API #############################################
|
||||
|
||||
/**
|
||||
* get the quota of a user
|
||||
* @param string $format
|
||||
* @param string $user
|
||||
* @return string xml/json
|
||||
*/
|
||||
private static function quotaGet($format,$user) {
|
||||
$login=OC_OCS::checkpassword();
|
||||
if(OC_Group::inGroup($login, 'admin') or ($login==$user)) {
|
||||
|
||||
if(OC_User::userExists($user)){
|
||||
// calculate the disc space
|
||||
$user_dir = '/'.$user.'/files';
|
||||
OC_Filesystem::init($user_dir);
|
||||
$rootInfo=OC_FileCache::get('');
|
||||
$sharedInfo=OC_FileCache::get('/Shared');
|
||||
$used=$rootInfo['size']-$sharedInfo['size'];
|
||||
$free=OC_Filesystem::free_space();
|
||||
$total=$free+$used;
|
||||
if($total==0) $total=1; // prevent division by zero
|
||||
$relative=round(($used/$total)*10000)/100;
|
||||
|
||||
$xml=array();
|
||||
$xml['quota']=$total;
|
||||
$xml['free']=$free;
|
||||
$xml['used']=$used;
|
||||
$xml['relative']=$relative;
|
||||
|
||||
$txt=OC_OCS::generatexml($format, 'ok', 100, '', $xml, 'cloud', 'full', 1, count($xml), 0);
|
||||
echo($txt);
|
||||
}else{
|
||||
echo self::generateXml('', 'fail', 300, 'User does not exist');
|
||||
}
|
||||
}else{
|
||||
echo self::generateXml('', 'fail', 300, 'You don´t have permission to access this ressource.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* set the quota of a user
|
||||
* @param string $format
|
||||
* @param string $user
|
||||
* @param string $quota
|
||||
* @return string xml/json
|
||||
*/
|
||||
private static function quotaSet($format,$user,$quota) {
|
||||
$login=OC_OCS::checkpassword();
|
||||
if(OC_Group::inGroup($login, 'admin')) {
|
||||
|
||||
// todo
|
||||
// not yet implemented
|
||||
// edit logic here
|
||||
error_log('OCS call: user:'.$user.' quota:'.$quota);
|
||||
|
||||
$xml=array();
|
||||
$txt=OC_OCS::generatexml($format, 'ok', 100, '', $xml, 'cloud', 'full', 1, count($xml), 0);
|
||||
echo($txt);
|
||||
}else{
|
||||
echo self::generateXml('', 'fail', 300, 'You don´t have permission to access this ressource.');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -104,10 +104,16 @@ class OC_User {
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
true;
|
||||
}
|
||||
|
||||
/**
|
||||
* remove all used backends
|
||||
*/
|
||||
public static function clearBackends(){
|
||||
self::$_usedBackends=array();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Create a new user
|
||||
* @param $uid The username of the user to create
|
||||
|
|
59
lib/util.php
59
lib/util.php
|
@ -77,13 +77,13 @@ class OC_Util {
|
|||
return '5 pre alpha';
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 '';
|
||||
}
|
||||
/**
|
||||
* 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
|
||||
|
@ -131,12 +131,12 @@ class OC_Util {
|
|||
self::$headers[]=array('tag'=>$tag,'attributes'=>$attributes,'text'=>$text);
|
||||
}
|
||||
|
||||
/**
|
||||
* formats a timestamp in the "right" way
|
||||
*
|
||||
* @param int timestamp $timestamp
|
||||
* @param bool dateOnly option to ommit time from the result
|
||||
*/
|
||||
/**
|
||||
* formats a timestamp in the "right" way
|
||||
*
|
||||
* @param int timestamp $timestamp
|
||||
* @param bool dateOnly option to ommit time from the result
|
||||
*/
|
||||
public static function formatDate( $timestamp,$dateOnly=false){
|
||||
if(isset($_SESSION['timezone'])){//adjust to clients timezone if we know it
|
||||
$systemTimeZone = intval(date('O'));
|
||||
|
@ -438,26 +438,25 @@ class OC_Util {
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if the htaccess file is working by creating a test file in the data directory and trying to access via http
|
||||
*/
|
||||
public static function ishtaccessworking() {
|
||||
|
||||
/**
|
||||
* Check if the htaccess file is working by creating a test file in the data directory and trying to access via http
|
||||
*/
|
||||
public static function ishtaccessworking() {
|
||||
// testdata
|
||||
$filename='/htaccesstest.txt';
|
||||
$testcontent='testcontent';
|
||||
|
||||
// creating a test file
|
||||
$testfile = OC_Config::getValue( "datadirectory", OC::$SERVERROOT."/data" ).'/'.$filename;
|
||||
$fp = @fopen($testfile, 'w');
|
||||
@fwrite($fp, $testcontent);
|
||||
@fclose($fp);
|
||||
$testfile = OC_Config::getValue( "datadirectory", OC::$SERVERROOT."/data" ).'/'.$filename;
|
||||
$fp = @fopen($testfile, 'w');
|
||||
@fwrite($fp, $testcontent);
|
||||
@fclose($fp);
|
||||
|
||||
// accessing the file via http
|
||||
$url = OC_Helper::serverProtocol(). '://' . OC_Helper::serverHost() . OC::$WEBROOT.'/data'.$filename;
|
||||
$fp = @fopen($url, 'r');
|
||||
$content=@fread($fp, 2048);
|
||||
@fclose($fp);
|
||||
$url = OC_Helper::serverProtocol(). '://' . OC_Helper::serverHost() . OC::$WEBROOT.'/data'.$filename;
|
||||
$fp = @fopen($url, 'r');
|
||||
$content=@fread($fp, 2048);
|
||||
@fclose($fp);
|
||||
|
||||
// cleanup
|
||||
@unlink($testfile);
|
||||
|
@ -467,13 +466,7 @@ class OC_Util {
|
|||
return(false);
|
||||
}else{
|
||||
return(true);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -35,7 +35,9 @@ echo('
|
|||
<termsofuse></termsofuse>
|
||||
<register></register>
|
||||
<services>
|
||||
<activity ocsversion="1.5" />
|
||||
<config ocsversion="1.7" />
|
||||
<activity ocsversion="1.7" />
|
||||
<cloud ocsversion="1.7" />
|
||||
</services>
|
||||
</provider>
|
||||
</providers>
|
||||
|
|
|
@ -42,6 +42,27 @@ abstract class Test_Cache extends UnitTestCase {
|
|||
$this->assertNull($this->instance->get('not_set'),'Unset value not equal to null');
|
||||
|
||||
$this->assertTrue($this->instance->remove('value1'));
|
||||
$this->assertFalse($this->instance->hasKey('value1'));
|
||||
}
|
||||
|
||||
function testClear(){
|
||||
$value='ipsum lorum';
|
||||
$this->instance->set('1_value1',$value);
|
||||
$this->instance->set('1_value2',$value);
|
||||
$this->instance->set('2_value1',$value);
|
||||
$this->instance->set('3_value1',$value);
|
||||
|
||||
$this->assertTrue($this->instance->clear('1_'));
|
||||
$this->assertFalse($this->instance->hasKey('1_value1'));
|
||||
$this->assertFalse($this->instance->hasKey('1_value2'));
|
||||
$this->assertTrue($this->instance->hasKey('2_value1'));
|
||||
$this->assertTrue($this->instance->hasKey('3_value1'));
|
||||
|
||||
$this->assertTrue($this->instance->clear());
|
||||
$this->assertFalse($this->instance->hasKey('1_value1'));
|
||||
$this->assertFalse($this->instance->hasKey('1_value2'));
|
||||
$this->assertFalse($this->instance->hasKey('2_value1'));
|
||||
$this->assertFalse($this->instance->hasKey('3_value1'));
|
||||
}
|
||||
|
||||
function testTTL(){
|
||||
|
|
19
tests/lib/cache/file.php
vendored
19
tests/lib/cache/file.php
vendored
|
@ -21,8 +21,10 @@
|
|||
*/
|
||||
|
||||
class Test_Cache_File extends Test_Cache {
|
||||
private $user;
|
||||
|
||||
function skip() {
|
||||
$this->skipUnless(OC_User::isLoggedIn());
|
||||
//$this->skipUnless(OC_User::isLoggedIn());
|
||||
}
|
||||
|
||||
public function setUp(){
|
||||
|
@ -39,10 +41,23 @@ class Test_Cache_File extends Test_Cache {
|
|||
OC_Filesystem::clearMounts();
|
||||
OC_Filesystem::mount('OC_Filestorage_Temporary',array(),'/');
|
||||
|
||||
OC_User::clearBackends();
|
||||
OC_User::useBackend(new OC_User_Dummy());
|
||||
|
||||
//login
|
||||
OC_User::createUser('test', 'test');
|
||||
|
||||
$this->user=OC_User::getUser();
|
||||
OC_User::setUserId('test');
|
||||
|
||||
//set up the users dir
|
||||
$rootView=new OC_FilesystemView('');
|
||||
$rootView->mkdir('/'.OC_User::getUser());
|
||||
$rootView->mkdir('/test');
|
||||
|
||||
$this->instance=new OC_Cache_File();
|
||||
}
|
||||
|
||||
public function tearDown(){
|
||||
OC_User::setUserId($this->user);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue