first import

This commit is contained in:
Bachir Soussi Chiadmi
2015-04-08 11:40:19 +02:00
commit 1bc61b12ad
8435 changed files with 1582817 additions and 0 deletions

View 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.

View File

@@ -0,0 +1,220 @@
sfwupload Module
================================================================================
DESCRIPTION:
--------------------------------------------------------------------------------
The SWFUpload module provides an CCK widget for filefield and handles the upload
through javascript/flash. It depends on the SWFUpload library which makes it
possible to upload multiple file at once.
For developers the module provides a hook function. Using this hook function
developers can alter the way the widget is presented, op hook in to the file
upload process.
INSTALLATION:
--------------------------------------------------------------------------------
1. Download the FileField module.
(http://drupal.org/project/filefield)
2. Download the jQuery Plugin Handler (jQp) module. This module is required for
loading the SWFUpload javascript library.
(http://drupal.org/project/jqp)
3. Place both modules, as well as the SWFUpload module, in your module
directory.
(sites/all/modules)
4. If you do not have created a 'libraries' directory yet, create one.
(sites/all/libraries)
5. Create a new directory called 'swfupload' inside the 'libraries' folder.
(sites/all/libraries)
6. Download the SWFUpload 2.2.0.1 release.
(http://code.google.com/p/swfupload/downloads/list)
7. Copy the files 'swfupload.swf' and 'swfupload.js' to the swfupload folder
inside the libraries folder. The end result will read:
sites/all/libraries/swfupload/swfupload.js
sites/all/libraries/swfupload/swfupload.swf
8. Enable this module by navigating to:
admin/build/modules
9. Ensure the library is available by visiting:
admin/build/jqp/swfupload/
USAGE:
--------------------------------------------------------------------------------
Create a new file field in through CCK's interface. Visit Administer -> Content
management -> Content types (admin/content/types), then click Manage fields on
the type you want to add an SWFUpload field. Select "File" as the field type and
"SWFUpload" as the widget type to create a new field.
On the field configuration screen set the "Permitted upload file extensions"
to include the image types you will allow users to upload.
Grant the permission to "upload files with swfupload" to the appropriate roles.
API:
--------------------------------------------------------------------------------
Developers can take the advantage of the hook function hook_swfupload(). Using
this function developers have access to alter the way the files are displayed,
as well as how file uploads are processed.
HOOK_SWFUPLOAD():
DEFINITION:
hook_swfupload(&$file, $op, &$instance, $widget)
DESCRIPTION:
Provide other modules a hook to change the data for the swfupload scripts.
Modules can change the default provided fields, customize the way files are
uploaded and change the type of swfupload (table or button).
PARAMETERS:
$file: The file object in its different states.
$op: What kind of action is being performed. Possible values:
'init': The swfupload is being initialized. Here you can change the instance
object in order to define other javascript callback functions, or to
change the way the files are displayed.
'move_uploaded_file': The swfupload requests an upload. Here you can alter
the file object in order to change it's filename or the destination
folder. You can also change the validation functions which are passed
to file_save_upload(). The file object will look something similar
like this:
$file = (object) array(
'validators' => array(
'file_validate_extensions => 'jpg jpeg gif png txt',
'filefield_validate_image_resolution' => array('800x600', '100x100'),
'file_validate_size' => array($widget->max_filesize_per_file, $widget->max_filesize_per_file),
),
'file_path' => 'files/'
);
'upload_complete': The upload is complete. Using the hook_function in this
state, the file can be copied, modified or you can do some database
stuff. The file object will look something similar like this:
$file = (object) array(
'filename' => 'Image1.png',
'filepath' => 'files/Image1_3.png',
'filemime' => 'image/png',
'source' => 'upload',
'destination' => 'files/Image1_3.png',
'filesize' => 220567,
'uid' => '3',
'status' => 0,
'timestamp' => 1227182505,
'fid' => '2468' }
),
'filepath' => 'files/'
);
$instance: The instance object in its different states. When $op is 'init' the
instance can be altered in order to change the callback functions or to change
the way the upload module displayes files. When $op is 'move_uploaded_file' or
'upload_complete', the instance object can be used as a reference.
The reference object on init:
// The type of the instance. Currently only table is supported
$instance->type = 'table';
// Javascript callback functions
$instance->callbacks = array(
'swfupload_loaded_handler' => 'ref.swfUploadLoaded',
'file_queued_handler' => 'ref.fileQueued',
'queue_complete_handler' => 'ref.queueComplete',
'file_queue_error_handler' => 'ref.fileQueueError',
'file_dialog_complete_handler' => 'ref.dialogComplete',
'upload_success_handler' => 'ref.uploadSuccess',
'upload_progress_handler' => 'ref.uploadProgress',
'upload_error_handler' => 'ref.uploadError',
'upload_complete_handler' => 'ref.uploadComplete',
'init_complete_handler' => 'ref.initComplete',
);
// The $instance->elements array represents all elements (or columns) which are displayed on added files.
// Each element can be changed. Javascript will render the proper markup.
// By default the elements below are used for each added file, however by changing the widget settings, an 'alt', 'title', 'description' or 'display' column can be added.
$instance->elements = array(
'drag' => array(
'class' => 'drag first indentation',
'type' => 'drag',
'colspan' => 3,
'title' => t('Filename'),
'add_separator' => TRUE,
),
'icon' => array(
'type' => 'icon',
'class' => 'icon',
),
'filename' => array(
'type' => 'markup',
'value' => '[filename]',
'class' => 'text title',
),
);
EXAMPLE:
/**
* Implements hook_swfupload().
*/
function MODULENAME_swfupload(&$file, $op, &$instance, $widget) {
switch ($op) {
case 'init':
// Add a custom callback function to be executed after the scripts have
// been initialized.
$instance->callbacks['init_complete_handler'] = 'myCustomCallbackFunction';
// Add a custom editabe tabledrawer.
$instance->elements['test'] => array(
'class' => 'my-class', // The class for the td.
'type' => 'text', // An editable textfield will be added. Values will be saved!
'colspan' => 2, // Colspan for this td
'title' => t('Description'), // This will be used in the th
'add_separator' => TRUE, // Whether or not to put a separator between the colums in the thead.
'contains_progressbar' = TRUE, // Whether or not the progressbar can be put here during upload.
);
break;
case 'move_uploaded_file':
global $user;
$file->filepath = "files/$user->uid/"; // Files will be stored in an user folder
break;
case 'upload_complete':
db_query("INSERT INTO {mymoduletable} (fid, filename) VALUES ('%s', '%s')", $file->fid, $file->filename);
break;
}
}
BUGS:
--------------------------------------------------------------------------------
1. If the swfupload is loaded inside a collapsed fieldset, Firefox occasionally
crashes when the fieldset expanded.
2. If you're getting 'IO Error #2038' errors, try pasting the following in your
.htaccess file, or visit http://swfupload.org/forum/generaldiscussion/92.
SecFilterEngine Off
SecFilterScanPOST Off
KUDOS:
--------------------------------------------------------------------------------
Special thanks to Nathan Haug (quicksketch) for writing ImageField and helping
me out developing the SWFUpload module, and Morten Nielsen (minus) for
sponsoring the module.

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 584 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 170 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 795 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 888 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 868 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 585 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 808 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 166 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 284 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 130 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 150 B

View File

@@ -0,0 +1,952 @@
// $Id: jw_player.js, v 0.1, 2009/07/28 12:11:24, skilip Exp $;
(function ($) {
/**
*
*/
function SWFU(id, settings) {
var ref = {};
ref.settings = {};
ref.ajax_settings = {};
ref.queue = {};
ref.stats = {};
ref.instance = {};
ref.upload_stack_length = 0;
ref.max_queue_size = 0;
ref.upload_stack = {};
ref.upload_stack_obj;
ref.upload_button_obj;
ref.upload_stack_size = 0;
ref.wrapper_obj;
ref.wrapper_id;
ref.num_elements;
ref.key_pressed;
ref.message_wrapper_obj;
ref.messages_timeout;
/**
*
*/
ref.init = function() {
ref.settings = settings;
ref.upload_button_obj = $('#' + ref.settings.upload_button_id);
ref.instance = {name:settings.file_post_name};
ref.ajax_settings = {
type:"post",
url:ref.settings.upload_url,
data:{
op:'init',
file_path:ref.settings.post_params.file_path,
instance:ref.toJson(ref.instance),
instance_settings:ref.settings.post_params.instance_settings
},
success:function(result) {
ref.ajaxResponse(result);
}
};
ref.prepareSWFButton();
// Get the instance data by an AJAX request in order to let other modules change the callbacks and elements for this instance (using hook_swfupload);
$.ajax(ref.ajax_settings);
};
/**
* Prepares the swfupload button.
*/
ref.prepareSWFButton = function() {
// Create a copy of the button to get it's dimensions.
// If we'd use the original button, we could end up with dimensions equal to 0px when the button is inside a hidden fieldset.
var tmp_button = ref.upload_button_obj.clone().css({'position':'absolute'}).prependTo('body');
// Set the dimensions of the swf so it matches exactly the dimensions of the upload button
// swfupload.swf will be placed exactly over the upload button
ref.settings.button_width = (tmp_button.find('.left').width() + tmp_button.find('.center').width() + tmp_button.find('.right').width());
ref.settings.button_height = tmp_button.find('.center').height();
tmp_button.remove();
// Add the other button settings to the settings object
ref.settings.button_placeholder_id = ref.settings.file_post_name + '-swfwrapper';
ref.settings.button_window_mode = SWFUpload.WINDOW_MODE.TRANSPARENT;
ref.settings.button_cursor = SWFUpload.CURSOR.HAND;
};
/**
* Creates a hidden input field which will contain a JSON formatted string containing all uploaded files
*/
ref.createStackObj = function() {
var upload_stack_value = settings.custom_settings.upload_stack_value;
ref.max_queue_size = settings.custom_settings.max_queue_size;
ref.upload_stack_obj = $('<input type="hidden" />').attr('name', ref.instance.name).val(upload_stack_value).prependTo(ref.upload_button_obj);
ref.upload_stack = jQuery.parseJSON(upload_stack_value);
ref.upload_stack_length = ref.objectLength(ref.upload_stack);
};
/**
*
*/
ref.newSWFUpload = function() {
ref.swfu = new SWFUpload(ref.settings);
};
/**
*
*/
ref.ajaxResponse = function(result) {
var result = jQuery.parseJSON(result);
switch (result.op) {
case 'init':
ref.instance = result.instance;
ref.num_elements = ref.objectLength(ref.instance.elements);
$.each(result.instance.callbacks, function(setting, callback) {
ref.settings[setting] = eval(callback);
});
ref.newSWFUpload();
ref.settings.init_complete_handler(result);
break;
};
ref.addEventHandlers(result.op);
};
/**
* Custom function for when the initialization is complete
* This event handler is defined in swfupload.module as an instance callback function
*/
ref.initComplete = function(result) {
ref.createWrapper(result.instance.name);
ref.createStackObj();
ref.addStoredFiles();
// Enable the upload button if the current stack is smaller than the allowed stack size,
// or when there's no limit at all.
if ((ref.settings.file_upload_limit && (ref.upload_stack_length < ref.settings.file_upload_limit)) || ref.settings.file_upload_limit === 0) {
ref.upload_button_obj.removeClass('disabled').css({opacity:1});
}
else {
ref.upload_button_obj.addClass('disabled').css({opacity:0.4});
};
};
/**
* This will process all file elements stored in the upload stack.
* The upload represents all files submitted in the upload form.
* For all files in the stack, a file element will be added to the wrapper using ref.addFileItem().
*/
ref.addStoredFiles = function() {
for(var i in ref.upload_stack) {
if (ref.upload_stack[i] == 0) {
break;
};
ref.upload_stack[i].id = i;
ref.upload_stack[i].fid = i;
ref.upload_stack[i].extension = ref.getExtension(ref.upload_stack[i].filename);
ref.addFileItem(ref.upload_stack[i]);
// Adjust the bytes in the stack.
ref.upload_stack_size += parseInt(ref.upload_stack[i].filesize);
};
ref.addEventHandlers('drag_enable');
};
/**
* Places the wrapper markup above the upload button
* Depending on what type isset by the instance, a table or a list element is created.
*/
ref.createWrapper = function(field_name) {
var use_header = false;
var element;
if (ref.num_elements > 1 && ref.instance.type == 'table') {
// First we'll check if we need to create a header
for (var name in ref.instance.elements) {
if (ref.instance.elements[name].title) {
use_header = true;
};
};
ref.wrapper_id = 'swfupload_file_wrapper-' + field_name.replace(/[\[\]]/g, '-');
ref.wrapper_obj = $('<table />').attr({'id': ref.wrapper_id, 'class':'swfupload'});
if (use_header) {
ref.wrapper_obj.append($('<thead />').append(ref.tableRow(true)));
};
ref.wrapper_obj.append($('<tbody />').append(ref.tableRow()));
ref.upload_button_obj.before(ref.wrapper_obj);
if (!Drupal.settings.tableDrag) {
Drupal.settings.tableDrag = {};
};
Drupal.settings.tableDrag[ref.wrapper_id] = {};
};
};
/**
* Creates or changes a tablerow
* @param header Boolean Wheter or not the tablerow should contain th's. If sety to false, td's will be generated.
* @param file Object A completed file object
* - If this is not set, a row is created including the progressbar, which replaces the td's with contains_progressbar set to true.
* - If file is set, the progressbar will be replaced with the appropriate td's
*/
ref.tableRow = function(header, file) {
var counter = 0;
var colspan = 0;
var fid = (file) ? file.fid : 0;
var progress_td_counter = 0;
var element, colum, content, input, progress_td, elem_value, value;
var tr = (file) ? $('#' + file.fid) : $('<tr />');
var wrapper = $('<div />').addClass('wrapper');
var left_span = $('<div />').addClass('left').html('&nbsp;');
var center_span = $('<div />').addClass('center');
var right_span = $('<div />').addClass('right').html('&nbsp;');
// A tablerow will be created containing all elements defined in ref.instance.elements.
// If file is set, all elements will be skipped exept the ones with 'contains_progressbar'
// If file isn't set, this tablerow will be hidden.
for (var name in ref.instance.elements) {
counter++;
element = ref.instance.elements[name];
if (file) {
if(!element.contains_progressbar) {
// The current td doesn't have to be replaced.
// We only need to replace fid of the id and name of the input field
tr.find('#edit-' + name + '_0').attr({'name':name +'_' + fid, 'id':'edit-' + name + '_' + fid});
continue;
};
}
else {
if (!header && element.contains_progressbar) {
if (!progress_td) {
progress_td = $('<td />').addClass('progress').append($('<div />').addClass('sfwupload-list-progressbar').append($('<div />').addClass('sfwupload-list-progressbar-status')).append($('<div />').addClass('sfwupload-list-progressbar-glow'))).appendTo(tr);
};
progress_td_counter++;
continue;
};
};
column = $((header ? '<th />' : '<td />'));
content = wrapper.clone().appendTo(column);
input = $((element.type == 'textarea' ? '<textarea />' : '<input type="' + element.type + '" />')).attr({'name':name +'_' + fid, 'id':'edit-' + name + '_' + fid}).addClass('form-' + element.type);
if (header) {
// Keep track of colspans
if (colspan > 0) colspan--;
if (element.colspan) {
colspan = element.colspan;
}
else if (colspan !== 0) {
continue;
};
// Add the colspan if set.
if (element.colspan) {
column.attr({'colSpan':element.colspan});
};
// Add a separator only if we're not dealing with the first or last column
if (counter !== ref.num_elements && (counter + (colspan - 1) !== ref.num_elements) && element.add_separator) {
content.append(left_span.clone()).append(right_span.clone());
};
content.append(center_span.clone().html((element.title ? element.title : '&nbsp;')));
}
else {
elem_value = (element.value) || element.default_value;
// Create the content for this td
// Depending on the type the appropriate input field is appended to store the values of this type
switch (element.type) {
case 'icon':
case 'cancel':
content.append($('<div />').addClass('sfwupload-list-' + (element.type == 'icon' ? 'mime' : element.type)));
break;
case 'textfield':
case 'textarea':
value = (file ? ref.replaceMacros(elem_value, file) : elem_value);
content.append($('<span />').html((value !== '' ? value : '&nbsp;'))).append(input.css({'display':'none'}).val((value ? value : '')));
break;
case 'checkbox':
value = (file[name] !== undefined) ? (typeof(file[name]) == 'string' ? (file[name] == '1') : file[name]) : elem_value;
// For IE we need to check the checkbox after the content has been added to the tr.
// We'll temporarily store it's value in a classname
content.append(input.addClass('checkbox ' + (value ? 'checked' : '')));
break;
case 'markup':
value = (file) ? (file[name] !== undefined) ? file[name] : ref.replaceMacros(elem_value, file) : elem_value;
content.append($('<div />').addClass('swfupload-markup').attr('id', 'swfupload-markup-' + name).html(value));
break;
default:
break;
};
};
// Add a classname if set.
if (element.classname) {
column.addClass(element.classname);
};
if (file && element.contains_progressbar) {
column.insertBefore(tr.find('td.progress'));
}
else {
tr.append(column);
};
};
if (!header && !file) {
// Hide the tablerow
tr.addClass('hidden');
};
if (progress_td) {
progress_td.attr({'colSpan':progress_td_counter});
};
// Update the checked value of all added checkboxes
tr.find('input.checkbox').each(function() {
$(this).attr('checked', $(this).hasClass('checked'));
});
if (file) {
tr.addClass('processed').find('td.progress').remove();
}
else {
// Create borders
var border = $(header ? '<th />' : '<td />').addClass('border').append($('<img />').attr({'src':Drupal.settings.basePath + ref.settings.module_path + '/images/spacer.gif'}).css({'width':'1px'}));
tr.prepend(border.clone()).append(border);
return tr;
};
};
/**
* A file has been selected. This function creates the markup referring to the new file object
*/
ref.addFileItem = function(file) {
// Create the markup for the new file by copying the hidden template
var new_file_obj = ref.wrapper_obj.find('.hidden').clone().attr({'id':file.id}).appendTo(ref.wrapper_obj);
var dom_obj, value, elem_value;
// Remove tabledrag elements
new_file_obj.find('a.tabledrag-handle').remove();
// If it is a file earlier stored (a file in the upload_stack), remove it's progressbar.
if (file.filestatus !== -1) {
ref.tableRow(false, file);
};
// Replace macro's
for (var name in ref.instance.elements) {
dom_obj = new_file_obj.find('#edit-' + name + '_' + (file.fid || '0') + ', #swfupload-markup-' + name);
if (dom_obj.size() > 0) {
elem_value = (ref.instance.elements[name].value) || ref.instance.elements[name].default_value;
value = (file[name] !== undefined) ? file[name] : ref.replaceMacros(elem_value, file);
if (dom_obj[0].tagName.toLowerCase() == 'input' || dom_obj[0].tagName.toLowerCase() == 'textarea') {
dom_obj.val(value);
}
else {
dom_obj.html(value).show();
};
// If the inputfield is hidden, we're dealing with a string.
// Look if there is a span of which the text can be replaced
if (dom_obj.css('display') == 'none') {
dom_obj.parent().find('span').text(value);
};
};
};
if (file.thumb) {
// Attach the thumbnail image
new_file_obj.find('.sfwupload-list-mime').css({'background-image': 'url(' + file.thumb + ')'});
}
else {
// Add the extension to the mime icon
new_file_obj.find('.sfwupload-list-mime').addClass(file.extension);
};
// Fix transparency for IE6
if ($.cssPNGFix) {
new_file_obj.find('.sfwupload-list-mime').cssPNGFix();
};
new_file_obj.removeClass('hidden').addClass('draggable');
ref.addEventHandlers((file.filestatus == -1 ? 'file_queued' : 'file_added'), file);
};
/**
* Attaches all event handlers to the loaded markup
*/
ref.addEventHandlers = function(op, file) {
switch (op) {
case 'flash_loaded':
ref.upload_button_obj.find('.swfupload-wrapper .swfupload').mousedown(function() {
$(this).parent().parent().addClass('active');
}).mouseup(function() {
$(this).parent().parent().removeClass('active');
});
break;
case 'file_queued':
$('#' + file.id).find('.sfwupload-list-cancel').click(function() {
ref.cancelUpload(file);
});
break;
case 'file_added':
var file_element_obj = $('#' + file.fid);
file_element_obj.find('.sfwupload-list-cancel').unbind('click').click(function() {
ref.removeFileItem(file);
}).disableTextSelect();
file_element_obj.find('input:checkbox').bind('click', function() {
ref.updateStack(file);
});
file_element_obj.find('input:text, textarea').blur(function() {
ref.toggleInput($(this), false, file);
}).keydown(function(e) {
ref.key_pressed = e.keyCode;
if ((e.keyCode == 27) || (e.keyCode == 13 && $(this).get(0).tagName.toLowerCase() !== 'textarea')) {
$(this).blur();
return false;
};
}).parents('td').dblclick(function() {
ref.toggleInput($(this).find('span'), true, file);
}).find('.wrapper').append($('<a href="#" />').text(Drupal.t('edit')).addClass('toggle-editable').click(function() {
ref.toggleInput($(this).parent().find('span'), true, file);
return false;
}));
break;
case 'drag_enable':
// Attach the tabledrag behavior
// This will we only executed once.
Drupal.attachBehaviors(ref.wrapper_obj.parent());
$('.tabledrag-toggle-weight-wrapper', ref.wrapper_obj.parent()).hide();
$('tbody tr', ref.wrapper_obj).not('.hidden, .tabledrag-handle-swfupload-moved').each(function() {
if (!$('a.tabledrag-handle', $(this)).size()) {
Drupal.tableDrag[ref.wrapper_id].makeDraggable(this);
};
$('a.tabledrag-handle', $(this)).not('.tabledrag-handle-swfupload-moved').each(function() {
$(this).appendTo($(this).parents('tr').addClass('tabledrag-handle-swfupload-moved').find('td.drag div.wrapper')).bind('mousedown', function() {
$(this).parents('tr').addClass('dragging');
});
});
});
$(document).unbind('mouseup', ref.tableDragStop).bind('mouseup', ref.tableDragStop);
break;
default:
break;
};
};
/**
* Triggered when the user has stopped dragging a tablerow.
*/
ref.tableDragStop = function() {
$('tr', ref.wrapper_obj).removeClass('dragging');
$(ref.wrapper_obj).parent().children('.warning').css({'visibility':'hidden'}).remove();
ref.updateStack();
};
/**
* Toggles editability of text spans inside tablerows
*/
ref.toggleInput = function(obj, start, file) {
obj.hide().parent().toggleClass('editable-enabled');
if (start) {
obj.hide().parent().find('input:text, textarea').show().focus().select();
}
else {
if (ref.key_pressed == 27) {
obj.val(obj.parent().find('span').html()).hide().parent().find('span').show();
return;
};
var value = obj.val();
if (value == '') {
obj.hide().parent().find('span').html('&nbsp;').show();
}
else {
obj.hide().parent().find('span').text((value == '&nbsp;' ? '' : value)).show();
};
};
ref.updateStack(file);
};
/**
* Launched when the swf has been loaded.
*/
ref.swfUploadLoaded = function() {
// Update the stats object in order to let SWFUpload know we've already got some files stored
ref.swfu.setStats({successful_uploads: ref.upload_stack_length});
ref.addEventHandlers('flash_loaded');
};
/**
* The file(s) have been selected.
*/
ref.dialogComplete = function(files_selected, files_queued) {
if (ref.settings.file_upload_limit && ref.settings.file_upload_limit !== 0 && (files_selected > ref.settings.file_upload_limit)) {
ref.displayMessage(Drupal.t('You can upload only !num !file!', {'!num':ref.settings.file_upload_limit, '!file': Drupal.formatPlural(ref.settings.file_upload_limit, 'file', 'files')}), 'error');
}
else {
ref.uploadNextInQueue();
};
};
/**
* The file(s) have been selected by the user and added to the upload queue
*/
ref.fileQueued = function(file) {
if (ref.settings.file_upload_limit && ref.settings.file_upload_limit !== 0) {
// Check if the queued file(s) do not exceed the max number of files
var stats = ref.swfu.getStats();
if ((ref.upload_stack_length + stats.files_queued) > ref.settings.file_upload_limit) {
ref.swfu.cancelUpload(file.id);
var queue_space = (ref.settings.file_upload_limit - ref.upload_stack_length);
if (queue_space == 0) {
ref.displayMessage(Drupal.t('You are not allowed to add more than !num !file!', {'!num':ref.settings.file_upload_limit, '!file': Drupal.formatPlural(ref.settings.file_upload_limit, 'file', 'files')}), 'error');
}
else {
ref.displayMessage(Drupal.t('You can upload only !num more !file!', {'!num':queue_space, '!file':Drupal.formatPlural(queue_space, 'file', 'files')}), 'error');
};
return;
};
};
if (ref.max_queue_size && ref.max_queue_size !== 0) {
// Check if the new file does not exceed the max queue size
if ((ref.upload_stack_size + file.size) > ref.max_queue_size) {
var max_queue_mbs = ref.getMbs(ref.max_queue_size);
var file_mbs = ((file.size / 1024) / 1024);
ref.swfu.cancelUpload(file.id);
ref.displayMessage(Drupal.t('The file size (!num1 MB) exceeds the upload size (!num2 MB) for this page!', {'!num1':file_mbs.toFixed(2), '!num2':max_queue_mbs.toFixed(2)}), 'error');
return;
};
};
// No problems found, add the new file to the stack.
file.extension = ref.getExtension(file.name);
ref.queue[file.id] = file;
ref.addFileItem(file);
};
/**
* Responds on file queue errors
*/
ref.fileQueueError = function(file, code, message) {
switch (code) {
case -110: // The file selected is too large
var max_file_mbs = ref.getMbs(ref.settings.file_size_limit);
var file_mbs = ((file.size / 1024) / 1024);
ref.displayMessage(Drupal.t('The file size (!num1 MB) exceeds the file size limit (!num2 MB)!', {'!num1':file_mbs.toFixed(2), '!num2':max_file_mbs.toFixed(2)}), 'error');
break;
default:
break;
};
};
/**
* Calculates the MB's from a given string
*/
ref.getMbs = function(size) {
// B, KB, MB and GB
if (size.indexOf('MB') > -1) {
return parseInt(size);
}
else if (size.indexOf('GB') > -1) {
return (parseInt(size) * 1024);
}
else if (size.indexOf('KB') > -1) {
return (parseInt(size) / 1024);
}
else if (size.indexOf('B') > -1) {
return ((parseInt(size) / 1024) / 1024);
};
return false;
};
/**
* Displays messages
*/
ref.displayMessage = function(messages, type) {
if (typeof(messages) == 'object') {
var multiple = (messages.length > 1);
var messages_tmp = (multiple ? '<ul>' : '');
for (var i in messages) {
messages_tmp += (multiple ? '<li>' + messages[i] + '</li>' : messages[i]);
};
messages = (multiple ? messages_tmp + '</ul>' : messages_tmp);
};
if (!ref.message_wrapper_obj) {
ref.message_wrapper_obj = $('<div />').addClass('swfupload-messages').insertAfter(ref.wrapper_obj);
ref.messages_timeout = setTimeout(function() {ref.hideMessages();}, 5000);
};
if (!$('div.' + type, ref.message_wrapper_obj).size()) {
ref.message_wrapper_obj.append($('<div />').css({'height':'auto', 'opacity':1}).addClass('messages ' + type).html(messages));
}
else {
// The messagewrapper already exists. Add the new message to the wrapper and reset the timeout.
// Check if the message isn't already displayed
if (ref.message_wrapper_obj.html().indexOf(messages) > -1) {
return;
};
// If the new type differs from the current type, we'll remove the old message.
if ((ref.message_wrapper_obj.hasClass('status') && type !== 'status') || (ref.message_wrapper_obj.hasClass('error') && type !== 'error')) {
ref.message_wrapper_obj.removeClass('status error').addClass(type).html(messages);
}
else {
ref.message_wrapper_obj.append('<br />' + messages);
};
clearInterval(ref.messages_timeout);
ref.messages_timeout = setTimeout(function() {ref.hideMessages();}, 5000);
};
};
/**
* Slowly hides the messages wrapper
*/
ref.hideMessages = function() {
ref.message_wrapper_obj.animate({'height':'0px', 'opacity':0}, 'slow', function() {
ref.message_wrapper_obj.remove();
ref.message_wrapper_obj = false;
});
};
/**
* Triggers a new upload.
*/
ref.uploadNextInQueue = function() {
try {
ref.swfu.startUpload();
}
catch (err) {
ref.swfu.debug(err);
};
};
/**
* Adjusts the progress indicator.
*/
ref.uploadProgress = function(file, complete, total) {
// We don't want this one to end up to 100% when all bytes are loaded. The progressbar will have an width of 100% on uploadFileComplete
var done = Math.round((96 / total) * complete);
$('#' + file.id + ' .sfwupload-list-progressbar-status').css({'width': done + '%'});
};
/**
* Handles upload errors
*/
ref.uploadError = function(file, code, message) {
// Check for messages which can be handled as 'status' messages
switch (code) {
case -240:
ref.displayMessage(Drupal.t('The upload limit (!num) has been reached!', {'!num': ref.settings.file_upload_limit}), 'status');
return;
case -200:
message = Drupal.t('Server error!');
};
// Give the user some visual indicators of the event
$('#' + file.id + ' .sfwupload-list-progressbar').addClass('stopped').find('.sfwupload-list-progressbar-status').css({'width':'100%'});
$('#' + file.id + ' .sfwupload-list-progressbar-glow').append((typeof(message) == 'object' ? message[0] : message));
// If a file is set, we need to remove the added file DOM element
if (file) {
setTimeout(function() {
ref.removeFileItem(file);
}, 2000);
};
};
/**
* Triggered after the upload is succesfully completed.
*/
ref.uploadComplete = function(file) {
if (ref.queue[file.id] && !ref.queue[file.id].cancelled) {
setTimeout(function() {
$('#' + ref.queue[file.id].fid).find('.sfwupload-list-progressbar').animate({'opacity':0}, "slow", function() {
file.fid = ref.queue[file.id].fid;
ref.tableRow(false, file);
ref.updateStack(file);
ref.addEventHandlers('file_added', file);
if (ref.queue[file.id].thumb) {
$('.sfwupload-list-mime', $('#' + ref.queue[file.id].fid)).css({'background-image': 'url(' + ref.queue[file.id].thumb + ')'});
};
ref.upload_button_obj.removeClass('swfupload-error');
});
}, 1000);
};
ref.uploadNextInQueue();
};
/**
* Retrieves the data returned by the server
*/
ref.uploadSuccess = function(file, server_data) {
var server_data = jQuery.parseJSON(server_data);
// Check for messages returned by the server.
if (server_data.messages) {
// Check if the server returned status messages
if (server_data.messages) {
for (var type in server_data.messages) {
if (type !== 'swfupload_error') {
ref.displayMessage(server_data.messages[type], type);
};
};
};
// Check if the server returned an error
if (server_data.messages.swfupload_error) {
ref.uploadError(file, null, server_data.messages.swfupload_error);
ref.queue[file.id].cancelled = true;
return;
};
};
// No errors. Complete the fileupload.
ref.queue[file.id].fid = server_data.file.fid;
$('#' + file.id).attr({'id':server_data.file.fid}).find('.sfwupload-list-progressbar-status').css({'width':'100%'}).parent().addClass('complete');
if (server_data.file.thumb) {
ref.queue[file.id].thumb = server_data.file.thumb;
};
};
/**
* Updates the value of the hidden input field which stores all uploaded files
*/
ref.updateStack = function(file) {
var fid, input_field, element;
var old_upload_stack = ref.upload_stack;
var total_size = 0;
ref.upload_stack = {};
ref.wrapper_obj.find('.processed').each(function() {
fid = $(this).attr('id');
// If no file is secified, the function is called after sorting
// There are no new values so the file object is not needed
// We only need to change the order of the stack
if (!file) {
ref.upload_stack[fid] = old_upload_stack[fid];
}
else {
ref.upload_stack[fid] = {filename:file.filename || file.name, fid:fid};
total_size += parseInt(file.size);
for (var name in ref.instance.elements) {
input_field = $('#edit-' + name + '_' + fid);
if (input_field.size() !== 0) {
ref.upload_stack[fid][name] = (input_field.attr('type') == 'checkbox') ? input_field.attr('checked') : input_field.val();
};
};
};
});
ref.upload_stack_size = total_size;
ref.upload_stack_length = ref.objectLength(ref.upload_stack);
ref.upload_stack_obj.val(ref.toJson(ref.upload_stack));
ref.addEventHandlers('drag_enable');
if ((ref.settings.file_upload_limit > ref.upload_stack_length) || ref.settings.file_upload_limit === 0) {
ref.upload_button_obj.removeClass('disabled').css({opacity:1});
}
else {
ref.upload_button_obj.addClass('disabled').css({opacity:0.4});
};
};
/**
* Aborts a file upload
*/
ref.cancelUpload = function(file) {
// Check if the file is still being uploaded.
if (ref.swfu.getFile(file.id)) {
// Abort the upload
ref.swfu.cancelUpload(file.id);
ref.queue[file.id].cancelled = true;
setTimeout(function() {
ref.removeFileItem(file);
}, 1000);
};
};
/**
* Removes a file form the list
*/
ref.removeFileItem = function(file) {
var file_tr = $('#' + (file.fid ? file.fid : file.id)).removeClass('processed');
var file_tds = file_tr.find('td');
var current_height = file_tr.height();
var cleared = false;
// Delete the file from the queue
delete(ref.queue[file.id]);
// Animate the deletion of the file's table row
// First fade out the contents of the td's
file_tds.find('div, input').animate({opacity:0}, 'fast', function() {
file_tds.each(function() {
// The contents are not visible anymore, so we can remove it.
$(this).html('');
});
// Since animate({height:0}) does not work for tr and td's, we need to declare our own interval
var intv = setInterval(function() {
current_height -= 5;
file_tds.height(current_height);
file_tr.css({opacity: current_height * 4});
// The animation is complete
if (current_height <= 5) {
if (!cleared) {
cleared = true;
file_tr.remove();
clearInterval(intv);
// Reset the successfull upload queue
var stats = ref.swfu.getStats();
stats.successful_uploads--;
ref.swfu.setStats(stats);
if (file_tr) {
// Update the hidden input field
ref.updateStack(file);
};
};
};
}, 50);
});
};
/**
* Retrieve the number of elements in an object
*/
ref.objectLength = function(obj) {
if (obj.status !== undefined && obj.status == 0) return 0;
var count = 0;
for (var i in obj)
count++;
return count;
};
/**
* Parses an object to a json formatted string
*/
ref.toJson = function(v) {
switch (typeof v) {
case 'boolean':
return v == true ? 'true' : 'false';
case 'number':
return v;
case 'string':
return '"'+ v.replace(/\n/g, '\\n') +'"';
case 'object':
var output = '';
for(i in v) {
output += (output ? ',' : '') + '"' + i + '":' + ref.toJson(v[i]);
}
return '{' + output + '}';
default:
return 'null';
};
};
/**
*
*/
ref.getExtension = function(file_name) {
return file_name.substring(file_name.lastIndexOf('.') + 1).toLowerCase();
};
/**
* Replaces default values from ref.instance.elements to file values
* @see ref.uploadComplete
*/
ref.replaceMacros = function(value, file) {
if (!value || value == 0) {
return false;
}
else if (value == 1) {
return true;
}
else {
var macros = {'[filename]':file.name, '{fid}':file.fid};
for (var i in macros) {
value = value.replace(i, macros[i]);
};
return value;
};
};
/**
* Reverses the order of an object
*/
ref.objReverse = function(obj) {
var temp_arr = [];
var temp_obj = {};
for (var i in obj) {
temp_arr.push({key:i, data:obj[i]});
};
temp_arr = temp_arr.reverse();
for (var i in temp_arr) {
temp_obj[temp_arr[i].key] = temp_arr[i].data;
};
return temp_obj;
};
return ref;
};
/**
* Overwrite for the TableDrag markChanged function
* Allows to place the marker in an other table drawer than the first one.
*/
Drupal.tableDrag.prototype.row.prototype.markChanged = function() {
var marker = Drupal.theme('tableDragChangedMarker');
var cell = ($('td.drag .wrapper', this.element)) || $('td:first', this.element);
if ($('span.tabledrag-changed', cell).length == 0) {
cell.append(marker);
};
};
/**
* Disables text selection on the DOM element the behavior is attached to.
*/
jQuery.fn.disableTextSelect = function() {
return this.each(function() {
$(this).css({
'MozUserSelect' : 'none'
}).bind('selectstart', function() {
return false;
}).mousedown(function() {
return false;
});
});
};
$(function() {
if (Drupal.settings.swfupload_settings) {
Drupal.swfu = {};
var settings = Drupal.settings.swfupload_settings;
for (var id in settings) {
Drupal.swfu[id] = new SWFU(id, settings[id]);
Drupal.swfu[id].init();
};
};
});
})(jQuery);

Binary file not shown.

After

Width:  |  Height:  |  Size: 262 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 256 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 143 B

View File

@@ -0,0 +1,51 @@
#swfupload-settings-form label {
background-image:url('images/back.png');
background-color:silver;
display:block;
height:24px;
width:100%;
font-weight:bold;
color:#333333;
}
#swfupload-settings-form label span {
padding-left:5px;
}
#swfupload-settings-form li {
position:relative;
background:none;
padding:0px;
margin-bottom:10px;
}
#swfupload-settings-form table {
margin:0px 0px 20px 0px;
}
#swfupload-settings-form .left {
padding-left:20px;
}
#swfupload-settings-form .left2 {
padding-left:0px;
}
.swf-nodetype-wrapper {
display:none;
border:1px solid silver;
padding:0px 10px;
}
.swf-harmonica-arrow {
height:13px;
width:13px;
position:absolute;
top:6px;
right:6px;
background-image:url('images/arrow-right.png');
}
.swf-harmonica-arrow.south {
background-image:url('images/arrow-down.png');
}

