first import
40
sites/all/modules/plupload/CHANGELOG.txt
Normal file
@@ -0,0 +1,40 @@
|
||||
CHANGELOG for Plupload integration for Drupal 7
|
||||
|
||||
Plupload integration 7.x-1.x-dev
|
||||
=================================
|
||||
- #1903818 by quicksketch, slashrsm: Fixed Double dollar signs in hook_requirements().
|
||||
- #1506642 by MrHaroldA | succinct: Fixed plupload.js issue with Internet Explorer.
|
||||
|
||||
Plupload integration 7.x-1.1
|
||||
=================================
|
||||
- #1895328 by larowlan, slashrsm: Fixed Security exploit in plupload external library examples folder.
|
||||
- #1230632 by -enzo-, slashrsm: Fixed hard-coded file size limits.
|
||||
- by slashrsm: Fix CodeSniffer errors.
|
||||
- #1827368 by Kevin Hankens: Fixed Use standard language when validating files.
|
||||
- #1565898 by slashrsm: Create docs for Plupload element usage in README.txt.
|
||||
- #1111036 by slashrsm: Blacklist script extensions if 'allow_insecure_uploads' isn't set to TRUE.
|
||||
- #1426088 by slashrsm: Anonymous User can't upload.
|
||||
|
||||
Plupload integration 7.x-1.0
|
||||
=================================
|
||||
- #1414486 by nbucknor, slashrsm: Improvements of error handling for multiple plupload elements on a single form.
|
||||
|
||||
Plupload integration 7.x-1.0-rc1
|
||||
==================================
|
||||
- by slashrsm: Fix 3 Coder review notices.
|
||||
- by slashrsm: Removed unnecessary popup caused by previous commit.
|
||||
- #1414486 by nbucknor, annblack: Allow for Multiple Plupload elements in a form.
|
||||
- #1461884 by atlea: File uploads larger than php post_max_size broken
|
||||
- #1445172 by Moloc: Use drupal_unlink() instead unlink()
|
||||
|
||||
Plupload integration 7.x-1.0-beta4
|
||||
==================================
|
||||
- #1230632 by ksenzee: Hard-coded file size limits.
|
||||
- #1219992 by slashrsm, axe312, Dave Reid: Add support for Drupal native translations.
|
||||
- #1111054 by George Petsagourakis: Convert plupload_fix_temporary_filename() a private function
|
||||
- #1316438 by jcfiala, slashrsm: Plupload in AJAX call causes form.submit handler to be added multiple times
|
||||
- #1300620 by jamiecuthill, ksenzee: Update to 1.5.1.1 because uploading is broken in Firefox 7
|
||||
- #1121070 by Moloc: Warning: unlink(...) [function.unlink]: Permission denied in plupload_handle_uploads()
|
||||
- #1348892 by slashrsm, Moloc: Show library version in status report
|
||||
- #1267190 by Moloc: Plupload transliteration support for d7
|
||||
- #1240654 by Dave Reid: Use a proper namespace for file_uri_to_object().
|
339
sites/all/modules/plupload/LICENSE.txt
Normal file
@@ -0,0 +1,339 @@
|
||||
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.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License.
|
63
sites/all/modules/plupload/README.txt
Normal file
@@ -0,0 +1,63 @@
|
||||
This module integrates the Plupload library (available from http://plupload.com)
|
||||
with Drupal forms. To install the Plupload library:
|
||||
|
||||
1. Download it (version 1.5.1.1 or later) from http://plupload.com.
|
||||
2. Unzip it into sites/all/libraries, so that there's a
|
||||
sites/all/libraries/plupload/js/plupload.full.js file, in addition to the
|
||||
other files included in the library.
|
||||
3. Remove "examples" folder from libraries folder as it could constitute a
|
||||
security risk to your site. See http://drupal.org/node/1895328 and
|
||||
http://drupal.org/node/1189632 for more info.
|
||||
|
||||
If you would like to use an alternate library location, you can install the
|
||||
http://drupal.org/project/libraries module and/or add
|
||||
|
||||
$conf['plupload_library_path'] = PATH/TO/PLUPLOAD;
|
||||
|
||||
to your settings.php file.
|
||||
|
||||
At this time, this module only provides a 'plupload' form element type that
|
||||
other modules can use for providing multiple file upload capability to their
|
||||
forms. It does not provide any end-user functionality on its own. This may
|
||||
change, however, as this module evolves. See http://drupal.org/node/880300.
|
||||
|
||||
---=== For developers ===---
|
||||
|
||||
Plupload from element can be used like this:
|
||||
|
||||
$form['my_element'] = array(
|
||||
'#type' => 'plupload',
|
||||
'#title' => t('Upload files'),
|
||||
'#description => t('This multi-upload widget uses Plupload library.'),
|
||||
'#upload_validators' => array(
|
||||
'file_validate_extensions' => array('jpg jpeg gif png txt doc xls pdf ppt pps odt ods odp'),
|
||||
'my_custom_file_validator => array('some validation criteria'),
|
||||
);
|
||||
'#plupload_settings' => array(
|
||||
'runtimes' => 'html5',
|
||||
'chunk_size => '1mb',
|
||||
),
|
||||
);
|
||||
|
||||
- #upload_validators - an array of validation function/validation criteria pairs, that
|
||||
will be passed to file_validate().
|
||||
|
||||
Defaults to:
|
||||
'#upload_validators' => array(
|
||||
'file_validate_extensions' => array('jpg jpeg gif png txt doc xls pdf ppt pps odt ods odp'),
|
||||
);
|
||||
|
||||
|
||||
- #plupload_settings - array of settings, that will be passed to Plupload library.
|
||||
See: http://www.plupload.com/documentation.php
|
||||
|
||||
Defaults to:
|
||||
'#plupload_settings' => array(
|
||||
'runtimes' => 'html5,flash,html4',
|
||||
'url' => url('plupload-handle-uploads', array('query' => array('plupload_token' => drupal_get_token('plupload-handle-uploads')))),
|
||||
'max_file_size' => file_upload_max_size() . 'b',
|
||||
'chunk_size' => '1mb',
|
||||
'unique_names' => TRUE,
|
||||
'flash_swf_url' => file_create_url($library_path . '/js/plupload.flash.swf'),
|
||||
'silverlight_xap_url' => file_create_url($library_path . '/js/plupload.silverlight.xap'),
|
||||
),
|
BIN
sites/all/modules/plupload/images/add.png
Normal file
After Width: | Height: | Size: 160 B |
BIN
sites/all/modules/plupload/images/backgrounds.gif
Normal file
After Width: | Height: | Size: 2.9 KiB |
BIN
sites/all/modules/plupload/images/buttons-disabled.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
sites/all/modules/plupload/images/buttons.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
sites/all/modules/plupload/images/delete.gif
Normal file
After Width: | Height: | Size: 180 B |
BIN
sites/all/modules/plupload/images/done.gif
Normal file
After Width: | Height: | Size: 1.0 KiB |
BIN
sites/all/modules/plupload/images/error.gif
Normal file
After Width: | Height: | Size: 994 B |
BIN
sites/all/modules/plupload/images/icon-feed.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
sites/all/modules/plupload/images/throbber.gif
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
sites/all/modules/plupload/images/transp50.png
Normal file
After Width: | Height: | Size: 399 B |
BIN
sites/all/modules/plupload/images/up_arrow.png
Normal file
After Width: | Height: | Size: 66 KiB |
BIN
sites/all/modules/plupload/images/up_arrow_disabled.png
Normal file
After Width: | Height: | Size: 62 KiB |
BIN
sites/all/modules/plupload/images/video-indicator.png
Normal file
After Width: | Height: | Size: 231 B |
29
sites/all/modules/plupload/js/i18n.js
Normal file
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
* @file
|
||||
* Localization file for Plupload's strings.
|
||||
*/
|
||||
|
||||
// Add translations.
|
||||
plupload.addI18n({
|
||||
"Select files" : Drupal.t("Select files"),
|
||||
"Add files to the upload queue and click the start button." : Drupal.t("Add files to the upload queue and click the start button."),
|
||||
"Filename" : Drupal.t("Filename"),
|
||||
"Status" : Drupal.t("Status"),
|
||||
"Size" : Drupal.t("Size"),
|
||||
"Add files" : Drupal.t("Add files"),
|
||||
"Stop current upload" : Drupal.t("Stop current upload"),
|
||||
"Start uploading queue" : Drupal.t("Start uploading queue"),
|
||||
"Uploaded %d/%d files": Drupal.t("Uploaded %d/%d files"),
|
||||
"N/A" : Drupal.t("N/A"),
|
||||
"Drag files here." : Drupal.t("Drag files here."),
|
||||
"File extension error.": Drupal.t("File extension error."),
|
||||
"File size error.": Drupal.t("File size error."),
|
||||
"Init error.": Drupal.t("Init error."),
|
||||
"HTTP Error.": Drupal.t("HTTP Error."),
|
||||
"Security error.": Drupal.t("Security error."),
|
||||
"Generic error.": Drupal.t("Generic error."),
|
||||
"IO error.": Drupal.t("IO error."),
|
||||
"Start upload" : Drupal.t("Start upload"),
|
||||
"Stop upload" : Drupal.t("Stop upload"),
|
||||
"%d files queued" : Drupal.t("%d files queued")
|
||||
});
|
207
sites/all/modules/plupload/plupload.css
Normal file
@@ -0,0 +1,207 @@
|
||||
|
||||
.plupload_button {
|
||||
display:inline-block;
|
||||
font:normal 12px sans-serif;
|
||||
text-decoration:none;
|
||||
color:#42454a;
|
||||
margin-right:4px;
|
||||
outline:0;
|
||||
-moz-border-radius:3px;
|
||||
-khtml-border-radius:3px;
|
||||
-webkit-border-radius:3px;
|
||||
border-radius:3px;
|
||||
font-family:"Lucida Grande", Verdana, sans-serif;
|
||||
border:none;
|
||||
background:none;
|
||||
padding:2px 8px 3px 15px;
|
||||
}
|
||||
|
||||
.plupload_button:hover {
|
||||
color:#000;
|
||||
text-decoration:none;
|
||||
}
|
||||
|
||||
.plupload_disabled,a.plupload_disabled:hover {
|
||||
cursor:default;
|
||||
color:#737373;
|
||||
background:transparent url(images/up_arrow_disabled.png) no-repeat 0 center;
|
||||
border-color:#c5c5c5;
|
||||
}
|
||||
|
||||
.plupload_add {
|
||||
background-position:-181px center;
|
||||
background:transparent url(images/add.png) no-repeat 0 center;
|
||||
}
|
||||
|
||||
.plupload_wrapper {
|
||||
font:normal 11px Verdana,sans-serif;
|
||||
width:100%;
|
||||
font-family:"Lucida Grande", Verdana, sans-serif;
|
||||
}
|
||||
|
||||
.plupload_container {
|
||||
background:url('images/transp50.png');
|
||||
}
|
||||
|
||||
.plupload_container input {
|
||||
border:1px solid #DDD;
|
||||
font:normal 11px Verdana,sans-serif;
|
||||
width:98%;
|
||||
font-family:"Lucida Grande", Verdana, sans-serif;
|
||||
}
|
||||
|
||||
.plupload_filelist {
|
||||
list-style:none;
|
||||
margin:0;
|
||||
padding:0;
|
||||
}
|
||||
|
||||
.plupload_scroll .plupload_filelist {
|
||||
height:135px;
|
||||
overflow-y:scroll;
|
||||
background:none;
|
||||
}
|
||||
|
||||
.plupload_filelist li {
|
||||
background:#F5F5F5 url('images/backgrounds.gif') repeat-x 0 -156px;
|
||||
border-bottom:1px solid #DDD;
|
||||
padding:10px 8px;
|
||||
}
|
||||
|
||||
.plupload_filelist_header,.plupload_filelist_footer {
|
||||
background:#DFDFDF;
|
||||
color:#42454A;
|
||||
padding:6px 8px;
|
||||
}
|
||||
|
||||
.plupload_filelist_header {
|
||||
border-top:1px solid #EEE;
|
||||
border-bottom:1px solid #CDCDCD;
|
||||
}
|
||||
|
||||
.plupload_filelist_footer {
|
||||
border-top:1px solid #FFF;
|
||||
height:22px;
|
||||
line-height:20px;
|
||||
vertical-align:middle;
|
||||
}
|
||||
|
||||
.plupload_file_name {
|
||||
float:left;
|
||||
overflow:hidden;
|
||||
}
|
||||
|
||||
.plupload_file_status {
|
||||
color:#777;
|
||||
}
|
||||
|
||||
.plupload_file_status span {
|
||||
color:#42454A;
|
||||
}
|
||||
|
||||
.plupload_file_size,.plupload_file_status,.plupload_progress {
|
||||
float:right;
|
||||
width:80px;
|
||||
}
|
||||
|
||||
.plupload_file_size,.plupload_file_status,.plupload_file_action {
|
||||
text-align:right;
|
||||
}
|
||||
|
||||
.plupload_filelist .plupload_file_name {
|
||||
width:205px;
|
||||
}
|
||||
|
||||
.plupload_file_action {
|
||||
float:right;
|
||||
width:16px;
|
||||
height:16px;
|
||||
margin-left:15px;
|
||||
}
|
||||
|
||||
.plupload_file_action * {
|
||||
display:none;
|
||||
width:16px;
|
||||
height:16px;
|
||||
}
|
||||
|
||||
li.plupload_uploading {
|
||||
background:#ECF3DC url('images/backgrounds.gif') repeat-x 0 -238px;
|
||||
}
|
||||
|
||||
li.plupload_done {
|
||||
color:#AAA;
|
||||
}
|
||||
|
||||
li.plupload_delete a {
|
||||
background:url('images/delete.gif');
|
||||
}
|
||||
|
||||
li.plupload_failed a {
|
||||
background:url('images/error.gif');
|
||||
cursor:default;
|
||||
}
|
||||
|
||||
li.plupload_done a {
|
||||
background:url('images/done.gif');
|
||||
cursor:default;
|
||||
}
|
||||
|
||||
.plupload_progress,.plupload_upload_status {
|
||||
display:none;
|
||||
}
|
||||
|
||||
.plupload_progress_container {
|
||||
margin-top:3px;
|
||||
border:1px solid #CCC;
|
||||
background:#FFF;
|
||||
padding:1px;
|
||||
}
|
||||
|
||||
.plupload_progress_bar {
|
||||
width:0;
|
||||
height:7px;
|
||||
background:#CDEB8B;
|
||||
}
|
||||
|
||||
.plupload_scroll .plupload_filelist_header .plupload_file_action,.plupload_scroll .plupload_filelist_footer .plupload_file_action {
|
||||
margin-right:17px;
|
||||
}
|
||||
|
||||
.plupload_clear,.plupload_clearer {
|
||||
clear:both;
|
||||
}
|
||||
|
||||
.plupload_clearer,.plupload_progress_bar {
|
||||
display:block;
|
||||
font-size:0;
|
||||
line-height:0;
|
||||
}
|
||||
|
||||
li.plupload_droptext {
|
||||
background:transparent;
|
||||
text-align:center;
|
||||
vertical-align:middle;
|
||||
border:0;
|
||||
line-height:115px;
|
||||
list-style-type:none;
|
||||
}
|
||||
|
||||
.plupload {
|
||||
border:solid 1px #ccc;
|
||||
}
|
||||
|
||||
.plupload_header {
|
||||
display:none;
|
||||
}
|
||||
|
||||
.plupload_button,.plupload_button:hover {
|
||||
color:#0074bd;
|
||||
padding-bottom:0;
|
||||
margin-bottom:0;
|
||||
}
|
||||
|
||||
.plupload_start,a.plupload_start:hover {
|
||||
background:transparent url(images/up_arrow.png) no-repeat 0 center;
|
||||
z-index:100000;
|
||||
}
|
12
sites/all/modules/plupload/plupload.info
Normal file
@@ -0,0 +1,12 @@
|
||||
name = Plupload integration module
|
||||
description = Provides a plupload element.
|
||||
files[] = plupload.module
|
||||
core = 7.x
|
||||
package = Media
|
||||
|
||||
; Information added by drupal.org packaging script on 2013-02-01
|
||||
version = "7.x-1.1+2-dev"
|
||||
core = "7.x"
|
||||
project = "plupload"
|
||||
datestamp = "1359682808"
|
||||
|
106
sites/all/modules/plupload/plupload.install
Normal file
@@ -0,0 +1,106 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Install, update and uninstall functions for the Plupload module.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_requirements().
|
||||
*/
|
||||
function plupload_requirements($phase) {
|
||||
$requirements = array();
|
||||
$t = get_t();
|
||||
|
||||
if ($phase == 'runtime') {
|
||||
$requirements['plupload'] = array(
|
||||
'title' => $t('Plupload library'),
|
||||
'value' => $t('Unknown'),
|
||||
);
|
||||
$requirements['plupload']['severity'] = REQUIREMENT_OK;
|
||||
$libraries = plupload_library();
|
||||
$library = $libraries['plupload'];
|
||||
|
||||
// Check if Plupload library exists. Try to determine it's version
|
||||
// if it does.
|
||||
if (!_plupload_requirements_installed()) {
|
||||
$message = 'The <a href="@url">@title</a> library (version @version or higher) is not installed.';
|
||||
$args = array(
|
||||
'@title' => $library['title'],
|
||||
'@url' => url($library['website']),
|
||||
'@version' => $library['version'],
|
||||
);
|
||||
|
||||
$requirements['plupload']['description'] = $t($message, $args);
|
||||
$requirements['plupload']['severity'] = REQUIREMENT_ERROR;
|
||||
}
|
||||
elseif (($installed_version = _plupload_requirements_version()) === NULL) {
|
||||
$requirements['plupload']['description'] = $t('Plupload version could not be determined.');
|
||||
$requirements['plupload']['severity'] = REQUIREMENT_INFO;
|
||||
}
|
||||
elseif (!version_compare($library['version'], $installed_version, '<=')) {
|
||||
$requirements['plupload']['description'] = $t('Plupload @version or higher is required.', array('@version' => $library['version']));
|
||||
$requirements['plupload']['severity'] = REQUIREMENT_INFO;
|
||||
}
|
||||
|
||||
$requirements['plupload']['value'] = empty($installed_version) ? $t('Not found') : $installed_version;
|
||||
|
||||
if (file_exists(_plupload_library_path() . '/examples/upload.php')) {
|
||||
$requirements['plupload_examples'] = array(
|
||||
'title' => $t('Plupload example folder'),
|
||||
'value' => $t('Example folder found'),
|
||||
'description' => $t('Plupload library contains example files, these could constitute a security risk to your site as per <a href="!url">PSA-2011-02</a>. Please remove the !path folder immediately.', array(
|
||||
'!url' => 'http://drupal.org/node/1189632',
|
||||
'!path' => _plupload_library_path() . '/examples'
|
||||
)),
|
||||
'severity' => REQUIREMENT_ERROR
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return $requirements;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks wether Plupload library exists or not.
|
||||
*
|
||||
* @return boolean
|
||||
* TRUE if plupload library installed, FALSE otherwise.
|
||||
*/
|
||||
function _plupload_requirements_installed() {
|
||||
$libraries = plupload_library();
|
||||
$library = $libraries['plupload'];
|
||||
|
||||
// We grab the first file and check if it exists.
|
||||
$testfile = key($library['js']);
|
||||
if (!file_exists($testfile)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the version of the installed plupload library.
|
||||
*
|
||||
* @return string
|
||||
* The version of installed Plupload or NULL if unable to detect version.
|
||||
*/
|
||||
function _plupload_requirements_version() {
|
||||
$library_path = _plupload_library_path();
|
||||
$jspath = $library_path . '/js/plupload.js';
|
||||
|
||||
// Read contents of Plupload's javascript file.
|
||||
$configcontents = @file_get_contents($jspath);
|
||||
if (!$configcontents) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Search for version string using a regular expression.
|
||||
$matches = array();
|
||||
if (preg_match('#VERSION:\"(\d+[\.\d+]*)\"#', $configcontents, $matches)) {
|
||||
return $matches[1];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
167
sites/all/modules/plupload/plupload.js
Normal file
@@ -0,0 +1,167 @@
|
||||
(function($) {
|
||||
|
||||
Drupal.plupload = Drupal.plupload || {};
|
||||
|
||||
/**
|
||||
* Attaches the Plupload behavior to each Plupload form element.
|
||||
*/
|
||||
Drupal.behaviors.plupload = {
|
||||
attach: function (context, settings) {
|
||||
$(".plupload-element", context).once('plupload-init', function () {
|
||||
var $this = $(this);
|
||||
|
||||
// Merge the default settings and the element settings to get a full
|
||||
// settings object to pass to the Plupload library for this element.
|
||||
var id = $this.attr('id');
|
||||
var defaultSettings = settings.plupload['_default'] ? settings.plupload['_default'] : {};
|
||||
var elementSettings = (id && settings.plupload[id]) ? settings.plupload[id] : {};
|
||||
var pluploadSettings = $.extend({}, defaultSettings, elementSettings);
|
||||
|
||||
// Do additional requirements testing to prevent a less than ideal runtime
|
||||
// from being used. For example, the Plupload library treats Firefox 3.5
|
||||
// as supporting HTML 5, but this is incorrect, because Firefox 3.5
|
||||
// doesn't support the 'multiple' attribute for file input controls. So,
|
||||
// if settings.plupload._requirements.html5.mozilla = '1.9.2', then we
|
||||
// remove 'html5' from pluploadSettings.runtimes if $.browser.mozilla is
|
||||
// true and if $.browser.version is less than '1.9.2'.
|
||||
if (settings.plupload['_requirements'] && pluploadSettings.runtimes) {
|
||||
var runtimes = pluploadSettings.runtimes.split(',');
|
||||
var filteredRuntimes = [];
|
||||
for (var i = 0; i < runtimes.length; i++) {
|
||||
var includeRuntime = true;
|
||||
if (settings.plupload['_requirements'][runtimes[i]]) {
|
||||
var requirements = settings.plupload['_requirements'][runtimes[i]];
|
||||
for (var browser in requirements) {
|
||||
if ($.browser[browser] && Drupal.plupload.compareVersions($.browser.version, requirements[browser]) < 0) {
|
||||
includeRuntime = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (includeRuntime) {
|
||||
filteredRuntimes.push(runtimes[i]);
|
||||
}
|
||||
}
|
||||
pluploadSettings.runtimes = filteredRuntimes.join(',');
|
||||
}
|
||||
|
||||
// Initialize Plupload for this element.
|
||||
$this.pluploadQueue(pluploadSettings);
|
||||
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Attaches the Plupload behavior to each Plupload form element.
|
||||
*/
|
||||
Drupal.behaviors.pluploadform = {
|
||||
attach: function(context, settings) {
|
||||
$('form', context).once('plupload-form', function() {
|
||||
if (0 < $(this).find('.plupload-element').length) {
|
||||
var $form = $(this);
|
||||
var originalFormAttributes = {
|
||||
'method': $form.attr('method'),
|
||||
'enctype': $form.attr('enctype'),
|
||||
'action': $form.attr('action'),
|
||||
'target': $form.attr('target')
|
||||
};
|
||||
|
||||
$(this).submit(function(e) {
|
||||
var completedPluploaders = 0;
|
||||
var totalPluploaders = $(this).find('.plupload-element').length;
|
||||
var errors = '';
|
||||
|
||||
$(this).find('.plupload-element').each( function(index){
|
||||
var uploader = $(this).pluploadQueue();
|
||||
|
||||
var id = $(this).attr('id');
|
||||
var defaultSettings = settings.plupload['_default'] ? settings.plupload['_default'] : {};
|
||||
var elementSettings = (id && settings.plupload[id]) ? settings.plupload[id] : {};
|
||||
var pluploadSettings = $.extend({}, defaultSettings, elementSettings);
|
||||
|
||||
//Only allow the submit to proceed if there are files and they've all
|
||||
//completed uploading.
|
||||
//TODO: Implement a setting for whether the field is required, rather
|
||||
//than assuming that all are.
|
||||
if (uploader.state == plupload.STARTED) {
|
||||
errors += Drupal.t("Please wait while your files are being uploaded.");
|
||||
}
|
||||
else if (uploader.files.length == 0 && !pluploadSettings.required) {
|
||||
completedPluploaders++;
|
||||
}
|
||||
|
||||
else if (uploader.files.length == 0) {
|
||||
errors += Drupal.t("@index: You must upload at least one file.\n",{'@index': (index + 1)});
|
||||
}
|
||||
|
||||
else if (uploader.files.length > 0 && uploader.total.uploaded == uploader.files.length) {
|
||||
completedPluploaders++;
|
||||
}
|
||||
|
||||
else {
|
||||
var stateChangedHandler = function() {
|
||||
if (uploader.total.uploaded == uploader.files.length) {
|
||||
uploader.unbind('StateChanged', stateChangedHandler);
|
||||
completedPluploaders++;
|
||||
if (completedPluploaders == totalPluploaders ) {
|
||||
//Plupload's html4 runtime has a bug where it changes the
|
||||
//attributes of the form to handle the file upload, but then
|
||||
//fails to change them back after the upload is finished.
|
||||
for (var attr in originalFormAttributes) {
|
||||
$form.attr(attr, originalFormAttributes[attr]);
|
||||
}
|
||||
$form.submit();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
};
|
||||
uploader.bind('StateChanged', stateChangedHandler);
|
||||
uploader.start();
|
||||
}
|
||||
|
||||
});
|
||||
if (completedPluploaders == totalPluploaders) {
|
||||
//Plupload's html4 runtime has a bug where it changes the
|
||||
//attributes of the form to handle the file upload, but then
|
||||
//fails to change them back after the upload is finished.
|
||||
for (var attr in originalFormAttributes) {
|
||||
$form.attr(attr, originalFormAttributes[attr]);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else if (0 < errors.length){
|
||||
alert(errors);
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Helper function to compare version strings.
|
||||
*
|
||||
* Returns one of:
|
||||
* - A negative integer if a < b.
|
||||
* - A positive integer if a > b.
|
||||
* - 0 if a == b.
|
||||
*/
|
||||
Drupal.plupload.compareVersions = function (a, b) {
|
||||
a = a.split('.');
|
||||
b = b.split('.');
|
||||
// Return the most significant difference, if there is one.
|
||||
for (var i=0; i < Math.min(a.length, b.length); i++) {
|
||||
var compare = parseInt(a[i]) - parseInt(b[i]);
|
||||
if (compare != 0) {
|
||||
return compare;
|
||||
}
|
||||
}
|
||||
// If the common parts of the two version strings are equal, the greater
|
||||
// version number is the one with the most sections.
|
||||
return a.length - b.length;
|
||||
}
|
||||
|
||||
})(jQuery);
|
510
sites/all/modules/plupload/plupload.module
Normal file
@@ -0,0 +1,510 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Implementation of plupload.module.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_menu().
|
||||
*/
|
||||
function plupload_menu() {
|
||||
$items['plupload-handle-uploads'] = array(
|
||||
'title' => 'Handles uploads',
|
||||
'page callback' => 'plupload_handle_uploads',
|
||||
'type' => MENU_CALLBACK,
|
||||
'access callback' => 'plupload_upload_access',
|
||||
'access arguments' => array('access content'),
|
||||
);
|
||||
$items['plupload-test'] = array(
|
||||
'title' => 'Test Plupload',
|
||||
'page callback' => 'drupal_get_form',
|
||||
'page arguments' => array('plupload_test'),
|
||||
// @todo: change this to something appropriate, not sure what.
|
||||
'access arguments' => array('Administer site configuration'),
|
||||
'type' => MENU_CALLBACK,
|
||||
);
|
||||
return $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies the token for this request.
|
||||
*/
|
||||
function plupload_upload_access() {
|
||||
foreach (func_get_args() as $permission) {
|
||||
if (!user_access($permission)) {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
return !empty($_REQUEST['plupload_token']) && drupal_valid_token($_REQUEST['plupload_token'], 'plupload-handle-uploads');
|
||||
}
|
||||
|
||||
/**
|
||||
* Form callback function for test page visible at URL "plupload-test".
|
||||
*/
|
||||
function plupload_test($form, &$form_state) {
|
||||
$form['pud'] = array(
|
||||
'#type' => 'plupload',
|
||||
'#title' => 'Plupload',
|
||||
// '#validators' => array(...);
|
||||
);
|
||||
|
||||
$form['submit'] = array(
|
||||
'#type' => 'submit',
|
||||
'#value' => 'Submit',
|
||||
);
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Submit callback for plupload_test form.
|
||||
*/
|
||||
function plupload_test_submit($form, &$form_state) {
|
||||
$saved_files = array();
|
||||
$scheme = variable_get('file_default_scheme', 'public') . '://';
|
||||
// We can't use file_save_upload() because of
|
||||
// http://www.jacobsingh.name/content/tight-coupling-no-not
|
||||
// file_uri_to_object();
|
||||
foreach ($form_state['values']['pud'] as $uploaded_file) {
|
||||
if ($uploaded_file['status'] == 'done') {
|
||||
$source = $uploaded_file['tmppath'];
|
||||
$destination = file_stream_wrapper_uri_normalize($scheme . $uploaded_file['name']);
|
||||
// Rename it to its original name, and put it in its final home.
|
||||
// Note - not using file_move here because if we call file_get_mime
|
||||
// (in file_uri_to_object) while it has a .tmp extension, it horks.
|
||||
$destination = file_unmanaged_move($source, $destination, FILE_EXISTS_RENAME);
|
||||
$file = plupload_file_uri_to_object($destination);
|
||||
file_save($file);
|
||||
$saved_files[] = $file;
|
||||
}
|
||||
else {
|
||||
// @todo: move this to element validate or something and clean up t().
|
||||
form_set_error('pud', "Upload of {$uploaded_file['name']} failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_element_info().
|
||||
*/
|
||||
function plupload_element_info() {
|
||||
$types = array();
|
||||
$module_path = drupal_get_path('module', 'plupload');
|
||||
$types['plupload'] = array(
|
||||
'#input' => TRUE,
|
||||
'#attributes' => array('class' => array('plupload-element')),
|
||||
// @todo
|
||||
// '#element_validate' => array('file_managed_file_validate'),
|
||||
'#theme_wrappers' => array('form_element'),
|
||||
'#theme' => 'container',
|
||||
'#value_callback' => 'plupload_element_value',
|
||||
'#attached' => array(
|
||||
'library' => array(array('plupload', 'plupload')),
|
||||
'js' => array($module_path . '/plupload.js'),
|
||||
'css' => array($module_path . '/plupload.css'),
|
||||
),
|
||||
'#process' => array('plupload_element_process'),
|
||||
'#element_validate' => array('plupload_element_validate'),
|
||||
'#pre_render' => array('plupload_element_pre_render'),
|
||||
);
|
||||
return $types;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate callback for plupload form element.
|
||||
*/
|
||||
function plupload_element_value(&$element, $input = FALSE, $form_state = NULL) {
|
||||
$id = $element['#id'];
|
||||
$files = array();
|
||||
foreach ($form_state['input'] as $key => $value) {
|
||||
if (preg_match('/' . $id . '_([0-9]+)_(.*)/', $key, $reg)) {
|
||||
$i = $reg[1];
|
||||
$key = $reg[2];
|
||||
|
||||
// Only add the keys we expect.
|
||||
if (!in_array($key, array('tmpname', 'name', 'status'))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Munge the submitted file names for security.
|
||||
//
|
||||
// Similar munging is normally done by file_save_upload(), but submit
|
||||
// handlers for forms containing plupload elements can't use
|
||||
// file_save_upload(), for reasons discussed in plupload_test_submit().
|
||||
// So we have to do this for them.
|
||||
//
|
||||
// Note that we do the munging here in the value callback function
|
||||
// (rather than during form validation or elsewhere) because we want to
|
||||
// actually modify the submitted values rather than reject them outright;
|
||||
// file names that require munging can be innocent and do not necessarily
|
||||
// indicate an attempted exploit. Actual validation of the file names is
|
||||
// performed later, in plupload_element_validate().
|
||||
if (in_array($key, array('tmpname', 'name'))) {
|
||||
// Find the whitelist of extensions to use when munging. If there are
|
||||
// none, we'll be adding default ones in plupload_element_process(), so
|
||||
// use those here.
|
||||
if (isset($element['#upload_validators']['file_validate_extensions'][0])) {
|
||||
$extensions = $element['#upload_validators']['file_validate_extensions'][0];
|
||||
}
|
||||
else {
|
||||
$validators = _plupload_default_upload_validators();
|
||||
$extensions = $validators['file_validate_extensions'][0];
|
||||
}
|
||||
$value = file_munge_filename($value, $extensions, FALSE);
|
||||
// To prevent directory traversal issues, make sure the file name does
|
||||
// not contain any directory components in it. (This more properly
|
||||
// belongs in the form validation step, but it's simpler to do here so
|
||||
// that we don't have to deal with the temporary file names during form
|
||||
// validation and can just focus on the final file name.)
|
||||
//
|
||||
// This step is necessary since this module allows a large amount of
|
||||
// flexibility in where its files are placed (for example, they could
|
||||
// be intended for public://subdirectory rather than public://, and we
|
||||
// don't want an attacker to be able to get them back into the top
|
||||
// level of public:// in that case).
|
||||
$value = rtrim(basename($value), '.');
|
||||
|
||||
|
||||
// Based on the same feture from file_save_upload().
|
||||
if (!variable_get('allow_insecure_uploads', 0) && preg_match('/\.(php|pl|py|cgi|asp|js)(\.|$)/i', $value) && (substr($value, -4) != '.txt')) {
|
||||
$value .= '.txt';
|
||||
|
||||
// The .txt extension may not be in the allowed list of extensions.
|
||||
// We have to add it here or else the file upload will fail.
|
||||
if (!empty($extensions)) {
|
||||
$element['#upload_validators']['file_validate_extensions'][0] .= ' txt';
|
||||
drupal_set_message(t('For security reasons, your upload has been renamed to %filename.', array('%filename' => $value)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The temporary file name has to be processed further so it matches what
|
||||
// was used when the file was written; see plupload_handle_uploads().
|
||||
if ($key == 'tmpname') {
|
||||
$value = _plupload_fix_temporary_filename($value);
|
||||
// We also define an extra key 'tmppath' which is useful so that submit
|
||||
// handlers do not need to know which directory plupload stored the
|
||||
// temporary files in before trying to copy them.
|
||||
$files[$i]['tmppath'] = variable_get('plupload_temporary_uri', 'temporary://') . $value;
|
||||
}
|
||||
elseif ($key == 'name') {
|
||||
if (module_exists('transliteration')) {
|
||||
$value = transliteration_clean_filename($value);
|
||||
}
|
||||
}
|
||||
|
||||
// Store the final value in the array we will return.
|
||||
$files[$i][$key] = $value;
|
||||
}
|
||||
}
|
||||
return $files;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process callback (#process) for plupload form element.
|
||||
*/
|
||||
function plupload_element_process($element) {
|
||||
// Start session if not there yet. We need session if we want security
|
||||
// tokens to work properly.
|
||||
if (!drupal_session_started()) {
|
||||
drupal_session_start();
|
||||
}
|
||||
|
||||
if (!isset($element['#upload_validators'])) {
|
||||
$element['#upload_validators'] = array();
|
||||
}
|
||||
$element['#upload_validators'] += _plupload_default_upload_validators();
|
||||
return $element;
|
||||
}
|
||||
|
||||
/**
|
||||
* Element validation handler for a Plupload element.
|
||||
*/
|
||||
function plupload_element_validate($element, &$form_state) {
|
||||
foreach ($element['#value'] as $file_info) {
|
||||
// @todo Here we create a $file object for a file that doesn't exist yet,
|
||||
// because saving the file to its destination is done in a submit handler.
|
||||
// Need more investigation into what else is needed for it to be okay to
|
||||
// call file_validate(). For example, file_validate_size() will not have
|
||||
// access to a meaningful $file->filesize unless we set that here. For
|
||||
// now, we can at least rely on file_validate_extensions() running
|
||||
// successfully.
|
||||
$destination = variable_get('file_default_scheme', 'public') . '://' . $file_info['name'];
|
||||
$file = plupload_file_uri_to_object($destination);
|
||||
foreach (file_validate($file, $element['#upload_validators']) as $error_message) {
|
||||
$message = t('The specified file %name could not be uploaded.', array('%name' => $file->filename));
|
||||
form_error($element, $message . ' ' . $error_message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Pre render (#pre_render) callback to attach JS settings for the element.
|
||||
*/
|
||||
function plupload_element_pre_render($element) {
|
||||
$settings = isset($element['#plupload_settings']) ? $element['#plupload_settings'] : array();
|
||||
|
||||
// The Plupload library supports client-side validation of file extension, so
|
||||
// pass along the information for it to do that. However, as with all client-
|
||||
// side validation, this is a UI enhancement only, and not a replacement for
|
||||
// server-side validation.
|
||||
if (empty($settings['filters']) && isset($element['#upload_validators']['file_validate_extensions'][0])) {
|
||||
$settings['filters'][] = array(
|
||||
// @todo Some runtimes (e.g., flash) require a non-empty title for each
|
||||
// filter, but I don't know what this title is used for. Seems a shame
|
||||
// to hard-code it, but what's a good way to avoid that?
|
||||
'title' => t('Allowed files'),
|
||||
'extensions' => str_replace(' ', ',', $element['#upload_validators']['file_validate_extensions'][0]),
|
||||
);
|
||||
}
|
||||
|
||||
if (empty($element['#description'])) {
|
||||
$element['#description'] = '';
|
||||
}
|
||||
$element['#description'] = theme('file_upload_help', array('description' => $element['#description'], 'upload_validators' => $element['#upload_validators']));
|
||||
|
||||
$element['#attached']['js'][] = array(
|
||||
'type' => 'setting',
|
||||
'data' => array('plupload' => array($element['#id'] => $settings)),
|
||||
);
|
||||
|
||||
return $element;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the path to the plupload library.
|
||||
*/
|
||||
function _plupload_library_path() {
|
||||
return variable_get('plupload_library_path', module_exists('libraries') ? libraries_get_path('plupload') : 'sites/all/libraries/plupload');
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_library().
|
||||
*/
|
||||
function plupload_library() {
|
||||
$library_path = _plupload_library_path();
|
||||
$libraries['plupload'] = array(
|
||||
'title' => 'Plupload',
|
||||
'website' => 'http://www.plupload.com',
|
||||
'version' => '1.5.1.1',
|
||||
'js' => array(
|
||||
// @todo - only add gears JS if gears is an enabled runtime.
|
||||
// $library_path . '/js/gears_init.js' => array(),
|
||||
$library_path . '/js/jquery.plupload.queue/jquery.plupload.queue.js' => array(),
|
||||
$library_path . '/js/plupload.full.js' => array(),
|
||||
0 => array(
|
||||
'type' => 'setting',
|
||||
'data' => array(
|
||||
'plupload' => array(
|
||||
// Element-specific settings get keyed by the element id (see
|
||||
// plupload_element_pre_render()), so put default settings in
|
||||
// '_default' (Drupal element ids do not have underscores, because
|
||||
// they have hyphens instead).
|
||||
'_default' => array(
|
||||
// @todo Provide a settings page for configuring these.
|
||||
'runtimes' => 'html5,flash,html4',
|
||||
'url' => url('plupload-handle-uploads', array('query' => array('plupload_token' => drupal_get_token('plupload-handle-uploads')))),
|
||||
'max_file_size' => file_upload_max_size() . 'b',
|
||||
'chunk_size' => parse_size(ini_get('post_max_size')) . 'b',
|
||||
'unique_names' => TRUE,
|
||||
'flash_swf_url' => file_create_url($library_path . '/js/plupload.flash.swf'),
|
||||
'silverlight_xap_url' => file_create_url($library_path . '/js/plupload.silverlight.xap'),
|
||||
),
|
||||
// The plupload.js integration file in the module folder can do
|
||||
// additional browser checking to remove unsupported runtimes.
|
||||
// This is in addition to what is done by the Plupload library.
|
||||
'_requirements' => array(
|
||||
'html5' => array(
|
||||
// The Plupload library recognizes Firefox 3.5 as supporting
|
||||
// HTML 5, but Firefox 3.5 does not support the HTML 5
|
||||
// "multiple" attribute for file input controls. This makes the
|
||||
// html5 runtime much less appealing, so we treat all Firefox
|
||||
// versions less than 3.6 as ineligible for the html5 runtime.
|
||||
'mozilla' => '1.9.2',
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
if (module_exists('locale')) {
|
||||
$module_path = drupal_get_path('module', 'plupload');
|
||||
$libraries['plupload']['js'][$module_path . '/js/i18n.js'] = array('scope' => 'footer');
|
||||
}
|
||||
|
||||
return $libraries;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback that handles and saves uploaded files.
|
||||
*
|
||||
* This will respond to the URL on which plupoad library will upload files.
|
||||
*/
|
||||
function plupload_handle_uploads() {
|
||||
// @todo: Implement file_validate_size();
|
||||
// Added a variable for this because in HA environments, temporary may need
|
||||
// to be a shared location for this to work.
|
||||
$temp_directory = variable_get('plupload_temporary_uri', 'temporary://');
|
||||
$writable = file_prepare_directory($temp_directory, FILE_CREATE_DIRECTORY);
|
||||
if (!$writable) {
|
||||
die('{"jsonrpc" : "2.0", "error" : {"code": 104, "message": "Failed to open temporary directory."}, "id" : "id"}');
|
||||
}
|
||||
// Try to make sure this is private via htaccess.
|
||||
file_create_htaccess($temp_directory, TRUE);
|
||||
|
||||
// Chunk it?
|
||||
$chunk = isset($_REQUEST["chunk"]) ? $_REQUEST["chunk"] : 0;
|
||||
|
||||
// Get and clean the filename.
|
||||
$file_name = isset($_REQUEST["name"]) ? $_REQUEST["name"] : '';
|
||||
$file_name = _plupload_fix_temporary_filename($file_name);
|
||||
|
||||
// Check the file name for security reasons; it must contain letters, numbers
|
||||
// and underscores followed by a (single) ".tmp" extension. Since this check
|
||||
// is more stringent than the one performed in plupload_element_value(), we
|
||||
// do not need to run the checks performed in that function here. This is
|
||||
// fortunate, because it would be difficult for us to get the correct list of
|
||||
// allowed extensions to pass in to file_munge_filename() from this point in
|
||||
// the code (outside the form API).
|
||||
if (empty($file_name) || !preg_match('/^\w+\.tmp$/', $file_name)) {
|
||||
die('{"jsonrpc" : "2.0", "error" : {"code": 105, "message": "Invalid temporary file name."}, "id" : "id"}');
|
||||
}
|
||||
|
||||
// Look for the content type header.
|
||||
if (isset($_SERVER["HTTP_CONTENT_TYPE"])) {
|
||||
$content_type = $_SERVER["HTTP_CONTENT_TYPE"];
|
||||
}
|
||||
if (isset($_SERVER["CONTENT_TYPE"])) {
|
||||
$content_type = $_SERVER["CONTENT_TYPE"];
|
||||
}
|
||||
|
||||
// Is this a multipart upload?.
|
||||
if (strpos($content_type, "multipart") !== FALSE) {
|
||||
if (isset($_FILES['file']['tmp_name']) && is_uploaded_file($_FILES['file']['tmp_name'])) {
|
||||
// Open temp file.
|
||||
$out = fopen($temp_directory . $file_name, $chunk == 0 ? "wb" : "ab");
|
||||
if ($out) {
|
||||
// Read binary input stream and append it to temp file.
|
||||
$in = fopen($_FILES['file']['tmp_name'], "rb");
|
||||
|
||||
if ($in) {
|
||||
while ($buff = fread($in, 4096)) {
|
||||
fwrite($out, $buff);
|
||||
}
|
||||
fclose($in);
|
||||
}
|
||||
else {
|
||||
die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": "Failed to open input stream."}, "id" : "id"}');
|
||||
}
|
||||
|
||||
fclose($out);
|
||||
drupal_unlink($_FILES['file']['tmp_name']);
|
||||
}
|
||||
else {
|
||||
die('{"jsonrpc" : "2.0", "error" : {"code": 102, "message": "Failed to open output stream."}, "id" : "id"}');
|
||||
}
|
||||
}
|
||||
else {
|
||||
die('{"jsonrpc" : "2.0", "error" : {"code": 103, "message": "Failed to move uploaded file."}, "id" : "id"}');
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Open temp file.
|
||||
$out = fopen($temp_directory . $file_name, $chunk == 0 ? "wb" : "ab");
|
||||
if ($out) {
|
||||
// Read binary input stream and append it to temp file.
|
||||
$in = fopen("php://input", "rb");
|
||||
|
||||
if ($in) {
|
||||
while ($buff = fread($in, 4096)) {
|
||||
fwrite($out, $buff);
|
||||
}
|
||||
fclose($in);
|
||||
}
|
||||
else {
|
||||
die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": "Failed to open input stream."}, "id" : "id"}');
|
||||
}
|
||||
|
||||
fclose($out);
|
||||
}
|
||||
else {
|
||||
die('{"jsonrpc" : "2.0", "error" : {"code": 102, "message": "Failed to open output stream."}, "id" : "id"}');
|
||||
}
|
||||
}
|
||||
|
||||
// Return JSON-RPC response.
|
||||
die('{"jsonrpc" : "2.0", "result" : null, "id" : "id"}');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a file object which can be passed to file_save().
|
||||
*
|
||||
* @param string $uri
|
||||
* A string containing the URI, path, or filename.
|
||||
*
|
||||
* @return boolean
|
||||
* A file object, or FALSE on error.
|
||||
*
|
||||
* @todo Replace with calls to this function with file_uri_to_object() when
|
||||
* http://drupal.org/node/685818 is fixed in core.
|
||||
*/
|
||||
function plupload_file_uri_to_object($uri) {
|
||||
global $user;
|
||||
$uri = file_stream_wrapper_uri_normalize($uri);
|
||||
$wrapper = file_stream_wrapper_get_instance_by_uri($uri);
|
||||
$file = new StdClass();
|
||||
$file->uid = $user->uid;
|
||||
$file->filename = basename($uri);
|
||||
$file->uri = $uri;
|
||||
$file->filemime = file_get_mimetype($uri);
|
||||
// This is gagged because some uris will not support it.
|
||||
$file->filesize = @filesize($uri);
|
||||
$file->timestamp = REQUEST_TIME;
|
||||
$file->status = FILE_STATUS_PERMANENT;
|
||||
return $file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fix the temporary filename provided by the plupload library.
|
||||
*
|
||||
* Newer versions of the plupload JavaScript library upload temporary files
|
||||
* with names that contain the intended final prefix of the uploaded file
|
||||
* (e.g., ".jpg" or ".png"). Older versions of the plupload library always use
|
||||
* ".tmp" as the temporary file extension.
|
||||
*
|
||||
* We prefer the latter behavior, since although the plupload temporary
|
||||
* directory where these files live is always expected to be private (and we
|
||||
* protect it via .htaccess; see plupload_handle_uploads()), in case it ever
|
||||
* isn't we don't want people to be able to upload files with an arbitrary
|
||||
* extension into that directory.
|
||||
*
|
||||
* This function therefore fixes the plupload temporary filenames so that they
|
||||
* will always use a ".tmp" extension.
|
||||
*
|
||||
* @param string $filename
|
||||
* The original temporary filename provided by the plupload library.
|
||||
*
|
||||
* @return string
|
||||
* The corrected temporary filename, with a ".tmp" extension replacing the
|
||||
* original one.
|
||||
*/
|
||||
function _plupload_fix_temporary_filename($filename) {
|
||||
$pos = strpos($filename, '.');
|
||||
if ($pos !== FALSE) {
|
||||
$filename = substr_replace($filename, '.tmp', $pos);
|
||||
}
|
||||
return $filename;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to add defaults to $element['#upload_validators'].
|
||||
*/
|
||||
function _plupload_default_upload_validators() {
|
||||
return array(
|
||||
// See file_save_upload() for details.
|
||||
'file_validate_extensions' => array('jpg jpeg gif png txt doc xls pdf ppt pps odt ods odp'),
|
||||
);
|
||||
}
|