View File

@@ -0,0 +1,241 @@
<?php
/**
* @file
* The swfupload settings form.
*/
/**
*
*/
function swfupload_settings_form() {
// Add js and css
$path = drupal_get_path('module', 'swfupload');
drupal_add_css($path .'/settings/settings.css');
drupal_add_js($path .'/settings/settings.js');
// Load all roles
$roles = user_roles();
$node_types = node_get_types();
// The first loop we make goes trough all the node types
foreach ($node_types as $node_type) {
// Get the default values
$settings = variable_get('swfupload_setting_' . $node_type->type, array());
// Now we are in the loop of every node type, we can loop every role :-)
foreach ($roles as $key => $role) {
$roles[$key] = $role;
// Set a default value if array is empty
if (empty($settings[$role])) {
$settings[$role]->filepath = '%file_directory_path';
$settings[$role]->max_img_resolution = '800x600';
$settings[$role]->list = 1;
$settings[$role]->file_extensions = 'jpg jpeg gif png txt';
$settings[$role]->max_file_size = 1;
$settings[$role]->node_max_file_size = 0;
$settings[$role]->max_files = 1;
$settings[$role]->upload_usersize = 10;
if ($role == t('authenticated user')) {
$settings[$role]->upload_usersize = round((file_upload_max_size() / (1024 * 1024)));
}
}
// Create the prefix for each role
$form_prefix = $node_type->type .'_'. str_replace(' ', '_', $role);
// Path settings
$form[$form_prefix .'_filepath'] = array(
'#type' => 'textfield',
'#title' => t('Path settings'),
'#default_value' => $settings[$role]->filepath,
'#maxlength' => 255,
);
// Resolution
$form[$form_prefix .'_max_img_resolution'] = array(
'#type' => 'textfield',
'#title' => t('Maximum resolution for uploaded images'),
'#default_value' => $settings[$role]->max_img_resolution,
'#size' => 15,
'#maxlength' => 10,
'#field_suffix' => '<kbd>'. t('WIDTHxHEIGHT') .'</kbd>'
);
// Display attachments
$form[$form_prefix .'_list'] = array(
'#type' => 'checkbox',
'#title' => t('List files by default'),
'#default_value' => $settings[$role]->list,
);
// Total files per node
$form[$form_prefix .'_max_files'] = array(
'#type' => 'select',
'#title' => t('Maximum files per node'),
'#default_value' => $settings[$role]->max_files,
'#options' => array(0 => 0, 1 => 1, 2 => 2, 3 => 3, 4 => 4, 5 => 5, 10 => 10, 20 => 20, 50 => 50),
);
// Allowed extentions
$form[$form_prefix .'_file_extensions'] = array(
'#type' => 'textfield',
'#title' => t('Permitted file extensions'),
'#default_value' => $settings[$role]->file_extensions,
'#maxlength' => 255,
);
$form[$form_prefix .'_max_file_size'] = array(
'#type' => 'textfield',
'#title' => t('Maximum file size per upload'),
'#default_value' => $settings[$role]->max_file_size,
'#size' => 5,
'#maxlength' => 5,
'#field_suffix' => t('MB'),
);
$form[$form_prefix .'_node_max_file_size'] = array(
'#type' => 'textfield',
'#title' => t('Total file size per node'),
'#default_value' => $settings[$role]->node_max_file_size,
'#size' => 5,
'#maxlength' => 5,
'#field_suffix' => t('MB'),
);
$form[$form_prefix .'_upload_usersize'] = array(
'#type' => 'textfield',
'#title' => t('Total file size per user'),
'#default_value' => $settings[$role]->upload_usersize,
'#size' => 5,
'#maxlength' => 5,
'#field_suffix' => t('MB'),
);
}
}
$form['node_types'] = array('#type' => 'value', '#value' => $node_types);
$form['roles'] = array('#type' => 'value', '#value' => $roles);
$form['submit'] = array('#type' => 'submit', '#value' => t('Save configuration'));
return $form;
}
/**
* Theme function for the file settings form
*/
function theme_swfupload_settings_form($form) {
// Create an array for all fields we want to render.
$fields = array('filepath', 'max_img_resolution', 'list', 'max_files', 'file_extensions', 'max_file_size', 'node_max_file_size', 'upload_usersize', );
// Loop trough all node types
foreach ($form['node_types']['#value'] as $node_type) {
// Reset the output array
$output = array('<div class="swf-nodetype-wrapper">');
// Loop trough all roles
foreach ($form['roles']['#value'] as $role) {
// Reset the rows array
$rows = array();
// Create the prefix for each role
$form_prefix = $node_type->type .'_'. str_replace(' ', '_', $role);
// Loop trough the fields we want to render
foreach ($fields as $field) {
$title = $form[$form_prefix ."_". $field]['#title'];
unset($form[$form_prefix ."_". $field]['#title']);
$rows[] = array(
array(
'data' => $title,
'class' => 'left'
),
drupal_render($form[$form_prefix ."_". $field])
);
}
$output[] = theme('table', array(array('data' => $role, 'colspan' => 2, 'class' => 'left2')), $rows);
}
$output[] = '</div><div class="swf-harmonica-arrow"></div>';
$lis[] = "<label><span>$node_type->name</span></label>". join("\n", $output);
}
return theme('item_list', $lis) . drupal_render($form) .'<div style="clear:both"></div>';
}
/**
* validation of the file settings form
*/
function swfupload_settings_form_validate($form, &$form_state) {
// Loop trough all node types
foreach ($form['node_types']['#value'] as $node_type) {
// Loop trough all the roles
foreach ($form['roles']['#value'] as $role) {
// Create the prefix for each role
$form_prefix = $node_type->type .'_'. str_replace(' ', '_', $role);
// Max resolution
if ($form_state['values'][$form_prefix .'_max_img_resolution'] != 0) {
$max_resolution = explode('x', $form_state['values'][$form_prefix .'_max_img_resolution']);
if (count($max_resolution) != 2) {
form_set_error($form_prefix .'_max_img_resolution', t('Maximum resolution for uploaded images is not valid'));
}
else {
if (!is_numeric($max_resolution[0]) or !is_numeric($max_resolution[1])) {
form_set_error($form_prefix .'_max_img_resolution', t('Maximum resolution for uploaded images is not valid'));
}
}
}
// Permited extentions
$extensions = explode(' ', $form_state['values'][$form_prefix .'_file_extensions']);
foreach ($extensions as $extention) {
if (!preg_match("/^([A-Z0-9]){2,10}$/i", $extention)) {
form_set_error($form_prefix .'_file_extensions', t('One of more extentions are not valid'));
break;
}
}
// Maximum file size
if (!is_numeric($form_state['values'][$form_prefix .'_max_file_size'])) {
form_set_error($form_prefix .'_max_file_size', t('Maximum file size per upload is not valid'));
}
// Total node size
if (!is_numeric($form_state['values'][$form_prefix .'_node_max_file_size'])) {
form_set_error($form_prefix .'_node_max_file_size', t('Total file size per node is not valid'));
}
// Total user size
if (!is_numeric($form_state['values'][$form_prefix .'_upload_usersize'])) {
form_set_error($form_prefix .'_upload_usersize', t('Total file size per user is not valid'));
}
}
}
}
/**
* Submittion of the file settings form
*/
function swfupload_settings_form_submit($form, &$form_state) {
// Loop trough all node types
foreach ($form['node_types']['#value'] as $node_type) {
// Loop trough all the roles
foreach ($form['roles']['#value'] as $role) {
// Create the prefix for each role
$form_prefix = $node_type->type .'_'. str_replace(' ', '_', $role);
$settings[$role]->filepath = $form_state['values'][$form_prefix .'_filepath'];
$settings[$role]->max_img_resolution = $form_state['values'][$form_prefix .'_max_img_resolution'];
$settings[$role]->list = $form_state['values'][$form_prefix .'_list'];
$settings[$role]->file_extensions = drupal_strtolower($form_state['values'][$form_prefix .'_file_extensions']);
$settings[$role]->max_file_size = $form_state['values'][$form_prefix .'_max_file_size'];
$settings[$role]->upload_usersize = $form_state['values'][$form_prefix .'_upload_usersize'];
$settings[$role]->node_max_file_size = $form_state['values'][$form_prefix .'_node_max_file_size'];
$settings[$role]->max_files = $form_state['values'][$form_prefix .'_max_files'];
}
variable_set('swfupload_setting_'. $node_type->type, $settings);
}
drupal_set_message(t('The configuration options have been saved.'));
}

View File

@@ -0,0 +1,29 @@
$(function() {
window.swfupload_label_heights = {};
window.swfupload_wrapper_getting_smaller = {};
$('#swfupload-settings-form label').each(function() {
window.swfupload_label_heights[$(this).text()] = $(this).parent().find('.swf-nodetype-wrapper').height();
$(this).parent().find('.swf-nodetype-wrapper').height(0);
window.swfupload_wrapper_getting_smaller[$(this).text()] = false;
});
$('#swfupload-settings-form label, .swf-harmonica-arrow').css({'cursor':'pointer'}).click(function() {
var content = $(this).parent().find('.swf-nodetype-wrapper').stop();
var label = content.parent().find('label').text();
var height = window.swfupload_label_heights[label];
var arrow = $(this).parent().find('.swf-harmonica-arrow');
var current_height = $(this).parent().find('.swf-nodetype-wrapper').height();
if (content.css("display") == 'none' || window.swfupload_wrapper_getting_smaller[label]) {
window.swfupload_wrapper_getting_smaller[label] = false;
arrow.addClass('south');
content.css({'height':(current_height == height ? 0 : current_height) + 'px', 'display':'block'}).animate({'height':height + 'px'}, 1000);
} else {
arrow.removeClass('south');
window.swfupload_wrapper_getting_smaller[label] = true;
content.animate({'height':'0px'}, 1000, function() {
$(this).css({'display':'none', 'height':height + 'px'});
});
};
});
});

View File

@@ -0,0 +1,115 @@
<?php
// $Id: swfupload.admin.inc,v 1.2 2010/06/17 18:24:57 eugenmayer Exp $
/**
* @file
* Include file for all functions required while using the CCK widget (e.g.: in node-edit forms).
*/
/**
* Menu callback for menu item 'swfupload'.
* This function is executed when SFWUpload.swf requests a file upload
*/
function swfupload_js() {
$p = (object) $_POST;
$op = $p->op;
$file = (isset($p->file) ? json_decode($p->file) : NULL);
$instance = json_decode($p->instance);
$instance_settings = json_decode($p->instance_settings);
$file_path = $p->file_path;
unset($p);
switch ($op) {
case 'init':
// Add the default callback functions for the SWF Upload
$instance->type = 'table';
$instance->callbacks = array(
'swfupload_loaded_handler' => 'ref.swfUploadLoaded',
'file_queued_handler' => 'ref.fileQueued',
'queue_complete_handler' => 'ref.queueComplete',
'file_queue_error_handler' => 'ref.fileQueueError',
'file_dialog_complete_handler' => 'ref.dialogComplete',
'upload_success_handler' => 'ref.uploadSuccess',
'upload_progress_handler' => 'ref.uploadProgress',
'upload_error_handler' => 'ref.uploadError',
'upload_complete_handler' => 'ref.uploadComplete',
'init_complete_handler' => 'ref.initComplete',// This custom javascript callback function is used to place the markup inside the dom
);
$instance->elements = array(
'drag' => array(
'class' => 'drag first indentation',
'type' => 'drag',
'colspan' => 3,
'title' => t('Filename'),
'add_separator' => TRUE,
),
'icon' => array(
'type' => 'icon',
'class' => 'icon',
),
'filename' => array(
'type' => 'markup',
'value' => '[filename]',
'class' => 'text title',
),
);
break;
case 'move_uploaded_file':
$max_filesize = parse_size(file_upload_max_size());
if (!empty($instance_settings->max_filesize) && parse_size($instance_settings->max_filesize) < $max_filesize) {
$max_filesize = parse_size($instance_settings->max_filesize);
}
$file->validators = array(
'file_validate_extensions' => array($instance_settings->file_extensions),
// 'filefield_validate_image_resolution' => array($instance_settings->max_resolution, $instance_settings->min_resolution),
'file_validate_size' => array($max_filesize),
);
$file->file_path = $file_path;
// Allow other modules to change the file_path an validators
foreach (module_implements('swfupload') as $module) {
$function = $module . '_swfupload';
$function($file, $op, $instance, $instance_settings);
}
$op = 'upload_complete';
break;
}
// Allow other modules to change the returned data
foreach (module_implements('swfupload') as $module) {
$function = $module . '_swfupload';
$function($file, $op, $instance, $instance_settings);
// We want to make sure the last column of each tablerow contains the 'cancel' or 'delete' button.
if ($op == 'init') {
$instance->elements['cancel'] = array('class' => 'last', 'type' => 'cancel');
}
}
// Replace keys named 'class' to 'classname'
if (!empty($instance->elements)) {
array_walk($instance->elements, '_class_to_classname');
}
$p->op = $op;
$p->file = $file;
$p->file_path = $file_path;
$p->instance = $instance;
$p->instance_settings = $instance_settings;
$p->messages = drupal_get_messages();
echo json_encode($p);
exit(0);
}
/**
* Helper function to replace instance elements class keys to classname keys
* Safari hangs if you use 'class' in javascript
*/
function _class_to_classname(&$element) {
$element['classname'] = $element['class'];
unset($element['class']);
}

View File

@@ -0,0 +1,367 @@
/**
* SWFUpload table
*/
table.swfupload {
border: none;
border-bottom: #c2c2c2 1px solid;
margin-top: 1px;
margin-bottom: 10px;
}
table.swfupload tr.even,
table.swfupload tr.odd,
table.swfupload tbody,
table.swfupload tbody th,
table.swfupload tr td:last-child {
border: none;
}
table.swfupload tr.even {
border-top: solid 1px #f00;
}
table.swfupload .border {
background: #c2c2c2;
width: 1px;
}
table.swfupload th,
table.swfupload td {
border-width: 0;
border-top: solid 1px #d3d3d3;
line-height: 100%;
padding: 0px;
white-space: nowrap;
vertical-align: top;
}
table.swfupload th {
border-bottom: solid 1px #c2c2c2;
background: url('images/thead.png') 0px 100% white repeat-x;
}
table.swfupload div.wrapper {
display: block;
height: 100%;
width: 100%;
position: relative;
}
table.swfupload td div.wrapper {
padding: 5px 0px;
}
table.swfupload tr.hidden {
display: none;
}
/**
* Table headers
*/
table.swfupload th {
text-align: center;
}
table.swfupload div.left,
table.swfupload div.right {
width: 1px;
height: 100%;
position: absolute;
top: 0px;
font-size: 1px;
}
table.swfupload div.left {
background: #c2c2c2;
right: 1px;
}
table.swfupload div.right {
background: #fff;
right: 0px;
}
table.swfupload th div.center {
font-size: 12px;
padding: 3px 5px 3px 3px;
}
table.swfupload th.first {
width: 50%;
}
/**
* Table drawers
*/
table.swfupload td {
background: url('images/row_background.png') white repeat-x 0px 1px;
}
table.swfupload td.drag {
width: 20px;
vertical-align: middle;
}
table.swfupload td.icon {
width: 32px;
padding-top: 2px;
}
table.swfupload td.text {
font-size: 12px;
min-width: 100px;
padding: 9px 5px;
}
table.swfupload td.text.title {
width: 45%;
}
table.swfupload td.last {
width: 40px;
}
table.swfupload td.checkbox {
text-align: center;
padding-top: 5px;
}
table.swfupload td textarea,
table.swfupload td.text input {
border: solid silver 1px;
width: 90%;
}
table.swfupload td textarea {
height: 100px;
}
table.swfupload td span {
width: 100%;
}
/**
* Editable
*/
table.swfupload td .toggle-editable {
position: absolute;
right: 0px;
visibility: hidden;
}
table.swfupload td:hover .toggle-editable {
visibility: visible;
}
table.swfupload td .editable-enabled .toggle-editable {
display: none;
}
/**
* Drag
*/
table.swfupload tr.dragging td {
opacity: .40;
filter: alpha(opacity=40);
-moz-opacity: 0.4;
}
table.swfupload td.drag a.tabledrag-handle {
margin: 0;
padding: 0;
}
table.swfupload td.drag a.tabledrag-handle .handle {
margin: 2px 10px;
}
/**
* Warning / tabledrag changed
*/
table.swfupload span.tabledrag-changed {
position: absolute;
top: 0;
left: 3px;
}
/**
* Progressbar
*/
table.swfupload td.progress {
padding: 0px 10px;
}
.sfwupload-list-progressbar {
width: 100%;
height: 14px;
margin-top: 12px;
background: url('images/progress_animated_back.gif') repeat-x;
position: relative;
border-top: 1px solid #acacac;
border-bottom: 1px solid #686868;
border-left: 1px solid #9c9c9c;
border-right: 1px solid #9c9c9c;
}
.sfwupload-list-progressbar.complete,
.sfwupload-list-progressbar.stopped {
background: url('images/progress_back.gif') repeat-x;
}
.sfwupload-list-progressbar-status {
position: absolute;
background: url('images/progress.png') 0px 0px repeat-x;
height: 14px;
}
.sfwupload-list-progressbar.stopped .sfwupload-list-progressbar-status {
background-position: 0px -14px;
}
.sfwupload-list-progressbar-glow {
position: absolute;
background: url('images/glow.png') repeat-x;
height: 14px;
font-weight: normal;
text-align: center;
font-size: 11px;
line-height: 110%;
color: white;
width: 100%;
}
/* Cancel button */
.sfwupload-list-cancel {
height: 14px;
width: 14px;
background-image: url('images/cancel.png');
margin: 10px;
overflow: hidden;
cursor: pointer;
}
/* Filename wrapper */
.swfupload-markup {
display: none;
}
/**
* Upload button
*/
.swfupload_button {
margin: 10px 0px;
}
.swfupload_button.disabled {
opacity: .40;
filter: alpha(opacity=40);
-moz-opacity: 0.4;
}
.swfupload_button div.swfupload-wrapper {
float: left;
width: 1px;
height: 1px;
position: relative;
}
html.js fieldset.collapsed .fieldset-wrapper,
html.js fieldset.collapsed #edit-upload,
html.js fieldset.collapsed #edit-upload .swfupload-wrapper,
html.js fieldset.collapsed #edit-upload .swfupload-wrapper .swfupload {
display: block;
height: 0px;
overflow: hidden;
}
.swfupload_button div.swfupload-wrapper .swfupload {
position: absolute;
top: 1px;
}
.swfupload_button.disabled div.swfupload-wrapper .swfupload {
height: 0px;
overflow: hidden;
}
.swfupload_button div.left,
.swfupload_button div.center,
.swfupload_button div.right {
height: 15px;
line-height: 100%;
float: left;
padding-top: 1px;
background: url('images/button.png') no-repeat 0px 0px;
}
.swfupload_button div.left {
width: 20px;
}
.swfupload_button.active div.left {
background-position: 0px -16px;
}
.swfupload_button div.center {
background-position: 50% 0px;
}
.swfupload_button.active div.center {
background-position: 50% -16px;
}
.swfupload_button div.right {
width: 20px;
background-position: 100% 0px;
}
.swfupload_button.active div.right {
background-position: 100% -16px;
}
.swfupload-error div.left,
.swfupload-error div.center,
.swfupload-error div.right {
background-position-y: -48px;
}
.swfupload-error.active div.left,
.swfupload-error.active div.center,
.swfupload-error.active div.right {
background-position-y: -32px;
}
/**
* Messages
*/
.swfupload .messages {
margin: 0px;
}
/**
* Mime types
*/
.sfwupload-list-mime {
width: 32px;
height: 32px;
background-position: 50% 50%;
background-repeat: no-repeat;
}
.sfwupload-list-mime.ai {background-image: url('images/mime/ai.png');}
.sfwupload-list-mime.bmp {background-image: url('images/mime/bmp.png');}
.sfwupload-list-mime.doc {background-image: url('images/mime/doc.png');}
.sfwupload-list-mime.gif {background-image: url('images/mime/gif.png');}
.sfwupload-list-mime.html {background-image: url('images/mime/html.png');}
.sfwupload-list-mime.jpeg {background-image: url('images/mime/jpeg.png');}
.sfwupload-list-mime.jpg {background-image: url('images/mime/jpg.png');}
.sfwupload-list-mime.mov {background-image: url('images/mime/mov.png');}
.sfwupload-list-mime.pdf {background-image: url('images/mime/pdf.png');}
.sfwupload-list-mime.png {background-image: url('images/mime/png.png');}
.sfwupload-list-mime.psd {background-image: url('images/mime/psd.png');}
.sfwupload-list-mime.rar {background-image: url('images/mime/rar.png');}
.sfwupload-list-mime.swf {background-image: url('images/mime/swf.png');}
.sfwupload-list-mime.txt {background-image: url('images/mime/txt.png');}
.sfwupload-list-mime.wmv {background-image: url('images/mime/wmv.png');}
.sfwupload-list-mime.xls {background-image: url('images/mime/xls.png');}
.sfwupload-list-mime.zip {background-image: url('images/mime/zip.png');}

View File

@@ -0,0 +1,14 @@
; $Id:$
name = SWFupload Widget
description = A widget for file field which enables multiple file uploads using the SWFUpload library.
package = Fields
version = VERSION
dependencies[] = file
dependencies[] = libraries
core = 7.x
; Information added by drupal.org packaging script on 2012-05-10
version = "7.x-1.0-alpha1+1-dev"
core = "7.x"
project = "swfupload"
datestamp = "1336653834"

View File

@@ -0,0 +1,13 @@
<?php
/**
* @file
* SWFUpload install file.
*/
/**
* Implementation of hook_uninstall().
*/
function swfupload_uninstall() {
db_query('DELETE FROM {variable} WHERE name LIKE "swfupload_setting_%"');
}

View File

@@ -0,0 +1,285 @@
<?php
// $Id: swfupload.info, v 0.1, 2008/10/13 10:02:46, skilip Exp $
include_once dirname(__FILE__) . '/swfupload_widget.inc';
/**
* @file
*
* A widget for file field which enables multiple file uploads using the SWFUpload library.
*/
/**
* Implements hook_perm().
*/
function swfupload_perm() {
return array('upload files with swfupload');
}
/**
* Implements hook_menu().
*/
function swfupload_menu() {
$items['swfupload'] = array(
'page callback' => 'swfupload_js',
'access callback' => 'swfupload_upload_access',
'type' => MENU_CALLBACK,
'file' => 'swfupload.admin.inc',
);
return $items;
}
/**
* Validate access to the swfuploadpath
*/
function swfupload_upload_access() {
$result = FALSE;
$p = (object) $_POST;
// Validate the request.
if (!empty($p->sid)) {
// $hash_arr[0] is the uid the user wants to athenticate for.
// $hash_arr[1] is the md5-hashed sid of drupals authetication token.
$hash_arr = explode('*', _swfupload_hex2bin($p->sid));
$uid = $hash_arr[0];
$token = $hash_arr[1];
if ($uid == 0) {
// If the uid is 0, there will be no session id.
// We'll check if the hash of the current remote address matches the sent one.
return ($token == md5($_SERVER['REMOTE_ADDR']));
}
// Get all session for the provided user
$result = db_query('SELECT sid FROM {sessions} WHERE uid = :uid', array(':uid' => $uid));
// There is no user with that uid, deny permission.
if ($result == FALSE) {
return FALSE;
}
$valid_sids = array();
// create our hashes we need for verification
foreach ($result as $row) {
$valid_sids[$row->sid] = md5($row->sid);
}
// If the hashed session is is present in the stored hashed session ids from the database,
// and if there weren't more that 5 invalid attempts for matching,
// make the user account global so other modules can use its credentials.
if (in_array($token, $valid_sids) && flood_is_allowed('swfupload_restore_session', 5)) {
// Use the global user, as we are about to store the loaded account object in it.
global $user;
// Now load the global user object to "login". We use the $uid provided, as we verfified
// that the token is correct (and matches this user)
$user = user_load($uid);
// This is needed. Most people forget about this - thats why forms wont work anymore ... the validation fails (token).
session_id(array_search($token, $valid_sids));
// As the user session is restored, check for general rights to use swfupload
return user_access('upload files with swfupload');
}
else {
// Register unwanted attempts to rstore the session.
flood_register_event('swfupload_restore_session');
}
// The sid doesn't exist for this user or its a flood attack
return FALSE;
}
// No session ID is set, we can assume we're still in the same session
return (!empty($p->op) && user_access('upload files with swfupload'));
}
/**
* Implements hook_theme().
*/
function swfupload_theme() {
return array(
'swfupload_widget' => array(
'render element' => 'element',
),
);
}
/**
* Implements hook_elements().
*/
function swfupload_element_info() {
$path = drupal_get_path('module', 'swfupload');
return array(
'swfupload_widget' => array(
'#process' => array('swfupload_widget_process'),
'#value_callback' => 'swfupload_widget_value',
'#input' => TRUE,
'#attached' => array(
'js' => array(
'misc/tabledrag.js' => array('weight' => -10),
$path . '/js/swfupload_widget.js' => array('weight' => 10),
),
'css' => array(
$path . '/swfupload.css',
),
),
'#theme' => 'swfupload_widget',
'#theme_wrappers' => array('form_element'),
),
);
}
/**
* Implements hook_swfupload().
*/
function swfupload_swfupload(&$file, $op, &$instance, $instance_settings) {
switch ($op) {
case 'init':
$columns = 0;
if ($instance_settings->description_field) {
$instance->elements['description'] = $instance->elements['filename'];
$instance->elements['description']['type'] = 'textfield';
$instance->elements['drag']['title'] = t('Description');
unset($instance->elements['filename']);
}
if ($instance_settings->display_field) {
$instance->elements['display'] = array(
'title' => t('Display'),
'type' => 'checkbox',
'default_value' => $instance_settings->display_default,
'class' => 'checkbox',
'contains_progressbar' => TRUE,
'add_separator' => TRUE,
);
$columns++;
}
foreach (array('alt' => t('Alt'), 'title' => t('Title')) as $elem => $title) {
if (!empty($instance_settings->{$elem . '_field'})) {
$instance->elements[$elem] = array(
'title' => $title,
'type' => ($instance_settings->{$elem . '_type'} ? $instance_settings->{$elem . '_type'} : 'textfield'),
'default_value' => $instance_settings->{$elem},
'class' => 'text',
'contains_progressbar' => TRUE,
'add_separator' => TRUE,
);
// Replace tokens.
if (module_exists('token')) {
$instance->elements[$elem]['default_value'] = token_replace($instance->elements[$elem]['default_value']);
}
$columns++;
}
}
if ($columns == 0) {
$instance->elements['progress'] = array(
'type' => 'markup',
'value' => '<span>&nbsp;</span>',
'class' => 'checkbox',
'contains_progressbar' => TRUE,
);
}
unset($instance->elements[$elem]['add_separator']);
break;
case 'move_uploaded_file':
if (isset($_FILES["Filedata"]) && is_uploaded_file($_FILES["Filedata"]["tmp_name"]) && $_FILES["Filedata"]["error"] == 0) {
// Set a message of the type 'swfupload_error' in order to place the message in the progressbar.
drupal_set_message(t('There was an error uploading the file'), 'swfupload_error');
return;
}
$_FILES['files']['name'][$instance->name] = reset($_FILES[$instance->name]['name']);
$_FILES['files']['type'][$instance->name] = reset($_FILES[$instance->name]['type']);
$_FILES['files']['tmp_name'][$instance->name] = reset($_FILES[$instance->name]['tmp_name']);
$_FILES['files']['error'][$instance->name] = reset($_FILES[$instance->name]['error']);
$_FILES['files']['size'][$instance->name] = reset($_FILES[$instance->name]['size']);
// Replace tokens.
if (module_exists('token')) {
$file->file_path = token_replace($file->file_path, 'user');
}
// Check if the file directory exists
file_prepare_directory($file->file_path, FILE_CREATE_DIRECTORY);
if (user_access('upload files with swfupload') && ($file = file_save_upload($instance->name, $file->validators, $file->file_path))) {
if (image_get_info($file->uri)) {
$file->thumb = swfupload_thumb($file);
}
break;
}
drupal_set_message(t('There was an error uploading the file'), 'swfupload_error');
break;
}
}
/**
* Implements hook_library().
*/
function swfupload_libraries_info() {
$libraries = array(
'swfupload' => array(
'name' => 'SWFUpload',
'vendor url' => 'http://code.google.com/p/swfupload/',
'version arguments' => array(
'file' => 'swfupload.js',
'pattern' => '/SWFUpload.version \= \"([0-9.]{1,}) ([0-9-]{1,})\"/',
'lines' => 60,
),
'files' => array(
'js' => array('swfupload.js'),
),
),
);
return $libraries;
}
/**
* Implements hook_requirements().
*/
function swfupload_requirements($phase) {
$requirements = array();
$library = libraries_load('swfupload');
// Ensure translations don't break at install time
$t = get_t();
// Report Drupal version
if ($phase == 'runtime') {
$requirements['swfupload'] = array(
'title' => $t('SWFUpload'),
'value' => empty($library) ? t('SWFUpload library was not found!') : $library['version'],
'severity' => empty($library) ? REQUIREMENT_ERROR : REQUIREMENT_OK,
);
}
return $requirements;
}
/**
* Generates an unique key, used for validating upload requests
*/
function _swfupload_post_key() {
global $user;
return bin2hex($user->uid . '*' . md5(($user->uid && $user->sid) ? $user->sid : $_SERVER['REMOTE_ADDR']));
}
/**
* Converts an hexadecimal string to binairy
*/
function _swfupload_hex2bin($h) {
if (!is_string($h)) {
return NULL;
}
$r = '';
for ($a = 0; $a < drupal_strlen($h); $a += 2) {
$r .= chr(hexdec($h{$a} . $h{($a + 1)}));
}
return $r;
}
/**
* Create a thumbnail to be shown in the swfupload table.
*/
function swfupload_thumb($file) {
// Force an object.
$file = (object) $file;
return image_style_url('thumbnail', $file->uri);
}

View File

@@ -0,0 +1,177 @@
<?php
// $Id: swfupload_widget.inc,v 1.6 2010/12/02 16:02:53 skilip Exp $
/**
* @file
* SWFUpload widget hooks and callbacks.
*/
/**
* Implements hook_field_widget_info().
*/
function swfupload_field_widget_info() {
return array(
'swfupload' => array(
'label' => 'SWFUpload',
'field types' => array('file', 'image'),
'settings' => array(
'progress_indicator' => 'throbber',
'preview_image_style' => 'thumbnail',
),
'behaviors' => array(
'multiple values' => FIELD_BEHAVIOR_CUSTOM,
'default value' => FIELD_BEHAVIOR_NONE,
),
),
);
}
/**
* Implements hook_field_widget_form().
*/
function swfupload_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
// Collect the files already stored in this field indexed by their file ID.
$files = array();
foreach ($items as $delta => $file) {
if ($file['fid'] != 0) {
$files[$file['fid']] = $file;
}
}
$element['#default_value'] = $files;
$element_info = element_info('swfupload_widget');
$element += array(
'#type' => 'swfupload_widget',
'#process' => $element_info['#process'],
'#value_callback' => $element_info['#value_callback'],
// Allows this field to return an array instead of a single value.
'#extended' => TRUE,
);
// $element['#display_field'] = $field['settings']['display_field'];
return $element;
}
/**
* The #value_callback for the swfupload_widget type element.
*/
function swfupload_widget_value(&$element, $input = FALSE, $form_state = NULL) {
if (is_string($input)) {
$input = json_decode($input, TRUE);
}
if ($input === FALSE) {
$default_value = array();
if (!empty($element['#default_value'])) {
foreach ($element['#default_value'] as $file) {
if ($file) {
// If we're dealing with an image, create a thumbpath
if (image_get_info($file['uri'])) {
$file['thumb'] = swfupload_thumb($file);
}
$default_value[$file['fid']] = $file;
}
}
}
return $default_value;
}
else {
// Files need an integer value for the 'display' field.
foreach ($input as $fid => $file) {
if (empty($file['display'])) {
$input[$fid]['display'] = 0;
}
}
return $input;
}
}
/**
* Process the link type element before displaying the field.
*
* Build the form element. When creating a form using FAPI #process,
* note that $element['#value'] is already set.
*
* The $fields array is in $form['#field_info'][$element['#field_name']].
*/
function swfupload_widget_process($element, $form_state, $form) {
$field = field_info_field($element['#field_name']);
$instance = field_info_instance($element['#entity_type'], $element['#field_name'], $element['#bundle']);
// Make sure the element's name exists.
if (!isset($element['#name'])) {
$element['#name'] = array_shift($element['#parents']);
}
$element['#default_value'] = '[]';
// Set a file upload limit for SWFUpload where 0 is unlimited.
$limit = ($field['cardinality'] == -1 ? 0 : $field['cardinality']);
// Set the button title which is used in the theme function.
if ($field['type'] == 'image') {
$element['#button_title'] = format_plural(($limit === 0 ? 2 : $limit), 'Upload new image', 'Upload new images');
}
else {
$element['#button_title'] = format_plural(($limit === 0 ? 2 : $limit), 'Upload new file', 'Upload new files');
}
// Construct the JavaScript settings array.
if ($library = libraries_load('swfupload')) {
$settings['swfupload_settings'][$element['#id']] = array(
'module_path' => drupal_get_path('module', 'swfupload'),
'flash_url' => url($library['library path'] . '/Flash/swfupload.swf'),
'upload_url' => url('swfupload'), // Relative to the SWF file
'upload_button_id' => $element['#id'],
'file_post_name' => $element['#name'],
'file_queue_limit' => $limit,
'post_params' => array(
'sid' => _swfupload_post_key(),
'file_path' => $field['settings']['uri_scheme'] . '://' . $instance['settings']['file_directory'],
'op' => 'move_uploaded_file',
'instance' => json_encode(array('name' => $element['#field_name'])),
'instance_settings' => json_encode($instance['settings'] + $field['settings']),
),
'file_size_limit' => ($instance['settings']['max_filesize'] ? (parse_size($instance['settings']['max_filesize']) / 1048576) . 'MB' : 0),
'file_types' => (empty($instance['settings']['file_extensions']) ? '' : '*.' . str_replace(" ", ";*.", $instance['settings']['file_extensions'])),
'file_types_description' => ($element['#description'] ? $element['#description'] : ''),
'file_upload_limit' => $limit,
'custom_settings' => array(
'upload_stack_value' => (!empty($element['#value'])) ? json_encode($element['#value']) : '[]',
'max_queue_size' => ($instance['settings']['max_filesize'] ? $instance['settings']['max_filesize'] : 0),
),
);
drupal_add_js($settings, 'setting');
}
return $element;
}
/**
* Theme function for the swfupload form element
*/
function theme_swfupload_widget($variables) {
$element = $variables['element'];
// Force the classes swfupload_button and disabled to be added to the button
_form_set_class($element, array('swfupload_button', 'disabled'));
$element['#attributes']['class'] = str_replace(' error', ' swfupload-error', $element['#attributes']['class']);
$output[] = '<div id="' . $element['#id'] . '" ' . drupal_attributes($element['#attributes']) . '>';
$output[] = ' <div class="swfupload-wrapper">';
$output[] = ' <div id="' . $element['#name'] . '-swfwrapper">&nbsp;</div>';
$output[] = ' </div>';
$output[] = ' <div class="left">&nbsp;</div>';
$output[] = ' <div class="center">' . $element['#button_title'] . '</div>';
$output[] = ' <div class="right">&nbsp;</div><br />';
$output[] = '</div>';
if ($element['#description']) {
$output[] = ' <div class="description">' . $element['#description'] . '</div>';
}
return join("\n", $output);
}