fmsystem-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Fmsystem-commits] [6627] recover from backup due to savanna down time


From: Sigurd Nes
Subject: [Fmsystem-commits] [6627] recover from backup due to savanna down time
Date: Thu, 02 Dec 2010 10:07:29 +0000

Revision: 6627
          http://svn.sv.gnu.org/viewvc/?view=rev&root=fmsystem&revision=6627
Author:   sigurdne
Date:     2010-12-02 10:07:28 +0000 (Thu, 02 Dec 2010)
Log Message:
-----------
recover from backup due to savanna down time

Modified Paths:
--------------
    trunk/booking/inc/class.bobuilding.inc.php
    trunk/booking/inc/class.sobuilding.inc.php
    trunk/booking/inc/class.soevent.inc.php
    trunk/booking/inc/class.uiapplication.inc.php
    trunk/booking/inc/class.uibuilding.inc.php
    trunk/booking/inc/class.uievent.inc.php
    trunk/booking/jasper/templates/application.jrxml
    trunk/booking/setup/phpgw_no.lang
    trunk/booking/setup/setup.inc.php
    trunk/booking/setup/tables_current.inc.php
    trunk/booking/setup/tables_update.inc.php
    trunk/booking/templates/base/building_form.xsl
    trunk/booking/templates/base/event_edit.xsl
    trunk/bookingfrontend/inc/class.uibuilding.inc.php
    trunk/bookingfrontend/setup/phpgw_no.lang
    trunk/bookingfrontend/setup/setup.inc.php
    trunk/bookingfrontend/templates/base/building.xsl
    trunk/bookingfrontend/templates/base/building_schedule.xsl
    trunk/frontend/inc/class.bofrontend.inc.php
    trunk/frontend/inc/class.uidelegates.inc.php
    trunk/frontend/inc/class.uihelpdesk.inc.php
    trunk/frontend/inc/hook_config.inc.php
    trunk/frontend/setup/setup.inc.php
    trunk/frontend/templates/base/config.tpl
    trunk/login.php
    trunk/phpgwapi/inc/functions.inc.php
    trunk/phpgwapi/inc/sso/include_login.inc.php
    trunk/phpgwapi/templates/base/login.tpl
    trunk/phpgwapi/templates/portico/footer.tpl
    trunk/phpgwapi/templates/portico/js/base.js
    trunk/phpgwapi/templates/portico/navbar.inc.php
    trunk/property/inc/class.bocommon.inc.php
    trunk/property/inc/class.fileuploader.inc.php
    trunk/property/inc/class.menu.inc.php
    trunk/property/inc/class.sogeneric.inc.php
    trunk/property/inc/class.solocation.inc.php
    trunk/property/inc/class.uidocument.inc.php
    trunk/property/inc/class.uientity.inc.php
    trunk/property/inc/class.uitts.inc.php
    trunk/property/js/yahoo/entity.edit.js
    trunk/property/js/yahoo/property.js
    trunk/property/js/yahoo/tts.index.js
    trunk/property/js/yahoo/tts.view.js
    trunk/property/setup/phpgw_no.lang
    trunk/property/setup/setup.inc.php
    trunk/property/setup/tables_current.inc.php
    trunk/property/setup/tables_update.inc.php
    trunk/property/templates/base/entity.xsl
    trunk/property/templates/base/files.xsl
    trunk/property/templates/base/fileuploader.xsl
    trunk/property/templates/base/tts.xsl
    trunk/property/tutorials/property/examples/install.apache.sh
    trunk/rental/inc/class.socontract.inc.php

Added Paths:
-----------
    trunk/frontend/inc/class.hook_helper.inc.php
    trunk/phpgwapi/js/swfupload/
    trunk/phpgwapi/js/swfupload/default.css
    trunk/phpgwapi/js/swfupload/fileprogress.js
    trunk/phpgwapi/js/swfupload/handlers.js
    trunk/phpgwapi/js/swfupload/swfupload.cookies.js
    trunk/phpgwapi/js/swfupload/swfupload.js
    trunk/phpgwapi/js/swfupload/swfupload.proxy.js
    trunk/phpgwapi/js/swfupload/swfupload.queue.js
    trunk/phpgwapi/js/swfupload/swfupload.speed.js
    trunk/phpgwapi/js/swfupload/swfupload.swf
    trunk/phpgwapi/js/swfupload/swfupload_fp9.swf
    trunk/property/js/yahoo/tts.add.js

Modified: trunk/booking/inc/class.bobuilding.inc.php
===================================================================
--- trunk/booking/inc/class.bobuilding.inc.php  2010-11-22 13:33:58 UTC (rev 
6626)
+++ trunk/booking/inc/class.bobuilding.inc.php  2010-12-02 10:07:28 UTC (rev 
6627)
@@ -20,7 +20,7 @@
                                        ),
                                        booking_sopermission::ROLE_CASE_OFFICER 
=> array
                                        (
-                                               'write' => 
array_fill_keys(array('name', 'homepage', 'description', 'email', 'phone', 
'street', 'zip_code', 'city', 'district'), true),
+                                               'write' => 
array_fill_keys(array('name', 'homepage', 'description', 'email', 'phone', 
'street', 'zip_code', 'city', 
'district','deactivate_application','deactivate_calendar'), true),
                                        ),
                                        'global' => array
                                        (

Modified: trunk/booking/inc/class.sobuilding.inc.php
===================================================================
--- trunk/booking/inc/class.sobuilding.inc.php  2010-11-22 13:33:58 UTC (rev 
6626)
+++ trunk/booking/inc/class.sobuilding.inc.php  2010-12-02 10:07:28 UTC (rev 
6627)
@@ -13,6 +13,8 @@
                                        'description' => array('type' => 
'string'),
                                        'phone' => array('type' => 'string'),
                                        'email' => array('type' => 'string'),
+                                       'deactivate_calendar' => array('type' 
=> 'int'),
+                                       'deactivate_application' => 
array('type' => 'int'),
                                        'location_code' =>array('type' => 
'string', 'required' => false),
                                        'street'                => array('type' 
=> 'string', 'query' => true),
                                        'zip_code'              => array('type' 
=> 'string'),

Modified: trunk/booking/inc/class.soevent.inc.php
===================================================================
--- trunk/booking/inc/class.soevent.inc.php     2010-11-22 13:33:58 UTC (rev 
6626)
+++ trunk/booking/inc/class.soevent.inc.php     2010-12-02 10:07:28 UTC (rev 
6627)
@@ -74,7 +74,7 @@
 
                function get_building_info($id)
                {
-                       $this->db->limit_query("SELECT bb_building.id, 
bb_building.name FROM bb_building, bb_resource, bb_event_resource WHERE 
bb_building.id=bb_resource.building_id AND 
bb_resource.id=bb_event_resource.resource_id AND bb_event_resource.event_id=" . 
intval($id), 0, __LINE__, __FILE__, 1);
+                       $this->db->limit_query("SELECT bb_building.id, 
bb_building.name, bb_building.email FROM bb_building, bb_resource, 
bb_event_resource WHERE bb_building.id=bb_resource.building_id AND 
bb_resource.id=bb_event_resource.resource_id AND bb_event_resource.event_id=" . 
intval($id), 0, __LINE__, __FILE__, 1);
                        if(!$this->db->next_record())
                        {
                                return False;

Modified: trunk/booking/inc/class.uiapplication.inc.php
===================================================================
--- trunk/booking/inc/class.uiapplication.inc.php       2010-11-22 13:33:58 UTC 
(rev 6626)
+++ trunk/booking/inc/class.uiapplication.inc.php       2010-12-02 10:07:28 UTC 
(rev 6627)
@@ -359,6 +359,13 @@
                                        $errors['email'] = lang('The e-mail 
addresses you entered do not match');
                                        $application['contact_email2'] = 
$_POST['contact_email2'];
                                }
+                               foreach($application['agegroups'] as $ag)
+                               {
+                                       if($ag['male'] > 9999 || $ag['female'] 
> 9999) {
+                                               $errors['agegroups'] = 
lang('Agegroups kan not be larger than 9999 peoples');
+                                       }
+                               }
+
                                if(!$errors)
                                {
                                        $comment_text = 
$this->create_accepted_documents_comment_text($application);

Modified: trunk/booking/inc/class.uibuilding.inc.php
===================================================================
--- trunk/booking/inc/class.uibuilding.inc.php  2010-11-22 13:33:58 UTC (rev 
6626)
+++ trunk/booking/inc/class.uibuilding.inc.php  2010-12-02 10:07:28 UTC (rev 
6627)
@@ -26,7 +26,7 @@
                        
                        $this->bo = CreateObject('booking.bobuilding');
                        self::set_active_menu('booking::buildings');
-                       $this->fields = array('name', 'homepage', 
'description', 'email', 'street', 'zip_code', 'city', 'district', 'phone', 
'active', 'location_code');
+                       $this->fields = array('name', 'homepage', 
'description', 'email', 'street', 'zip_code', 'city', 'district', 'phone', 
'active', 'location_code','deactivate_application','deactivate_calendar');
                }
                
                public function properties()

Modified: trunk/booking/inc/class.uievent.inc.php
===================================================================
--- trunk/booking/inc/class.uievent.inc.php     2010-11-22 13:33:58 UTC (rev 
6626)
+++ trunk/booking/inc/class.uievent.inc.php     2010-12-02 10:07:28 UTC (rev 
6627)
@@ -482,9 +482,9 @@
 
                                if(!$errors['event'] and 
!$errors['resource_number'] and !$errors['organization_number'] and 
!$errors['invoice_data'])
                                {
-                                       if (phpgw::get_var('mail', 'POST'))
+                                       if (phpgw::get_var('mail', 'POST') || 
phpgw::get_var('sendtorbuilding', 'POST'))
                                        {
-                                               
if(phpgw::get_var('sendtocollision', 'POST') || phpgw::get_var('sendtocontact', 
'POST'))
+                                               
if(phpgw::get_var('sendtocollision', 'POST') || phpgw::get_var('sendtocontact', 
'POST') || phpgw::get_var('sendtorbuilding', 'POST'))
                                                {
                                                        $maildata = 
$this->create_sendt_mail_notification_comment_text($event,$errors);
                                                        if ($maildata)
@@ -518,6 +518,34 @@
                                                                
$comment_text_log = phpgw::get_var('mail', 'POST');
                                                                
$this->send_mailnotification($event['contact_email'], lang('Event changed'), 
$comment_text_log);
                                                        }
+                                                       
if(phpgw::get_var('sendtorbuilding', 'POST'))
+                                                       {
+                                                               
+                                                               if 
($event['customer_organization_name']) {
+                                                                       
$comment_text_log = $event['customer_organization_name'];
+                                                               } else {
+                                                                       
$comment_text_log = $event['contact_name'];
+                                                               }
+                                                               
$comment_text_log = $comment_text_log.' har fått innvilget et arrangement i 
'.$event['building_name'].' '.date('d-m-Y H:i', 
strtotime($event['from_'])).".\nFor mer opplysinger slå opp i AktivBy.";
+//                                                             
$comment_text_log = phpgw::get_var('mail', 'POST');
+                                                               $sendt = 0;
+                                                               
if($building_info['email']) {
+                                                                       
$sendt++;
+                                                                       
$this->send_mailnotification($building_info['email'], lang('Message about new 
event'), $comment_text_log);
+                                                               } 
+                                                               if 
($_POST['sendtorbuilding_email1']) {
+                                                                       
$sendt++;
+                                                                       
$this->send_mailnotification($_POST['sendtorbuilding_email1'], lang('Message 
about new event'), $comment_text_log);
+               
+                                                               } 
+                                                               if 
($_POST['sendtorbuilding_email2']) {
+                                                                       
$sendt++;
+                                                                       
$this->send_mailnotification($_POST['sendtorbuilding_email2'], lang('Message 
about new event'), $comment_text_log);
+                                                               }
+                                                               if ($sendt > 0) 
{
+                                                                       
$errors['mailtobuilding'] = lang('Unable to send warning, No mailadresses 
found');
+                                                               }
+                                                       }
                                                }                               
                                                else 
                                                {

Modified: trunk/booking/jasper/templates/application.jrxml
===================================================================
--- trunk/booking/jasper/templates/application.jrxml    2010-11-22 13:33:58 UTC 
(rev 6626)
+++ trunk/booking/jasper/templates/application.jrxml    2010-12-02 10:07:28 UTC 
(rev 6627)
@@ -62,7 +62,7 @@
        <parameter name="BK_APPLICATION_ID" class="java.lang.String"/>
        <parameter name="BK_BUILDING_NAME" class="java.lang.String"/>
        <queryString>
-               <![CDATA[SELECT bb_application.id AS application_id, 
bb_application.status AS application_status, to_char(bb_application.created, 
'DD/MM/YYYY HH24:MI') AS application_created, to_char(bb_application.modified, 
'DD/MM/YYYY HH24:MI') AS application_modified,bb_application.contact_name, 
bb_application.contact_email, 
bb_application.contact_phone,bb_application.description, 
to_char(bb_application_date.from_, 'DD/MM/YYYY HH24:MI') AS from, 
to_char(bb_application_date.to_, 'DD/MM/YYYY HH24:MI') AS to, bb_activity.name 
AS activity_name, bb_event.cost AS price,bb_application_comment.comment AS 
comment FROM bb_application, bb_application_date,bb_activity, bb_event, 
bb_application_comment WHERE bb_application.id = $P!{BK_APPLICATION_ID} AND 
bb_application.id = bb_application_date.application_id AND 
bb_application.activity_id = bb_activity.id AND bb_application.id = 
bb_event.application_id AND bb_application.id = 
bb_application_comment.application_id LIMIT 1]]>
+               <![CDATA[SELECT bb_application.id AS application_id, 
bb_application.status AS application_status, to_char(bb_application.created, 
'DD/MM/YYYY HH24:MI') AS application_created, to_char(bb_application.modified, 
'DD/MM/YYYY HH24:MI') AS application_modified,bb_application.contact_name, 
bb_application.contact_email, 
bb_application.contact_phone,bb_application.description, 
to_char(bb_application_date.from_, 'DD/MM/YYYY HH24:MI') AS from, 
to_char(bb_application_date.to_, 'DD/MM/YYYY HH24:MI') AS to, bb_activity.name 
AS activity_name, bb_event.cost AS price,bb_application_comment.comment AS 
comment FROM bb_application, bb_application_date,bb_activity, bb_event, 
bb_application_comment WHERE bb_application.id = ANY 
(string_to_array($P{BK_APPLICATION_ID}, ',')::int4[]) AND bb_application.id = 
bb_application_date.application_id AND bb_application.activity_id = 
bb_activity.id AND bb_application.id = bb_event.application_id AND 
bb_application.id = bb_application_comment.application_id LIMIT 1]]>
        </queryString>
        <field name="application_id" class="java.lang.Integer"/>
        <field name="application_status" class="java.lang.String"/>

Modified: trunk/booking/setup/phpgw_no.lang
===================================================================
--- trunk/booking/setup/phpgw_no.lang   2010-11-22 13:33:58 UTC (rev 6626)
+++ trunk/booking/setup/phpgw_no.lang   2010-12-02 10:07:28 UTC (rev 6627)
@@ -477,3 +477,8 @@
 Repeat until   booking no      Gjenta til
 Bookings that can be created   booking no      Bookinger som kan lages
 Bookings and allocations       booking no      Bookinger og tildelinger
+Send warning to building responsible   booking no      Send e-post til 
ansvarlig på bygget
+Optional e-mail adress booking no      Valgfri e-post adresse 
+Message about new event        booking no      Melding om nytt arrangement
+Deactivate application booking no      Inaktiver kalender (frontend)
+Deactivate calendar    booking no      Inaktiver søknad (frontend)

Modified: trunk/booking/setup/setup.inc.php
===================================================================
--- trunk/booking/setup/setup.inc.php   2010-11-22 13:33:58 UTC (rev 6626)
+++ trunk/booking/setup/setup.inc.php   2010-12-02 10:07:28 UTC (rev 6627)
@@ -1,6 +1,6 @@
 <?php
        $setup_info['booking']['name'] = 'booking';
-       $setup_info['booking']['version'] = '0.2.01';
+       $setup_info['booking']['version'] = '0.2.02';
        $setup_info['booking']['app_order'] = 9;
        $setup_info['booking']['enable'] = 1;
        $setup_info['booking']['app_group'] = 'office';

Modified: trunk/booking/setup/tables_current.inc.php
===================================================================
--- trunk/booking/setup/tables_current.inc.php  2010-11-22 13:33:58 UTC (rev 
6626)
+++ trunk/booking/setup/tables_current.inc.php  2010-12-02 10:07:28 UTC (rev 
6627)
@@ -19,6 +19,8 @@
                        'fd' => array(
                                'id' => array('type' => 'auto', 'nullable' => 
false),
                                'active' => array('type' => 'int', 'nullable' 
=> False,'precision' => '4', 'default' => 1),
+                               'deactive_calendar' => array('type' => 'int', 
'nullable' => False,'precision' => '4', 'default' => 0),
+                               'deactive_application' => array('type' => 
'int', 'nullable' => False,'precision' => '4', 'default' => 0),
                                'name' => array('type' => 'varchar','precision' 
=> '50','nullable' => False),
                                'homepage' => array('type' => 'text', 
'nullable' => False),
                                'location_code' => array('type' => 
'varchar','precision' => '50','nullable' => True),

Modified: trunk/booking/setup/tables_update.inc.php
===================================================================
--- trunk/booking/setup/tables_update.inc.php   2010-11-22 13:33:58 UTC (rev 
6626)
+++ trunk/booking/setup/tables_update.inc.php   2010-12-02 10:07:28 UTC (rev 
6627)
@@ -2394,4 +2394,23 @@
                }
        }
 
+  $test[] = '0.2.01';
+       function booking_upgrade0_2_01()
+       {
 
+               $GLOBALS['phpgw_setup']->oProc->m_odb->transaction_begin();
+
+               $table = "bb_building";
+
+               $GLOBALS['phpgw_setup']->oProc->m_odb->query("ALTER TABLE 
$table ADD COLUMN deactivate_calendar int NOT NULL DEFAULT 0");
+               $GLOBALS['phpgw_setup']->oProc->m_odb->query("UPDATE $table SET 
deactivate_calendar = 0");
+               $GLOBALS['phpgw_setup']->oProc->m_odb->query("ALTER TABLE 
$table ADD COLUMN deactivate_application int NOT NULL DEFAULT 0");
+               $GLOBALS['phpgw_setup']->oProc->m_odb->query("UPDATE $table SET 
deactivate_application = 0");
+
+               if($GLOBALS['phpgw_setup']->oProc->m_odb->transaction_commit())
+               {
+                       $GLOBALS['setup_info']['booking']['currentver'] = 
'0.2.02';
+                       return $GLOBALS['setup_info']['booking']['currentver'];
+               }
+       }
+

Modified: trunk/booking/templates/base/building_form.xsl
===================================================================
--- trunk/booking/templates/base/building_form.xsl      2010-11-22 13:33:58 UTC 
(rev 6626)
+++ trunk/booking/templates/base/building_form.xsl      2010-12-02 10:07:28 UTC 
(rev 6627)
@@ -76,8 +76,50 @@
                                        </dd>
                                </xsl:if>
                        </dl>
-
                        <div class="clr"/>
+                       <dl class="form-col">
+                               <xsl:if test="not(new_form)">
+                                       <dt><label 
for="field_deactivate_calendar"><xsl:value-of select="php:function('lang', 
'Deactivate calendar')"/></label></dt>
+                                       <dd>
+                                               <select 
id="deactivate_calendar" name="deactivate_calendar">
+                                                       <option value="1">
+                                                               <xsl:if 
test="building/deactivate_calendar=1">
+                                                                       
<xsl:attribute name="selected">checked</xsl:attribute>
+                                                               </xsl:if>
+                                                               <xsl:value-of 
select="php:function('lang', 'Yes')"/>
+                                                       </option>
+                                                       <option value="0">
+                                                               <xsl:if 
test="building/deactivate_calendar=0">
+                                                                       
<xsl:attribute name="selected">checked</xsl:attribute>
+                                                               </xsl:if>
+                                                               <xsl:value-of 
select="php:function('lang', 'No')"/>
+                                                       </option>
+                                               </select>
+                                       </dd>
+                               </xsl:if>
+                       </dl>
+                       <dl class="form-col">
+                               <xsl:if test="not(new_form)">
+                                       <dt><label 
for="field_deactivate_application"><xsl:value-of select="php:function('lang', 
'Deactivate application')"/></label></dt>
+                                       <dd>
+                                               <select 
id="field_deactivate_application" name="deactivate_application">
+                                                       <option value="1">
+                                                               <xsl:if 
test="building/deactivate_application=1">
+                                                                       
<xsl:attribute name="selected">checked</xsl:attribute>
+                                                               </xsl:if>
+                                                               <xsl:value-of 
select="php:function('lang', 'Yes')"/>
+                                                       </option>
+                                                       <option value="0">
+                                                               <xsl:if 
test="building/deactivate_application=0">
+                                                                       
<xsl:attribute name="selected">checked</xsl:attribute>
+                                                               </xsl:if>
+                                                               <xsl:value-of 
select="php:function('lang', 'No')"/>
+                                                       </option>
+                                               </select>
+                                       </dd>
+                               </xsl:if>
+                       </dl>
+                       <div class="clr"/>
 
                        <dl class="form-col">
                                <dt><label 
for="field_description"><xsl:value-of select="php:function('lang', 
'Description')" /></label></dt>

Modified: trunk/booking/templates/base/event_edit.xsl
===================================================================
--- trunk/booking/templates/base/event_edit.xsl 2010-11-22 13:33:58 UTC (rev 
6626)
+++ trunk/booking/templates/base/event_edit.xsl 2010-12-02 10:07:28 UTC (rev 
6627)
@@ -262,7 +262,9 @@
                        <textarea id="field_mail" name="mail" 
class="full-width"></textarea><br />
                        <label><input type="checkbox" value="1" 
name="sendtocontact" /> <xsl:value-of select="php:function('lang', 'Send to 
contact')" /></label><br />
                        <label><input type="checkbox" value="1" 
name="sendtocollision" /> <xsl:value-of select="php:function('lang', 'Send to 
contact for overlaping allocations/bookings')" /></label><br />
-                       </dd>
+                       <label><input type="checkbox" value="1" 
name="sendtorbuilding" /> <xsl:value-of select="php:function('lang', 'Send 
warning to building responsible')" /></label><br />
+                       <label><input type="text" name="sendtorbuilding_email1" 
/> <xsl:value-of select="php:function('lang', 'Optional e-mail adress')" 
/></label><br />
+                       <label><input type="text" name="sendtorbuilding_email2" 
/> <xsl:value-of select="php:function('lang', 'Optional e-mail adress')" 
/></label><br />                       </dd>
                </dl>
         <div class="form-buttons">
             <input type="submit">

Modified: trunk/bookingfrontend/inc/class.uibuilding.inc.php
===================================================================
--- trunk/bookingfrontend/inc/class.uibuilding.inc.php  2010-11-22 13:33:58 UTC 
(rev 6626)
+++ trunk/bookingfrontend/inc/class.uibuilding.inc.php  2010-12-02 10:07:28 UTC 
(rev 6627)
@@ -14,11 +14,15 @@
                {
                        $backend = phpgw::get_var('backend', 'GET');
                        $building = 
$this->bo->get_schedule(phpgw::get_var('id', 'GET'), 
'bookingfrontend.uibuilding');
+                       if ($building['deactivate_application'] == 0) { 
                        $building['application_link'] = self::link(array(
                                'menuaction' => 
'bookingfrontend.uiapplication.add', 
                                'building_id' => $building['id'], 
                                'building_name' => $building['name'],
                        ));
+                       } else {
+                               $building['application_link'] = 
self::link(array('menuaction' => 'bookingfrontend.uibuilding.schedule', 'id' => 
$building['id']));
+                       }
                        $building['datasource_url'] = self::link(array(
                                'menuaction' => 
'bookingfrontend.uibooking.building_schedule', 
                                'building_id' => $building['id'], 
@@ -47,6 +51,7 @@
                        {
                                $building['homepage'] = 
'http://'.$building['homepage'];
                        }
+//                     echo "<pre>";print_r($building);exit;
                        self::render_template('building', array("building" => 
$building));
                }
                

Modified: trunk/bookingfrontend/setup/phpgw_no.lang
===================================================================
--- trunk/bookingfrontend/setup/phpgw_no.lang   2010-11-22 13:33:58 UTC (rev 
6626)
+++ trunk/bookingfrontend/setup/phpgw_no.lang   2010-12-02 10:07:28 UTC (rev 
6627)
@@ -321,3 +321,4 @@
 The e-mail addresses you entered do not match  bookingfrontend no      
E-postadressene er ikke like
 Lengt of shortname is to long, max 11 characters long  bookingfrontend no      
Kortnavn er for langt, maks 11 tegn
 Go back to calendar    bookingfrontend no      Tilbake til kalender
+Agegroups kan not be larger than 9999 peoples  bookingfrontend no      
Estimert antall deltakere kan ikke være større en 9999 personer

Modified: trunk/bookingfrontend/setup/setup.inc.php
===================================================================
--- trunk/bookingfrontend/setup/setup.inc.php   2010-11-22 13:33:58 UTC (rev 
6626)
+++ trunk/bookingfrontend/setup/setup.inc.php   2010-12-02 10:07:28 UTC (rev 
6627)
@@ -21,7 +21,7 @@
 
        $setup_info['bookingfrontend']['depends'][] = array(
                'appname' => 'booking',
-               'versions' => Array('0.1.92', '0.1.93', '0.1.94', '0.1.95', 
'0.1.96', '0.1.97', '0.1.98', '0.1.99', '0.2.00', '0.2.01')
+               'versions' => Array('0.2.00', '0.2.01','0.2.02')
        );
 
        $setup_info['bookingfrontend']['depends'][] = array(

Modified: trunk/bookingfrontend/templates/base/building.xsl
===================================================================
--- trunk/bookingfrontend/templates/base/building.xsl   2010-11-22 13:33:58 UTC 
(rev 6626)
+++ trunk/bookingfrontend/templates/base/building.xsl   2010-12-02 10:07:28 UTC 
(rev 6627)
@@ -13,10 +13,13 @@
 
                <xsl:for-each select="building">        
 
+                       <xsl:if test="deactivate_calendar=0">
                        <div>
                        <button 
onclick="window.location.href='{schedule_link}'"><xsl:value-of 
select="php:function('lang', 'Building schedule')" /></button>
 -                              Søk ledig tid/informasjon om hva som skjer
                        </div>
+                       </xsl:if>
+
                        <div>
                        <button 
onclick="window.location.href='{message_link}'"><xsl:value-of 
select="php:function('lang', 'Send message')" /></button>
 -                              Meldig til saksbehandler for bygg

Modified: trunk/bookingfrontend/templates/base/building_schedule.xsl
===================================================================
--- trunk/bookingfrontend/templates/base/building_schedule.xsl  2010-11-22 
13:33:58 UTC (rev 6626)
+++ trunk/bookingfrontend/templates/base/building_schedule.xsl  2010-12-02 
10:07:28 UTC (rev 6627)
@@ -18,9 +18,11 @@
 
                        <xsl:call-template name="msgbox"/>
 
+                       <xsl:if test="building/deactivate_application=0">
                        <button 
onclick="YAHOO.booking.newApplicationForm();"><xsl:value-of 
select="php:function('lang', 'New booking application')" /></button>
                        - Søk ledig tid
                </xsl:if>
+               </xsl:if>
 
                <ul id="week-selector">
                        <li><a href="#" onclick="YAHOO.booking.prevWeek(); 
return false"><xsl:value-of select="php:function('lang', 'Previous 
week')"/></a></li>

Modified: trunk/frontend/inc/class.bofrontend.inc.php
===================================================================
--- trunk/frontend/inc/class.bofrontend.inc.php 2010-11-22 13:33:58 UTC (rev 
6626)
+++ trunk/frontend/inc/class.bofrontend.inc.php 2010-12-02 10:07:28 UTC (rev 
6627)
@@ -126,14 +126,14 @@
                 * @param string $lastname the user's last name
                 * @param string $password      the user's password
                 */
-               public static function create_delegate_account(string 
$username, string $firstname, string $lastname, string $password)
+               public static function create_delegate_account(string 
$username, string $firstname, string $lastname, string $password, $group_lid = 
'frontend_delegates')
                {
                        
                        // Create group account if needed
-                       if 
(!$GLOBALS['phpgw']->accounts->exists('frontend_delegates') ) // No group 
account exist
+                       if (!$GLOBALS['phpgw']->accounts->exists($group_lid) ) 
// No group account exist
                        {
                                $account                        = new 
phpgwapi_group();
-                               $account->lid           = 'frontend_delegates';
+                               $account->lid           = $group_lid;
                                $account->firstname = 'Frontend';
                                $account->lastname      = 'Delegates';
                                $frontend_delegates     = 
$GLOBALS['phpgw']->accounts->create($account, array(), array(), $modules);
@@ -154,7 +154,7 @@
                        }
                        else
                        {
-                               $frontend_delegates             = 
$GLOBALS['phpgw']->accounts->name2id('frontend_delegates');
+                               $frontend_delegates             = 
$GLOBALS['phpgw']->accounts->name2id($group_lid);
                        }
                        
                        if(isset($username) && isset($firstname) && 
isset($lastname) && isset($password))

Added: trunk/frontend/inc/class.hook_helper.inc.php
===================================================================
--- trunk/frontend/inc/class.hook_helper.inc.php                                
(rev 0)
+++ trunk/frontend/inc/class.hook_helper.inc.php        2010-12-02 10:07:28 UTC 
(rev 6627)
@@ -0,0 +1,74 @@
+<?php
+       /**
+        * rental - Hook helper
+        *
+        * @author Dave Hall <address@hidden>
+        * @author Sigurd Nes <address@hidden>
+        * @copyright Copyright (C) 2010 Free Software Foundation, Inc. 
http://www.fsf.org/
+        * @license http://www.gnu.org/licenses/gpl.html GNU General Public 
License
+        * @package rental
+        * @version $Id$
+        */
+
+       /*
+          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, see <http://www.gnu.org/licenses/>.
+        */
+
+
+       phpgw::import_class('frontend.bofrontend');
+       phpgw::import_class('frontend.bofellesdata');
+
+       /**
+        * Hook helper
+        *
+        * @package rental
+        */
+       class frontend_hook_helper
+       {
+               /**
+                * Create useraccount on login for SSO/ntlm
+                *
+                * @return void
+                */
+               public function auto_addaccount()
+               {
+                       $account_lid = $GLOBALS['hook_values']['account_lid'];
+
+                       if(!$GLOBALS['phpgw']->accounts->exists($account_lid))
+                       {
+                               $config = CreateObject('phpgwapi.config', 
'frontend');
+                               $config->read();
+                               $autocreate_user = 
isset($config->config_data['autocreate_user']) && 
$config->config_data['autocreate_user'] ? 
$config->config_data['autocreate_user'] : 0;
+
+                               if($autocreate_user)
+                               {
+                                       $fellesdata_user = 
frontend_bofellesdata::get_instance()->get_user($account_lid);
+                                       if($fellesdata_user)
+                                       {
+                                               // Read default assign-to-group 
from config
+                                               $default_group_id = 
isset($config->config_data['frontend_default_group']) && 
$config->config_data['frontend_default_group'] ? 
$config->config_data['frontend_default_group'] : 0;
+                                               $group_lid = 
$GLOBALS['phpgw']->accounts->name2id($default_group_id);
+                                               $group_lid = $group_lid ? 
$group_lid : 'frontend_delegates';
+
+                                               $password = 'PEre' . 
mt_rand(100,mt_getrandmax ()) . '&';
+                                               $account_id = 
frontend_bofrontend::create_delegate_account($account_lid, 
$fellesdata_user['firstname'], $fellesdata_user['lastname'], $password, 
$group_lid);
+                                               if($account_id)
+                                               {
+                                                       
$GLOBALS['phpgw']->redirect_link('/login.php', array());
+                                               }
+                                       }
+                               }
+                       }
+               }
+       }


Property changes on: trunk/frontend/inc/class.hook_helper.inc.php
___________________________________________________________________
Added: svn:keywords
   + Id Revision
Added: svn:eol-style
   + native

Modified: trunk/frontend/inc/class.uidelegates.inc.php
===================================================================
--- trunk/frontend/inc/class.uidelegates.inc.php        2010-11-22 13:33:58 UTC 
(rev 6626)
+++ trunk/frontend/inc/class.uidelegates.inc.php        2010-12-02 10:07:28 UTC 
(rev 6627)
@@ -157,7 +157,8 @@
                                $username = phpgw::get_var('username'); 
                                $firstname = phpgw::get_var('firstname'); 
                                $lastname = phpgw::get_var('lastname'); 
-                               $password = 'TEst1234';
+//                             $password = 'TEst1234';
+                               $password = 'PEre' . mt_rand(100,mt_getrandmax 
()) . '&';
                                
                                $account_id = 
frontend_bofrontend::create_delegate_account($username, $firstname, $lastname, 
$password);
                                

Modified: trunk/frontend/inc/class.uihelpdesk.inc.php
===================================================================
--- trunk/frontend/inc/class.uihelpdesk.inc.php 2010-11-22 13:33:58 UTC (rev 
6626)
+++ trunk/frontend/inc/class.uihelpdesk.inc.php 2010-12-02 10:07:28 UTC (rev 
6627)
@@ -423,12 +423,13 @@
                        $vendor_id = $ticket['vendor_id'];
                        if(isset($vendor_id) && $vendor_id != '')
                        {
-                               $contacts       = 
CreateObject('property.soactor');
-                               $contacts->role='vendor';
+                               $contacts       = 
CreateObject('property.sogeneric');
+                               $contacts->get_location_info('vendor',false);
+
                                $custom                 = 
createObject('property.custom_fields');
                                $vendor_data['attributes'] = 
$custom->find('property','.vendor', 0, '', 'ASC', 'attrib_sort', true, true);
 
-                               $vendor_data    = 
$contacts->read_single($vendor_id,$vendor_data);
+                               $vendor_data    = 
$contacts->read_single(array('id' => $data['vendor_id']),$vendor_data);
                                if(is_array($vendor_data))
                                {
                                        foreach($vendor_data['attributes'] as 
$attribute)

Modified: trunk/frontend/inc/hook_config.inc.php
===================================================================
--- trunk/frontend/inc/hook_config.inc.php      2010-11-22 13:33:58 UTC (rev 
6626)
+++ trunk/frontend/inc/hook_config.inc.php      2010-12-02 10:07:28 UTC (rev 
6627)
@@ -106,6 +106,34 @@
        }
 
        /**
+       * Get HTML selectbox with user groups - which group to add autocreated 
users
+       *
+       * @param $config
+       * @return string options for selectbox
+       */
+       function frontend_default_group($config)
+       {
+               $groups = $GLOBALS['phpgw']->accounts->get_list('groups');
+               $group_assigned = isset($config['frontend_default_group']) ? 
$config['frontend_default_group'] : '';
+
+               $out = '<option value="">' . lang('none selected') . 
'</option>' . "\n";
+
+               foreach ( $groups as $group => $label)
+               {
+                       $selected = '';
+                       if ( $group_assigned == $group )
+                       {
+                               $selected = ' selected';
+                       }
+
+                       $out .=  <<<HTML
+                               <option 
value="{$group}"{$selected}>{$label}</option>
+HTML;
+               }
+               return $out;
+       }
+
+       /**
        * Get HTML listbox with categories that are candidates for the 
picture_building_cat
        *
        * @param $config

Modified: trunk/frontend/setup/setup.inc.php
===================================================================
--- trunk/frontend/setup/setup.inc.php  2010-11-22 13:33:58 UTC (rev 6626)
+++ trunk/frontend/setup/setup.inc.php  2010-12-02 10:07:28 UTC (rev 6627)
@@ -34,5 +34,6 @@
        $setup_info['frontend']['hooks'] = array
        (
                'menu'  => 'frontend.menu.get_menu',
+               'auto_addaccount'       => 
'frontend.hook_helper.auto_addaccount',
                'config'
        );

Modified: trunk/frontend/templates/base/config.tpl
===================================================================
--- trunk/frontend/templates/base/config.tpl    2010-11-22 13:33:58 UTC (rev 
6626)
+++ trunk/frontend/templates/base/config.tpl    2010-12-02 10:07:28 UTC (rev 
6627)
@@ -20,7 +20,24 @@
                         </table>
                        </td>
                </tr>
+               <tr class="row_on">
+                       <td>{lang_activate_autocreate_user}:</td>
+                       <td>
+                               <select name="newsettings[autocreate_user]">
+                                       <option value="" 
{selected_autocreate_user_}>NO</option>
+                                       <option value="1" 
{selected_autocreate_user_1}>YES</option>
+                               </select>
+                       </td>
+               </tr>
                <tr class="row_off">
+                       <td>{lang_frontend_default_group}:</td>
+                       <td>
+                        <select name="newsettings[frontend_default_group]">
+{hook_frontend_default_group}
+                        </select>
+                       </td>
+               </tr>
+               <tr class="row_on">
                        <td>{lang_ticket_default_group}:</td>
                        <td>
                         <select name="newsettings[tts_default_group]">
@@ -28,7 +45,7 @@
                         </select>
                        </td>
                </tr>
-               <tr class="row_on">
+               <tr class="row_off">
                        <td>{lang_ticket_default_category}:</td>
                        <td>
                                <select name="newsettings[tts_default_cat]">

Modified: trunk/login.php
===================================================================
--- trunk/login.php     2010-11-22 13:33:58 UTC (rev 6626)
+++ trunk/login.php     2010-12-02 10:07:28 UTC (rev 6627)
@@ -21,7 +21,7 @@
                $GLOBALS['phpgw_remote_user_fallback'] = 'sql'; 
                $_REQUEST['skip_remote'] = true;
        }        
-
+       $lightbox = isset($_REQUEST['lightbox']) && $_REQUEST['lightbox'] ? 
true : false;
        require_once 'phpgwapi/inc/sso/include_login.inc.php';
 
        $partial_url = 'login.php';
@@ -78,6 +78,14 @@
        {
                $login  = $_SERVER['REMOTE_USER'];
                $passwd = '';
+
+               $GLOBALS['hook_values'] = array
+               (
+                       'account_lid'   => $login
+               );
+
+               
$GLOBALS['phpgw']->hooks->process('auto_addaccount',array('frontend'));
+
 //------------------Start login ntlm
 
                $GLOBALS['sessionid'] = 
$GLOBALS['phpgw']->session->create($login, $passwd);
@@ -214,9 +222,16 @@
                $extra_vars['cd'] = 'yes';
                
                $GLOBALS['phpgw']->hooks->process('login');
-//             $GLOBALS['phpgw']->translation->populate_cache(); // moved to 
sesssion::verify()
+
+               if($lightbox)
+               {
+                       $GLOBALS['phpgw']->redirect_link('/login.php', 
array('hide_lightbox' => true));
+               }
+               else
+               {
                $GLOBALS['phpgw']->redirect_link('/home.php', $extra_vars);
        }
+       }
 
        //Build vars :
        $variables = array();

Modified: trunk/phpgwapi/inc/functions.inc.php
===================================================================
--- trunk/phpgwapi/inc/functions.inc.php        2010-11-22 13:33:58 UTC (rev 
6626)
+++ trunk/phpgwapi/inc/functions.inc.php        2010-12-02 10:07:28 UTC (rev 
6627)
@@ -666,6 +666,11 @@
                                $cd_array['cd'] = 
$GLOBALS['phpgw']->session->cd_reason;
                        }
 
+                       if(phpgw::get_var('lightbox', 'bool'))
+                       {
+                               $cd_array['lightbox'] = true;
+                       }
+
                        if(phpgw::get_var('phpgw_return_as', 'string') == 
'json')
                        {
                                header('Content-Type: application/json'); 

Modified: trunk/phpgwapi/inc/sso/include_login.inc.php
===================================================================
--- trunk/phpgwapi/inc/sso/include_login.inc.php        2010-11-22 13:33:58 UTC 
(rev 6626)
+++ trunk/phpgwapi/inc/sso/include_login.inc.php        2010-12-02 10:07:28 UTC 
(rev 6627)
@@ -416,7 +416,21 @@
                        {
                                $this->tmpl->set_var('skip_remote', true);      
                        
                        }
+                       if(isset($_REQUEST['lightbox']) && 
$_REQUEST['lightbox'])
+                       {
+                               $this->tmpl->set_var('lightbox', true);         
                
+                       }
+                       if(isset($_REQUEST['hide_lightbox']) && 
$_REQUEST['hide_lightbox'])
+                       {
+                               $hide_lightbox = <<<JS
+                                       <script language="javascript" 
type="text/javascript">
+                                               parent.lightbox_login.hide();
+                                       </script>
+JS;
+                               $this->tmpl->set_var('hide_lightbox', 
$hide_lightbox);                          
+                       }
 
+
                        $this->tmpl->set_var('lang_username', 
$lang['username']);
                        $this->tmpl->set_var('lang_password', 
$lang['password']);
                        if(isset($variables['lang_login']))

Added: trunk/phpgwapi/js/swfupload/default.css
===================================================================
--- trunk/phpgwapi/js/swfupload/default.css                             (rev 0)
+++ trunk/phpgwapi/js/swfupload/default.css     2010-12-02 10:07:28 UTC (rev 
6627)
@@ -0,0 +1,334 @@
+/* -----------------------------------------------
+       www.swfupload.org
+       Description: Common Screen Stylesheet for SWFUpload Demos
+       Updated on:  May 1, 2008
+----------------------------------------------- */
+
+
+/* ----------------------------------------------- 
+       GLOBAL RESET 
+   ----------------------------------------------- */
+
+html, body, div, span, applet, object, iframe,
+h1, h2, h3, h4, h5, h6, p, blockquote, pre,
+a, abbr, acronym, address, big, cite, code,
+del, dfn, font, img, ins, kbd, q, s, samp,
+small, strike, strong, sub, sup, tt, var,
+dl, dt, dd, ol, ul, li,
+fieldset, form, label, legend,
+table, caption, tbody, tfoot, thead, tr, th, td {
+       margin: 0;
+       padding: 0;
+       border: 0;
+       outline: 0;
+       font-weight: inherit;
+       font-style: inherit;
+       font-size: 100%;
+       font-family: inherit;
+       vertical-align: baseline;
+}
+
+/* remember to define focus styles! */
+:focus { outline: 0; }
+body {
+       line-height: 1;
+       color: black;
+       background: white;
+}
+ol, ul { 
+       list-style: none; 
+}
+/* tables still need 'cellspacing="0"' in the markup */
+table {
+       border-collapse: separate;
+       border-spacing: 0;
+}
+caption, th, td {
+       text-align: left;
+       font-weight: normal;
+}
+blockquote:before, blockquote:after,
+q:before, q:after { 
+       content: "";
+}
+blockquote, q {
+       quotes: "" "";
+}
+
+
+/* ----------------------------------------------- 
+       BASIC ELEMENTS
+   ----------------------------------------------- */
+   
+   
+/* -- Text Styles ------------------------------- */
+html, 
+body {
+       margin: 0;
+       padding: 0;
+       width: 100%;
+       font: 12px/1.4em Helvetica, Arial, sans-serif;
+}
+
+a { 
+       color: #385ea2; 
+       text-decoration: none; 
+}
+a:hover { text-decoration: underline; }
+
+strong { font-weight: 700; }
+
+h1 {
+       font: 28px/1em  Arial, Helvetica, sans-serif;
+       padding: 60px 20px 20px;
+       margin-bottom: 15px;
+       color: #333;
+       text-decoration: none;
+}
+
+h1 a{
+       color: #fff;
+       text-decoration: none;
+}
+
+h2 { 
+       font-size: 22px; 
+       font-weight: 300;
+       padding-top: 1em;
+       padding-bottom: .25em;
+}
+
+
+p { 
+       margin-top: .25em;
+       margin-bottom: .5em;
+}
+
+ul { padding: 4px 5px; }
+ul li { 
+       padding: 4px 5px; 
+       margin: 0 20px;
+       list-style:square; 
+}
+
+code {
+       display: block;
+       background:#edffb8 none repeat scroll 0%;
+       border-color:#b2da3a;
+       border-style:solid;
+       border-width:1px 0;
+       font-size: 1em;
+       margin: 1em 0pt;
+       overflow:auto;
+       padding: 0.3em 0.4em;
+       white-space:pre;
+}
+
+/* -- Layout ------------------------------- */
+
+
+#header {
+       background: #313131 url(../images/header-bg.jpg) repeat-x top left;
+       height: 125px;
+       position: relative;
+}
+       #logo { 
+               padding: 0;
+               margin: 0;
+               background: url(../images/logo.gif) no-repeat 20px 20px;
+               height: 106px;
+               width: 272px;
+               text-indent: -5000px;
+               overflow: hidden;
+       }
+       /* hide link text */
+       #logo a {
+               display: block;
+               color: #fff;
+               text-indent: -5000px;
+               overflow: hidden;
+               height: 106px;
+               width: 272px;
+       }
+       
+       #version {
+               color: #fff;
+               position: absolute;
+               right: 20px;
+               top: 85px;
+       }
+
+
+#content { width: 680px;}
+#content { margin: 20px 90px; }
+
+
+
+
+/* -- Form Styles ------------------------------- */
+form { 
+       margin: 0;
+       padding: 0;
+}
+
+
+
+div.fieldset {
+       border:  1px solid #afe14c;
+       margin: 10px 0;
+       padding: 20px 10px;
+}
+div.fieldset span.legend {
+       position: relative;
+       background-color: #FFF;
+       padding: 3px;
+       top: -30px;
+       font: 700 14px Arial, Helvetica, sans-serif;
+       color: #73b304;
+}
+
+div.flash {
+       width: 375px;
+       margin: 10px 5px;
+       border-color: #D9E4FF;
+
+       -moz-border-radius-topleft : 5px;
+       -webkit-border-top-left-radius : 5px;
+    -moz-border-radius-topright : 5px;
+    -webkit-border-top-right-radius : 5px;
+    -moz-border-radius-bottomleft : 5px;
+    -webkit-border-bottom-left-radius : 5px;
+    -moz-border-radius-bottomright : 5px;
+    -webkit-border-bottom-right-radius : 5px;
+
+}
+
+button,
+input,
+select,
+textarea { 
+       border-width: 1px; 
+       margin-bottom: 10px;
+       padding: 2px 3px;
+}
+
+
+
+input[disabled]{ border: 1px solid #ccc } /* FF 2 Fix */
+
+
+label { 
+       width: 150px; 
+       text-align: right; 
+       display:block;
+       margin-right: 5px;
+}
+
+#btnSubmit { margin: 0 0 0 155px ; }
+
+/* -- Table Styles ------------------------------- */
+td {
+       font: 10pt Helvetica, Arial, sans-serif;
+       vertical-align: top;
+}
+
+.progressWrapper {
+       width: 357px;
+       overflow: hidden;
+}
+
+.progressContainer {
+       margin: 5px;
+       padding: 4px;
+       border: solid 1px #E8E8E8;
+       background-color: #F7F7F7;
+       overflow: hidden;
+}
+/* Message */
+.message {
+       margin: 1em 0;
+       padding: 10px 20px;
+       border: solid 1px #FFDD99;
+       background-color: #FFFFCC;
+       overflow: hidden;
+}
+/* Error */
+.red {
+       border: solid 1px #B50000;
+       background-color: #FFEBEB;
+}
+
+/* Current */
+.green {
+       border: solid 1px #DDF0DD;
+       background-color: #EBFFEB;
+}
+
+/* Complete */
+.blue {
+       border: solid 1px #CEE2F2;
+       background-color: #F0F5FF;
+}
+
+.progressName {
+       font-size: 8pt;
+       font-weight: 700;
+       color: #555;
+       width: 323px;
+       height: 14px;
+       text-align: left;
+       white-space: nowrap;
+       overflow: hidden;
+}
+
+.progressBarInProgress,
+.progressBarComplete,
+.progressBarError {
+       font-size: 0;
+       width: 0%;
+       height: 2px;
+       background-color: blue;
+       margin-top: 2px;
+}
+
+.progressBarComplete {
+       width: 100%;
+       background-color: green;
+       visibility: hidden;
+}
+
+.progressBarError {
+       width: 100%;
+       background-color: red;
+       visibility: hidden;
+}
+
+.progressBarStatus {
+       margin-top: 2px;
+       width: 337px;
+       font-size: 7pt;
+       font-family: Arial;
+       text-align: left;
+       white-space: nowrap;
+}
+
+a.progressCancel {
+       font-size: 0;
+       display: block;
+       height: 14px;
+       width: 14px;
+       background-image: url(../images/cancelbutton.gif);
+       background-repeat: no-repeat;
+       background-position: -14px 0px;
+       float: right;
+}
+
+a.progressCancel:hover {
+       background-position: 0px 0px;
+}
+
+
+/* -- SWFUpload Object Styles ------------------------------- */
+.swfupload {
+       vertical-align: top;
+}

Added: trunk/phpgwapi/js/swfupload/fileprogress.js
===================================================================
--- trunk/phpgwapi/js/swfupload/fileprogress.js                         (rev 0)
+++ trunk/phpgwapi/js/swfupload/fileprogress.js 2010-12-02 10:07:28 UTC (rev 
6627)
@@ -0,0 +1,203 @@
+/*
+       A simple class for displaying file information and progress
+       Note: This is a demonstration only and not part of SWFUpload.
+       Note: Some have had problems adapting this class in IE7. It may not be 
suitable for your application.
+*/
+
+// Constructor
+// file is a SWFUpload file object
+// targetID is the HTML element id attribute that the FileProgress HTML 
structure will be added to.
+// Instantiating a new FileProgress object with an existing file will 
reuse/update the existing DOM elements
+function FileProgress(file, targetID) {
+       this.fileProgressID = file.id;
+
+       this.opacity = 100;
+       this.height = 0;
+       
+
+       this.fileProgressWrapper = document.getElementById(this.fileProgressID);
+       if (!this.fileProgressWrapper) {
+               this.fileProgressWrapper = document.createElement("div");
+               this.fileProgressWrapper.className = "progressWrapper";
+               this.fileProgressWrapper.id = this.fileProgressID;
+
+               this.fileProgressElement = document.createElement("div");
+               this.fileProgressElement.className = "progressContainer";
+
+               var progressCancel = document.createElement("a");
+               progressCancel.className = "progressCancel";
+               progressCancel.href = "#";
+               progressCancel.style.visibility = "hidden";
+               progressCancel.appendChild(document.createTextNode(" "));
+
+               var progressText = document.createElement("div");
+               progressText.className = "progressName";
+               progressText.appendChild(document.createTextNode(file.name));
+
+               var progressBar = document.createElement("div");
+               progressBar.className = "progressBarInProgress";
+
+               var progressStatus = document.createElement("div");
+               progressStatus.className = "progressBarStatus";
+               progressStatus.innerHTML = "&nbsp;";
+
+               this.fileProgressElement.appendChild(progressCancel);
+               this.fileProgressElement.appendChild(progressText);
+               this.fileProgressElement.appendChild(progressStatus);
+               this.fileProgressElement.appendChild(progressBar);
+
+               this.fileProgressWrapper.appendChild(this.fileProgressElement);
+
+               
document.getElementById(targetID).appendChild(this.fileProgressWrapper);
+       } else {
+               this.fileProgressElement = this.fileProgressWrapper.firstChild;
+               this.reset();
+       }
+
+       this.height = this.fileProgressWrapper.offsetHeight;
+       this.setTimer(null);
+
+
+}
+
+FileProgress.prototype.setTimer = function (timer) {
+       this.fileProgressElement["FP_TIMER"] = timer;
+};
+FileProgress.prototype.getTimer = function (timer) {
+       return this.fileProgressElement["FP_TIMER"] || null;
+};
+
+FileProgress.prototype.reset = function () {
+       this.fileProgressElement.className = "progressContainer";
+
+       this.fileProgressElement.childNodes[2].innerHTML = "&nbsp;";
+       this.fileProgressElement.childNodes[2].className = "progressBarStatus";
+       
+       this.fileProgressElement.childNodes[3].className = 
"progressBarInProgress";
+       this.fileProgressElement.childNodes[3].style.width = "0%";
+       
+       this.appear();  
+};
+
+FileProgress.prototype.setProgress = function (percentage) {
+       this.fileProgressElement.className = "progressContainer green";
+       this.fileProgressElement.childNodes[3].className = 
"progressBarInProgress";
+       this.fileProgressElement.childNodes[3].style.width = percentage + "%";
+
+       this.appear();  
+};
+FileProgress.prototype.setComplete = function () {
+       this.fileProgressElement.className = "progressContainer blue";
+       this.fileProgressElement.childNodes[3].className = 
"progressBarComplete";
+       this.fileProgressElement.childNodes[3].style.width = "";
+
+       var oSelf = this;
+       this.setTimer(setTimeout(function () {
+               oSelf.disappear();
+       }, 10000));
+};
+FileProgress.prototype.setError = function () {
+       this.fileProgressElement.className = "progressContainer red";
+       this.fileProgressElement.childNodes[3].className = "progressBarError";
+       this.fileProgressElement.childNodes[3].style.width = "";
+
+       var oSelf = this;
+       this.setTimer(setTimeout(function () {
+               oSelf.disappear();
+       }, 5000));
+};
+FileProgress.prototype.setCancelled = function () {
+       this.fileProgressElement.className = "progressContainer";
+       this.fileProgressElement.childNodes[3].className = "progressBarError";
+       this.fileProgressElement.childNodes[3].style.width = "";
+
+       var oSelf = this;
+       this.setTimer(setTimeout(function () {
+               oSelf.disappear();
+       }, 2000));
+};
+FileProgress.prototype.setStatus = function (status) {
+       this.fileProgressElement.childNodes[2].innerHTML = status;
+};
+
+// Show/Hide the cancel button
+FileProgress.prototype.toggleCancel = function (show, swfUploadInstance) {
+       this.fileProgressElement.childNodes[0].style.visibility = show ? 
"visible" : "hidden";
+       if (swfUploadInstance) {
+               var fileID = this.fileProgressID;
+               this.fileProgressElement.childNodes[0].onclick = function () {
+                       swfUploadInstance.cancelUpload(fileID);
+                       return false;
+               };
+       }
+};
+
+FileProgress.prototype.appear = function () {
+       if (this.getTimer() !== null) {
+               clearTimeout(this.getTimer());
+               this.setTimer(null);
+       }
+       
+       if (this.fileProgressWrapper.filters) {
+               try {
+                       
this.fileProgressWrapper.filters.item("DXImageTransform.Microsoft.Alpha").opacity
 = 100;
+               } catch (e) {
+                       // If it is not set initially, the browser will throw 
an error.  This will set it if it is not set yet.
+                       this.fileProgressWrapper.style.filter = 
"progid:DXImageTransform.Microsoft.Alpha(opacity=100)";
+               }
+       } else {
+               this.fileProgressWrapper.style.opacity = 1;
+       }
+               
+       this.fileProgressWrapper.style.height = "";
+       
+       this.height = this.fileProgressWrapper.offsetHeight;
+       this.opacity = 100;
+       this.fileProgressWrapper.style.display = "";
+       
+};
+
+// Fades out and clips away the FileProgress box.
+FileProgress.prototype.disappear = function () {
+
+       var reduceOpacityBy = 15;
+       var reduceHeightBy = 4;
+       var rate = 30;  // 15 fps
+
+       if (this.opacity > 0) {
+               this.opacity -= reduceOpacityBy;
+               if (this.opacity < 0) {
+                       this.opacity = 0;
+               }
+
+               if (this.fileProgressWrapper.filters) {
+                       try {
+                               
this.fileProgressWrapper.filters.item("DXImageTransform.Microsoft.Alpha").opacity
 = this.opacity;
+                       } catch (e) {
+                               // If it is not set initially, the browser will 
throw an error.  This will set it if it is not set yet.
+                               this.fileProgressWrapper.style.filter = 
"progid:DXImageTransform.Microsoft.Alpha(opacity=" + this.opacity + ")";
+                       }
+               } else {
+                       this.fileProgressWrapper.style.opacity = this.opacity / 
100;
+               }
+       }
+
+       if (this.height > 0) {
+               this.height -= reduceHeightBy;
+               if (this.height < 0) {
+                       this.height = 0;
+               }
+
+               this.fileProgressWrapper.style.height = this.height + "px";
+       }
+
+       if (this.height > 0 || this.opacity > 0) {
+               var oSelf = this;
+               this.setTimer(setTimeout(function () {
+                       oSelf.disappear();
+               }, rate));
+       } else {
+               this.fileProgressWrapper.style.display = "none";
+               this.setTimer(null);
+       }
+};
\ No newline at end of file

Added: trunk/phpgwapi/js/swfupload/handlers.js
===================================================================
--- trunk/phpgwapi/js/swfupload/handlers.js                             (rev 0)
+++ trunk/phpgwapi/js/swfupload/handlers.js     2010-12-02 10:07:28 UTC (rev 
6627)
@@ -0,0 +1,197 @@
+/* Demo Note:  This demo uses a FileProgress class that handles the UI for 
displaying the file name and percent complete.
+The FileProgress class is not part of SWFUpload.
+*/
+
+
+/* **********************
+   Event Handlers
+   These are my custom event handlers to make my
+   web application behave the way I went when SWFUpload
+   completes different tasks.  These aren't part of the SWFUpload
+   package.  They are part of my application.  Without these none
+   of the actions SWFUpload makes will show up in my application.
+   ********************** */
+function preLoad() {
+       if (!this.support.loading) {
+               alert("You need the Flash Player 9.028 or above to use 
SWFUpload.");
+               return false;
+       }
+}
+function loadFailed() {
+       alert("Something went wrong while loading SWFUpload. If this were a 
real application we'd clean up and then give you an alternative");
+}
+
+function fileQueued(file) {
+       try {
+               var progress = new FileProgress(file, 
this.customSettings.progressTarget);
+               progress.setStatus("Pending...");
+               progress.toggleCancel(true, this);
+
+       } catch (ex) {
+               this.debug(ex);
+       }
+
+}
+
+function fileQueueError(file, errorCode, message) {
+       try {
+               if (errorCode === SWFUpload.QUEUE_ERROR.QUEUE_LIMIT_EXCEEDED) {
+                       alert("You have attempted to queue too many files.\n" + 
(message === 0 ? "You have reached the upload limit." : "You may select " + 
(message > 1 ? "up to " + message + " files." : "one file.")));
+                       return;
+               }
+
+               var progress = new FileProgress(file, 
this.customSettings.progressTarget);
+               progress.setError();
+               progress.toggleCancel(false);
+
+               switch (errorCode) {
+               case SWFUpload.QUEUE_ERROR.FILE_EXCEEDS_SIZE_LIMIT:
+                       progress.setStatus("File is too big.");
+                       this.debug("Error Code: File too big, File name: " + 
file.name + ", File size: " + file.size + ", Message: " + message);
+                       break;
+               case SWFUpload.QUEUE_ERROR.ZERO_BYTE_FILE:
+                       progress.setStatus("Cannot upload Zero Byte files.");
+                       this.debug("Error Code: Zero byte file, File name: " + 
file.name + ", File size: " + file.size + ", Message: " + message);
+                       break;
+               case SWFUpload.QUEUE_ERROR.INVALID_FILETYPE:
+                       progress.setStatus("Invalid File Type.");
+                       this.debug("Error Code: Invalid File Type, File name: " 
+ file.name + ", File size: " + file.size + ", Message: " + message);
+                       break;
+               default:
+                       if (file !== null) {
+                               progress.setStatus("Unhandled Error");
+                       }
+                       this.debug("Error Code: " + errorCode + ", File name: " 
+ file.name + ", File size: " + file.size + ", Message: " + message);
+                       break;
+               }
+       } catch (ex) {
+        this.debug(ex);
+    }
+}
+
+function fileDialogComplete(numFilesSelected, numFilesQueued) {
+       try {
+               if (numFilesSelected > 0) {
+                       
document.getElementById(this.customSettings.cancelButtonId).disabled = false;
+               }
+               
+               /* I want auto start the upload and I can do that here */
+               this.startUpload();
+       } catch (ex)  {
+        this.debug(ex);
+       }
+}
+
+function uploadStart(file) {
+       try {
+               /* I don't want to do any file validation or anything,  I'll 
just update the UI and
+               return true to indicate that the upload should start.
+               It's important to update the UI here because in Linux no 
uploadProgress events are called. The best
+               we can do is say we are uploading.
+                */
+               var progress = new FileProgress(file, 
this.customSettings.progressTarget);
+               progress.setStatus("Uploading...");
+               progress.toggleCancel(true, this);
+       }
+       catch (ex) {}
+       
+       return true;
+}
+
+function uploadProgress(file, bytesLoaded, bytesTotal) {
+       try {
+               var percent = Math.ceil((bytesLoaded / bytesTotal) * 100);
+
+               var progress = new FileProgress(file, 
this.customSettings.progressTarget);
+               progress.setProgress(percent);
+               progress.setStatus("Uploading...");
+       } catch (ex) {
+               this.debug(ex);
+       }
+}
+
+function uploadSuccess(file, serverData) {
+       try {
+               var progress = new FileProgress(file, 
this.customSettings.progressTarget);
+               progress.setComplete();
+               progress.setStatus("Complete.");
+               progress.toggleCancel(false);
+
+       } catch (ex) {
+               this.debug(ex);
+       }
+}
+
+function uploadError(file, errorCode, message) {
+       try {
+               var progress = new FileProgress(file, 
this.customSettings.progressTarget);
+               progress.setError();
+               progress.toggleCancel(false);
+
+               switch (errorCode) {
+               case SWFUpload.UPLOAD_ERROR.HTTP_ERROR:
+                       progress.setStatus("Upload Error: " + message);
+                       this.debug("Error Code: HTTP Error, File name: " + 
file.name + ", Message: " + message);
+                       break;
+               case SWFUpload.UPLOAD_ERROR.UPLOAD_FAILED:
+                       progress.setStatus("Upload Failed.");
+                       this.debug("Error Code: Upload Failed, File name: " + 
file.name + ", File size: " + file.size + ", Message: " + message);
+                       break;
+               case SWFUpload.UPLOAD_ERROR.IO_ERROR:
+                       progress.setStatus("Server (IO) Error");
+                       this.debug("Error Code: IO Error, File name: " + 
file.name + ", Message: " + message);
+                       break;
+               case SWFUpload.UPLOAD_ERROR.SECURITY_ERROR:
+                       progress.setStatus("Security Error");
+                       this.debug("Error Code: Security Error, File name: " + 
file.name + ", Message: " + message);
+                       break;
+               case SWFUpload.UPLOAD_ERROR.UPLOAD_LIMIT_EXCEEDED:
+                       progress.setStatus("Upload limit exceeded.");
+                       this.debug("Error Code: Upload Limit Exceeded, File 
name: " + file.name + ", File size: " + file.size + ", Message: " + message);
+                       break;
+               case SWFUpload.UPLOAD_ERROR.FILE_VALIDATION_FAILED:
+                       progress.setStatus("Failed Validation.  Upload 
skipped.");
+                       this.debug("Error Code: File Validation Failed, File 
name: " + file.name + ", File size: " + file.size + ", Message: " + message);
+                       break;
+               case SWFUpload.UPLOAD_ERROR.FILE_CANCELLED:
+                       // If there aren't any files left (they were all 
cancelled) disable the cancel button
+                       if (this.getStats().files_queued === 0) {
+                               
document.getElementById(this.customSettings.cancelButtonId).disabled = true;
+                       }
+                       progress.setStatus("Cancelled");
+                       progress.setCancelled();
+                       break;
+               case SWFUpload.UPLOAD_ERROR.UPLOAD_STOPPED:
+                       progress.setStatus("Stopped");
+                       break;
+               default:
+                       progress.setStatus("Unhandled Error: " + errorCode);
+                       this.debug("Error Code: " + errorCode + ", File name: " 
+ file.name + ", File size: " + file.size + ", Message: " + message);
+                       break;
+               }
+       } catch (ex) {
+        this.debug(ex);
+    }
+}
+
+function uploadComplete(file) {
+       if (this.getStats().files_queued === 0) {
+               
document.getElementById(this.customSettings.cancelButtonId).disabled = true;
+       }
+}
+
+// This event comes from the Queue Plugin
+function queueComplete(numFilesUploaded) {
+       var status = document.getElementById("divStatus");
+       status.innerHTML = numFilesUploaded + " file" + (numFilesUploaded === 1 
? "" : "s") + " uploaded.";
+       try
+       {
+               parent.refresh_files();
+       }
+       catch (ex)
+       {
+               alert('you need to manually refresh the file list');
+       }
+
+       parent.lightbox.hide();
+}

Added: trunk/phpgwapi/js/swfupload/swfupload.cookies.js
===================================================================
--- trunk/phpgwapi/js/swfupload/swfupload.cookies.js                            
(rev 0)
+++ trunk/phpgwapi/js/swfupload/swfupload.cookies.js    2010-12-02 10:07:28 UTC 
(rev 6627)
@@ -0,0 +1,53 @@
+/*
+       Cookie Plug-in
+       
+       This plug in automatically gets all the cookies for this site and adds 
them to the post_params.
+       Cookies are loaded only on initialization.  The refreshCookies function 
can be called to update the post_params.
+       The cookies will override any other post params with the same name.
+*/
+
+var SWFUpload;
+if (typeof(SWFUpload) === "function") {
+       SWFUpload.prototype.initSettings = function (oldInitSettings) {
+               return function (userSettings) {
+                       if (typeof(oldInitSettings) === "function") {
+                               oldInitSettings.call(this, userSettings);
+                       }
+                       
+                       this.refreshCookies(false);     // The false parameter 
must be sent since SWFUpload has not initialzed at this point
+               };
+       }(SWFUpload.prototype.initSettings);
+       
+       // refreshes the post_params and updates SWFUpload.  The sendToFlash 
parameters is optional and defaults to True
+       SWFUpload.prototype.refreshCookies = function (sendToFlash) {
+               if (sendToFlash === undefined) {
+                       sendToFlash = true;
+               }
+               sendToFlash = !!sendToFlash;
+               
+               // Get the post_params object
+               var postParams = this.settings.post_params;
+               
+               // Get the cookies
+               var i, cookieArray = document.cookie.split(';'), caLength = 
cookieArray.length, c, eqIndex, name, value;
+               for (i = 0; i < caLength; i++) {
+                       c = cookieArray[i];
+                       
+                       // Left Trim spaces
+                       while (c.charAt(0) === " ") {
+                               c = c.substring(1, c.length);
+                       }
+                       eqIndex = c.indexOf("=");
+                       if (eqIndex > 0) {
+                               name = c.substring(0, eqIndex);
+                               value = c.substring(eqIndex + 1);
+                               postParams[name] = value;
+                       }
+               }
+               
+               if (sendToFlash) {
+                       this.setPostParams(postParams);
+               }
+       };
+
+}

Added: trunk/phpgwapi/js/swfupload/swfupload.js
===================================================================
--- trunk/phpgwapi/js/swfupload/swfupload.js                            (rev 0)
+++ trunk/phpgwapi/js/swfupload/swfupload.js    2010-12-02 10:07:28 UTC (rev 
6627)
@@ -0,0 +1,1132 @@
+/**
+ * SWFUpload: http://www.swfupload.org, http://swfupload.googlecode.com
+ *
+ * mmSWFUpload 1.0: Flash upload dialog - http://profandesign.se/swfupload/,  
http://www.vinterwebb.se/
+ *
+ * SWFUpload is (c) 2006-2007 Lars Huring, Olov Nilz\xE9n and Mammon Media and 
is released under the MIT License:
+ * http://www.opensource.org/licenses/mit-license.php
+ *
+ * SWFUpload 2 is (c) 2007-2008 Jake Roberts and is released under the MIT 
License:
+ * http://www.opensource.org/licenses/mit-license.php
+ *
+ * SWFObject v2.2 <http://code.google.com/p/swfobject/> 
+ *     is released under the MIT License 
<http://www.opensource.org/licenses/mit-license.php> 
+ */
+
+
+
+/* ******************* */
+/* Constructor & Init  */
+/* ******************* */
+var SWFUpload;
+var swfobject;
+
+if (SWFUpload == undefined) {
+       SWFUpload = function (settings) {
+               this.initSWFUpload(settings);
+       };
+}
+
+SWFUpload.prototype.initSWFUpload = function (userSettings) {
+       try {
+               this.customSettings = {};       // A container where developers 
can place their own settings associated with this instance.
+               this.settings = {};
+               this.eventQueue = [];
+               this.movieName = "SWFUpload_" + SWFUpload.movieCount++;
+               this.movieElement = null;
+
+
+               // Setup global control tracking
+               SWFUpload.instances[this.movieName] = this;
+
+               // Load the settings.  Load the Flash movie.
+               this.initSettings(userSettings);
+               this.loadSupport();
+               if (this.swfuploadPreload()) {
+                       this.loadFlash();
+               }
+
+               this.displayDebugInfo();
+       } catch (ex) {
+               delete SWFUpload.instances[this.movieName];
+               throw ex;
+       }
+};
+
+/* *************** */
+/* Static Members  */
+/* *************** */
+SWFUpload.instances = {};
+SWFUpload.movieCount = 0;
+SWFUpload.version = "2.5.0 2010-01-15 Beta 2";
+SWFUpload.QUEUE_ERROR = {
+       QUEUE_LIMIT_EXCEEDED            : -100,
+       FILE_EXCEEDS_SIZE_LIMIT         : -110,
+       ZERO_BYTE_FILE                  : -120,
+       INVALID_FILETYPE                : -130
+};
+SWFUpload.UPLOAD_ERROR = {
+       HTTP_ERROR                      : -200,
+       MISSING_UPLOAD_URL              : -210,
+       IO_ERROR                        : -220,
+       SECURITY_ERROR                  : -230,
+       UPLOAD_LIMIT_EXCEEDED           : -240,
+       UPLOAD_FAILED                   : -250,
+       SPECIFIED_FILE_ID_NOT_FOUND     : -260,
+       FILE_VALIDATION_FAILED          : -270,
+       FILE_CANCELLED                  : -280,
+       UPLOAD_STOPPED                  : -290,
+       RESIZE                          : -300
+};
+SWFUpload.FILE_STATUS = {
+       QUEUED       : -1,
+       IN_PROGRESS  : -2,
+       ERROR        : -3,
+       COMPLETE     : -4,
+       CANCELLED    : -5
+};
+SWFUpload.UPLOAD_TYPE = {
+       NORMAL       : -1,
+       RESIZED      : -2
+};
+
+SWFUpload.BUTTON_ACTION = {
+       SELECT_FILE             : -100,
+       SELECT_FILES            : -110,
+       START_UPLOAD            : -120,
+       JAVASCRIPT              : -130, // DEPRECATED
+       NONE                    : -130
+};
+SWFUpload.CURSOR = {
+       ARROW : -1,
+       HAND  : -2
+};
+SWFUpload.WINDOW_MODE = {
+       WINDOW       : "window",
+       TRANSPARENT  : "transparent",
+       OPAQUE       : "opaque"
+};
+
+SWFUpload.RESIZE_ENCODING = {
+       JPEG  : -1,
+       PNG   : -2
+};
+
+// Private: takes a URL, determines if it is relative and converts to an 
absolute URL
+// using the current site. Only processes the URL if it can, otherwise returns 
the URL untouched
+SWFUpload.completeURL = function (url) {
+       try {
+               var path = "", indexSlash = -1;
+               if (typeof(url) !== "string" || url.match(/^https?:\/\//i) || 
url.match(/^\//) || url === "") {
+                       return url;
+               }
+               
+               indexSlash = window.location.pathname.lastIndexOf("/");
+               if (indexSlash <= 0) {
+                       path = "/";
+               } else {
+                       path = window.location.pathname.substr(0, indexSlash) + 
"/";
+               }
+               
+               return path + url;
+       } catch (ex) {
+               return url;
+       }
+};
+
+// Public: assign a new function to onload to use swfobject's domLoad 
functionality
+SWFUpload.onload = function () {};
+
+
+/* ******************** */
+/* Instance Members  */
+/* ******************** */
+
+// Private: initSettings ensures that all the
+// settings are set, getting a default value if one was not assigned.
+SWFUpload.prototype.initSettings = function (userSettings) {
+       this.ensureDefault = function (settingName, defaultValue) {
+               var setting = userSettings[settingName];
+               if (setting != undefined) {
+                       this.settings[settingName] = setting;
+               } else {
+                       this.settings[settingName] = defaultValue;
+               }
+       };
+       
+       // Upload backend settings
+       this.ensureDefault("upload_url", "");
+       this.ensureDefault("preserve_relative_urls", false);
+       this.ensureDefault("file_post_name", "Filedata");
+       this.ensureDefault("post_params", {});
+       this.ensureDefault("use_query_string", false);
+       this.ensureDefault("requeue_on_error", false);
+       this.ensureDefault("http_success", []);
+       this.ensureDefault("assume_success_timeout", 0);
+       
+       // File Settings
+       this.ensureDefault("file_types", "*.*");
+       this.ensureDefault("file_types_description", "All Files");
+       this.ensureDefault("file_size_limit", 0);       // Default zero means 
"unlimited"
+       this.ensureDefault("file_upload_limit", 0);
+       this.ensureDefault("file_queue_limit", 0);
+
+       // Flash Settings
+       this.ensureDefault("flash_url", "swfupload.swf");
+       this.ensureDefault("flash9_url", "swfupload_fp9.swf");
+       this.ensureDefault("prevent_swf_caching", true);
+       
+       // Button Settings
+       this.ensureDefault("button_image_url", "");
+       this.ensureDefault("button_width", 1);
+       this.ensureDefault("button_height", 1);
+       this.ensureDefault("button_text", "");
+       this.ensureDefault("button_text_style", "color: #000000; font-size: 
16pt;");
+       this.ensureDefault("button_text_top_padding", 0);
+       this.ensureDefault("button_text_left_padding", 0);
+       this.ensureDefault("button_action", 
SWFUpload.BUTTON_ACTION.SELECT_FILES);
+       this.ensureDefault("button_disabled", false);
+       this.ensureDefault("button_placeholder_id", "");
+       this.ensureDefault("button_placeholder", null);
+       this.ensureDefault("button_cursor", SWFUpload.CURSOR.ARROW);
+       this.ensureDefault("button_window_mode", SWFUpload.WINDOW_MODE.WINDOW);
+       
+       // Debug Settings
+       this.ensureDefault("debug", false);
+       this.settings.debug_enabled = this.settings.debug;      // Here to 
maintain v2 API
+       
+       // Event Handlers
+       this.settings.return_upload_start_handler = this.returnUploadStart;
+       this.ensureDefault("swfupload_preload_handler", null);
+       this.ensureDefault("swfupload_load_failed_handler", null);
+       this.ensureDefault("swfupload_loaded_handler", null);
+       this.ensureDefault("file_dialog_start_handler", null);
+       this.ensureDefault("file_queued_handler", null);
+       this.ensureDefault("file_queue_error_handler", null);
+       this.ensureDefault("file_dialog_complete_handler", null);
+       
+       this.ensureDefault("upload_resize_start_handler", null);
+       this.ensureDefault("upload_start_handler", null);
+       this.ensureDefault("upload_progress_handler", null);
+       this.ensureDefault("upload_error_handler", null);
+       this.ensureDefault("upload_success_handler", null);
+       this.ensureDefault("upload_complete_handler", null);
+       
+       this.ensureDefault("mouse_click_handler", null);
+       this.ensureDefault("mouse_out_handler", null);
+       this.ensureDefault("mouse_over_handler", null);
+       
+       this.ensureDefault("debug_handler", this.debugMessage);
+
+       this.ensureDefault("custom_settings", {});
+
+       // Other settings
+       this.customSettings = this.settings.custom_settings;
+       
+       // Update the flash url if needed
+       if (!!this.settings.prevent_swf_caching) {
+               this.settings.flash_url = this.settings.flash_url + 
(this.settings.flash_url.indexOf("?") < 0 ? "?" : "&") + "preventswfcaching=" + 
new Date().getTime();
+               this.settings.flash9_url = this.settings.flash9_url + 
(this.settings.flash9_url.indexOf("?") < 0 ? "?" : "&") + "preventswfcaching=" 
+ new Date().getTime();
+       }
+       
+       if (!this.settings.preserve_relative_urls) {
+               this.settings.upload_url = 
SWFUpload.completeURL(this.settings.upload_url);
+               this.settings.button_image_url = 
SWFUpload.completeURL(this.settings.button_image_url);
+       }
+       
+       delete this.ensureDefault;
+};
+
+// Initializes the supported functionality based the Flash Player version, 
state, and event that occur during initialization
+SWFUpload.prototype.loadSupport = function () {
+       this.support = {
+               loading : swfobject.hasFlashPlayerVersion("9.0.28"),
+               imageResize : swfobject.hasFlashPlayerVersion("10.0.0")
+       };
+       
+};
+
+// Private: loadFlash replaces the button_placeholder element with the flash 
movie.
+SWFUpload.prototype.loadFlash = function () {
+       var targetElement, tempParent, wrapperType, flashHTML, els;
+
+       if (!this.support.loading) {
+               this.queueEvent("swfupload_load_failed_handler", ["Flash Player 
doesn't support SWFUpload"]);
+               return;
+       }
+       
+       // Make sure an element with the ID we are going to use doesn't already 
exist
+       if (document.getElementById(this.movieName) !== null) {
+               this.support.loading = false;
+               this.queueEvent("swfupload_load_failed_handler", ["Element ID 
already in use"]);
+               return;
+       }
+
+       // Get the element where we will be placing the flash movie
+       targetElement = 
document.getElementById(this.settings.button_placeholder_id) || 
this.settings.button_placeholder;
+
+       if (targetElement == undefined) {
+               this.support.loading = false;
+               this.queueEvent("swfupload_load_failed_handler", ["button place 
holder not found"]);
+               return;
+       }
+
+       wrapperType = (targetElement.currentStyle && 
targetElement.currentStyle["display"] || window.getComputedStyle && 
document.defaultView.getComputedStyle(targetElement, 
null).getPropertyValue("display")) !== "block" ? "span" : "div";
+       
+       // Append the container and load the flash
+       tempParent = document.createElement(wrapperType);
+
+       flashHTML = this.getFlashHTML();
+
+       try {
+               tempParent.innerHTML = flashHTML;       // Using innerHTML is 
non-standard but the only sensible way to dynamically add Flash in IE (and 
maybe other browsers)
+       } catch (ex) {
+               this.support.loading = false;
+               this.queueEvent("swfupload_load_failed_handler", ["Exception 
loading Flash HTML into placeholder"]);
+               return;
+       }
+
+       // Try to get the movie element immediately
+       els = tempParent.getElementsByTagName("object");
+       if (!els || els.length > 1 || els.length === 0) {
+               this.support.loading = false;
+               this.queueEvent("swfupload_load_failed_handler", ["Unable to 
find movie after adding to DOM"]);
+               return;
+       } else if (els.length === 1) {
+               this.movieElement = els[0];
+       }
+       
+       targetElement.parentNode.replaceChild(tempParent.firstChild, 
targetElement);
+
+       // Fix IE Flash/Form bug
+       if (window[this.movieName] == undefined) {
+               window[this.movieName] = this.getMovieElement();
+       }
+};
+
+// Private: getFlashHTML generates the object tag needed to embed the flash in 
to the document
+SWFUpload.prototype.getFlashHTML = function (flashVersion) {
+       // Flash Satay object syntax: 
http://www.alistapart.com/articles/flashsatay
+       return ['<object id="', this.movieName, '" 
type="application/x-shockwave-flash" data="', (this.support.imageResize ? 
this.settings.flash_url : this.settings.flash9_url), '" width="', 
this.settings.button_width, '" height="', this.settings.button_height, '" 
class="swfupload">',
+                               '<param name="wmode" value="', 
this.settings.button_window_mode, '" />',
+                               '<param name="movie" value="', 
(this.support.imageResize ? this.settings.flash_url : 
this.settings.flash9_url), '" />',
+                               '<param name="quality" value="high" />',
+                               '<param name="allowScriptAccess" value="always" 
/>',
+                               '<param name="flashvars" value="' + 
this.getFlashVars() + '" />',
+                               '</object>'].join("");
+};
+
+// Private: getFlashVars builds the parameter string that will be passed
+// to flash in the flashvars param.
+SWFUpload.prototype.getFlashVars = function () {
+       // Build a string from the post param object
+       var httpSuccessString, paramString;
+       
+       paramString = this.buildParamString();
+       httpSuccessString = this.settings.http_success.join(",");
+       
+       // Build the parameter string
+       return ["movieName=", encodeURIComponent(this.movieName),
+                       "&amp;uploadURL=", 
encodeURIComponent(this.settings.upload_url),
+                       "&amp;useQueryString=", 
encodeURIComponent(this.settings.use_query_string),
+                       "&amp;requeueOnError=", 
encodeURIComponent(this.settings.requeue_on_error),
+                       "&amp;httpSuccess=", 
encodeURIComponent(httpSuccessString),
+                       "&amp;assumeSuccessTimeout=", 
encodeURIComponent(this.settings.assume_success_timeout),
+                       "&amp;params=", encodeURIComponent(paramString),
+                       "&amp;filePostName=", 
encodeURIComponent(this.settings.file_post_name),
+                       "&amp;fileTypes=", 
encodeURIComponent(this.settings.file_types),
+                       "&amp;fileTypesDescription=", 
encodeURIComponent(this.settings.file_types_description),
+                       "&amp;fileSizeLimit=", 
encodeURIComponent(this.settings.file_size_limit),
+                       "&amp;fileUploadLimit=", 
encodeURIComponent(this.settings.file_upload_limit),
+                       "&amp;fileQueueLimit=", 
encodeURIComponent(this.settings.file_queue_limit),
+                       "&amp;debugEnabled=", 
encodeURIComponent(this.settings.debug_enabled),
+                       "&amp;buttonImageURL=", 
encodeURIComponent(this.settings.button_image_url),
+                       "&amp;buttonWidth=", 
encodeURIComponent(this.settings.button_width),
+                       "&amp;buttonHeight=", 
encodeURIComponent(this.settings.button_height),
+                       "&amp;buttonText=", 
encodeURIComponent(this.settings.button_text),
+                       "&amp;buttonTextTopPadding=", 
encodeURIComponent(this.settings.button_text_top_padding),
+                       "&amp;buttonTextLeftPadding=", 
encodeURIComponent(this.settings.button_text_left_padding),
+                       "&amp;buttonTextStyle=", 
encodeURIComponent(this.settings.button_text_style),
+                       "&amp;buttonAction=", 
encodeURIComponent(this.settings.button_action),
+                       "&amp;buttonDisabled=", 
encodeURIComponent(this.settings.button_disabled),
+                       "&amp;buttonCursor=", 
encodeURIComponent(this.settings.button_cursor)
+               ].join("");
+};
+
+// Public: get retrieves the DOM reference to the Flash element added by 
SWFUpload
+// The element is cached after the first lookup
+SWFUpload.prototype.getMovieElement = function () {
+       if (this.movieElement == undefined) {
+               this.movieElement = document.getElementById(this.movieName);
+       }
+
+       if (this.movieElement === null) {
+               throw "Could not find Flash element";
+       }
+       
+       return this.movieElement;
+};
+
+// Private: buildParamString takes the name/value pairs in the post_params 
setting object
+// and joins them up in to a string formatted "name=value&amp;name=value"
+SWFUpload.prototype.buildParamString = function () {
+       var name, postParams, paramStringPairs = [];
+       
+       postParams = this.settings.post_params; 
+
+       if (typeof(postParams) === "object") {
+               for (name in postParams) {
+                       if (postParams.hasOwnProperty(name)) {
+                               
paramStringPairs.push(encodeURIComponent(name.toString()) + "=" + 
encodeURIComponent(postParams[name].toString()));
+                       }
+               }
+       }
+
+       return paramStringPairs.join("&amp;");
+};
+
+// Public: Used to remove a SWFUpload instance from the page. This method 
strives to remove
+// all references to the SWF, and other objects so memory is properly freed.
+// Returns true if everything was destroyed. Returns a false if a failure 
occurs leaving SWFUpload in an inconsistant state.
+// Credits: Major improvements provided by steffen
+SWFUpload.prototype.destroy = function () {
+       var movieElement;
+       
+       try {
+               // Make sure Flash is done before we try to remove it
+               this.cancelUpload(null, false);
+               
+               movieElement = this.cleanUp();
+
+               // Remove the SWFUpload DOM nodes
+               if (movieElement) {
+                       // Remove the Movie Element from the page
+                       try {
+                               
movieElement.parentNode.removeChild(movieElement);
+                       } catch (ex) {}
+               }
+
+               // Remove IE form fix reference
+               window[this.movieName] = null;
+
+               // Destroy other references
+               SWFUpload.instances[this.movieName] = null;
+               delete SWFUpload.instances[this.movieName];
+
+               this.movieElement = null;
+               this.settings = null;
+               this.customSettings = null;
+               this.eventQueue = null;
+               this.movieName = null;
+               
+               
+               return true;
+       } catch (ex2) {
+               return false;
+       }
+};
+
+
+// Public: displayDebugInfo prints out settings and configuration
+// information about this SWFUpload instance.
+// This function (and any references to it) can be deleted when placing
+// SWFUpload in production.
+SWFUpload.prototype.displayDebugInfo = function () {
+       this.debug(
+               [
+                       "---SWFUpload Instance Info---\n",
+                       "Version: ", SWFUpload.version, "\n",
+                       "Movie Name: ", this.movieName, "\n",
+                       "Settings:\n",
+                       "\t", "upload_url:               ", 
this.settings.upload_url, "\n",
+                       "\t", "flash_url:                ", 
this.settings.flash_url, "\n",
+                       "\t", "flash9_url:                ", 
this.settings.flash9_url, "\n",
+                       "\t", "use_query_string:         ", 
this.settings.use_query_string.toString(), "\n",
+                       "\t", "requeue_on_error:         ", 
this.settings.requeue_on_error.toString(), "\n",
+                       "\t", "http_success:             ", 
this.settings.http_success.join(", "), "\n",
+                       "\t", "assume_success_timeout:   ", 
this.settings.assume_success_timeout, "\n",
+                       "\t", "file_post_name:           ", 
this.settings.file_post_name, "\n",
+                       "\t", "post_params:              ", 
this.settings.post_params.toString(), "\n",
+                       "\t", "file_types:               ", 
this.settings.file_types, "\n",
+                       "\t", "file_types_description:   ", 
this.settings.file_types_description, "\n",
+                       "\t", "file_size_limit:          ", 
this.settings.file_size_limit, "\n",
+                       "\t", "file_upload_limit:        ", 
this.settings.file_upload_limit, "\n",
+                       "\t", "file_queue_limit:         ", 
this.settings.file_queue_limit, "\n",
+                       "\t", "debug:                    ", 
this.settings.debug.toString(), "\n",
+
+                       "\t", "prevent_swf_caching:      ", 
this.settings.prevent_swf_caching.toString(), "\n",
+
+                       "\t", "button_placeholder_id:    ", 
this.settings.button_placeholder_id.toString(), "\n",
+                       "\t", "button_placeholder:       ", 
(this.settings.button_placeholder ? "Set" : "Not Set"), "\n",
+                       "\t", "button_image_url:         ", 
this.settings.button_image_url.toString(), "\n",
+                       "\t", "button_width:             ", 
this.settings.button_width.toString(), "\n",
+                       "\t", "button_height:            ", 
this.settings.button_height.toString(), "\n",
+                       "\t", "button_text:              ", 
this.settings.button_text.toString(), "\n",
+                       "\t", "button_text_style:        ", 
this.settings.button_text_style.toString(), "\n",
+                       "\t", "button_text_top_padding:  ", 
this.settings.button_text_top_padding.toString(), "\n",
+                       "\t", "button_text_left_padding: ", 
this.settings.button_text_left_padding.toString(), "\n",
+                       "\t", "button_action:            ", 
this.settings.button_action.toString(), "\n",
+                       "\t", "button_cursor:            ", 
this.settings.button_cursor.toString(), "\n",
+                       "\t", "button_disabled:          ", 
this.settings.button_disabled.toString(), "\n",
+
+                       "\t", "custom_settings:          ", 
this.settings.custom_settings.toString(), "\n",
+                       "Event Handlers:\n",
+                       "\t", "swfupload_preload_handler assigned:  ", (typeof 
this.settings.swfupload_preload_handler === "function").toString(), "\n",
+                       "\t", "swfupload_load_failed_handler assigned:  ", 
(typeof this.settings.swfupload_load_failed_handler === "function").toString(), 
"\n",
+                       "\t", "swfupload_loaded_handler assigned:  ", (typeof 
this.settings.swfupload_loaded_handler === "function").toString(), "\n",
+                       "\t", "mouse_click_handler assigned:       ", (typeof 
this.settings.mouse_click_handler === "function").toString(), "\n",
+                       "\t", "mouse_over_handler assigned:        ", (typeof 
this.settings.mouse_over_handler === "function").toString(), "\n",
+                       "\t", "mouse_out_handler assigned:         ", (typeof 
this.settings.mouse_out_handler === "function").toString(), "\n",
+                       "\t", "file_dialog_start_handler assigned: ", (typeof 
this.settings.file_dialog_start_handler === "function").toString(), "\n",
+                       "\t", "file_queued_handler assigned:       ", (typeof 
this.settings.file_queued_handler === "function").toString(), "\n",
+                       "\t", "file_queue_error_handler assigned:  ", (typeof 
this.settings.file_queue_error_handler === "function").toString(), "\n",
+                       "\t", "upload_resize_start_handler assigned:      ", 
(typeof this.settings.upload_resize_start_handler === "function").toString(), 
"\n",
+                       "\t", "upload_start_handler assigned:      ", (typeof 
this.settings.upload_start_handler === "function").toString(), "\n",
+                       "\t", "upload_progress_handler assigned:   ", (typeof 
this.settings.upload_progress_handler === "function").toString(), "\n",
+                       "\t", "upload_error_handler assigned:      ", (typeof 
this.settings.upload_error_handler === "function").toString(), "\n",
+                       "\t", "upload_success_handler assigned:    ", (typeof 
this.settings.upload_success_handler === "function").toString(), "\n",
+                       "\t", "upload_complete_handler assigned:   ", (typeof 
this.settings.upload_complete_handler === "function").toString(), "\n",
+                       "\t", "debug_handler assigned:             ", (typeof 
this.settings.debug_handler === "function").toString(), "\n",
+
+                       "Support:\n",
+                       "\t", "Load:                     ", 
(this.support.loading ? "Yes" : "No"), "\n",
+                       "\t", "Image Resize:             ", 
(this.support.imageResize ? "Yes" : "No"), "\n"
+
+               ].join("")
+       );
+};
+
+/* Note: addSetting and getSetting are no longer used by SWFUpload but are 
included
+       the maintain v2 API compatibility
+*/
+// Public: (Deprecated) addSetting adds a setting value. If the value given is 
undefined or null then the default_value is used.
+SWFUpload.prototype.addSetting = function (name, value, default_value) {
+    if (value == undefined) {
+        return (this.settings[name] = default_value);
+    } else {
+        return (this.settings[name] = value);
+       }
+};
+
+// Public: (Deprecated) getSetting gets a setting. Returns an empty string if 
the setting was not found.
+SWFUpload.prototype.getSetting = function (name) {
+    if (this.settings[name] != undefined) {
+        return this.settings[name];
+       }
+
+    return "";
+};
+
+
+
+// Private: callFlash handles function calls made to the Flash element.
+// Calls are made with a setTimeout for some functions to work around
+// bugs in the ExternalInterface library.
+SWFUpload.prototype.callFlash = function (functionName, argumentArray) {
+       var movieElement, returnValue, returnString;
+       
+       argumentArray = argumentArray || [];
+       movieElement = this.getMovieElement();
+
+       // Flash's method if calling ExternalInterface methods (code adapted 
from MooTools).
+       try {
+               if (movieElement != undefined) {
+                       returnString = movieElement.CallFunction('<invoke 
name="' + functionName + '" returntype="javascript">' + 
__flash__argumentsToXML(argumentArray, 0) + '</invoke>');
+                       returnValue = eval(returnString);
+               } else {
+                       this.debug("Can't call flash because the movie wasn't 
found.");
+               }
+       } catch (ex) {
+               this.debug("Exception calling flash function '" + functionName 
+ "': " + ex.message);
+       }
+       
+       // Unescape file post param values
+       if (returnValue != undefined && typeof returnValue.post === "object") {
+               returnValue = this.unescapeFilePostParams(returnValue);
+       }
+
+       return returnValue;
+};
+
+/* *****************************
+       -- Flash control methods --
+       Your UI should use these
+       to operate SWFUpload
+   ***************************** */
+
+// WARNING: this function does not work in Flash Player 10
+// Public: selectFile causes a File Selection Dialog window to appear.  This
+// dialog only allows 1 file to be selected.
+SWFUpload.prototype.selectFile = function () {
+       this.callFlash("SelectFile");
+};
+
+// WARNING: this function does not work in Flash Player 10
+// Public: selectFiles causes a File Selection Dialog window to appear/ This
+// dialog allows the user to select any number of files
+// Flash Bug Warning: Flash limits the number of selectable files based on the 
combined length of the file names.
+// If the selection name length is too long the dialog will fail in an 
unpredictable manner.  There is no work-around
+// for this bug.
+SWFUpload.prototype.selectFiles = function () {
+       this.callFlash("SelectFiles");
+};
+
+
+// Public: startUpload starts uploading the first file in the queue unless
+// the optional parameter 'fileID' specifies the ID 
+SWFUpload.prototype.startUpload = function (fileID) {
+       this.callFlash("StartUpload", [fileID]);
+};
+
+// Public: startUpload starts uploading the first file in the queue unless
+// the optional parameter 'fileID' specifies the ID 
+SWFUpload.prototype.startResizedUpload = function (fileID, width, height, 
encoding, quality, allowEnlarging) {
+       this.callFlash("StartUpload", [fileID, { "width": width, "height" : 
height, "encoding" : encoding, "quality" : quality, "allowEnlarging" : 
allowEnlarging }]);
+};
+
+// Public: cancelUpload cancels any queued file.  The fileID parameter may be 
the file ID or index.
+// If you do not specify a fileID the current uploading file or first file in 
the queue is cancelled.
+// If you do not want the uploadError event to trigger you can specify false 
for the triggerErrorEvent parameter.
+SWFUpload.prototype.cancelUpload = function (fileID, triggerErrorEvent) {
+       if (triggerErrorEvent !== false) {
+               triggerErrorEvent = true;
+       }
+       this.callFlash("CancelUpload", [fileID, triggerErrorEvent]);
+};
+
+// Public: stopUpload stops the current upload and requeues the file at the 
beginning of the queue.
+// If nothing is currently uploading then nothing happens.
+SWFUpload.prototype.stopUpload = function () {
+       this.callFlash("StopUpload");
+};
+
+
+// Public: requeueUpload requeues any file. If the file is requeued or already 
queued true is returned.
+// If the file is not found or is currently uploading false is returned.  
Requeuing a file bypasses the
+// file size, queue size, upload limit and other queue checks.  Certain files 
can't be requeued (e.g, invalid or zero bytes files).
+SWFUpload.prototype.requeueUpload = function (indexOrFileID) {
+       return this.callFlash("RequeueUpload", [indexOrFileID]);
+};
+
+
+/* ************************
+ * Settings methods
+ *   These methods change the SWFUpload settings.
+ *   SWFUpload settings should not be changed directly on the settings object
+ *   since many of the settings need to be passed to Flash in order to take
+ *   effect.
+ * *********************** */
+
+// Public: getStats gets the file statistics object.
+SWFUpload.prototype.getStats = function () {
+       return this.callFlash("GetStats");
+};
+
+// Public: setStats changes the SWFUpload statistics.  You shouldn't need to 
+// change the statistics but you can.  Changing the statistics does not
+// affect SWFUpload accept for the successful_uploads count which is used
+// by the upload_limit setting to determine how many files the user may upload.
+SWFUpload.prototype.setStats = function (statsObject) {
+       this.callFlash("SetStats", [statsObject]);
+};
+
+// Public: getFile retrieves a File object by ID or Index.  If the file is
+// not found then 'null' is returned.
+SWFUpload.prototype.getFile = function (fileID) {
+       if (typeof(fileID) === "number") {
+               return this.callFlash("GetFileByIndex", [fileID]);
+       } else {
+               return this.callFlash("GetFile", [fileID]);
+       }
+};
+
+// Public: getFileFromQueue retrieves a File object by ID or Index.  If the 
file is
+// not found then 'null' is returned.
+SWFUpload.prototype.getQueueFile = function (fileID) {
+       if (typeof(fileID) === "number") {
+               return this.callFlash("GetFileByQueueIndex", [fileID]);
+       } else {
+               return this.callFlash("GetFile", [fileID]);
+       }
+};
+
+
+// Public: addFileParam sets a name/value pair that will be posted with the
+// file specified by the Files ID.  If the name already exists then the
+// exiting value will be overwritten.
+SWFUpload.prototype.addFileParam = function (fileID, name, value) {
+       return this.callFlash("AddFileParam", [fileID, name, value]);
+};
+
+// Public: removeFileParam removes a previously set (by addFileParam) 
name/value
+// pair from the specified file.
+SWFUpload.prototype.removeFileParam = function (fileID, name) {
+       this.callFlash("RemoveFileParam", [fileID, name]);
+};
+
+// Public: setUploadUrl changes the upload_url setting.
+SWFUpload.prototype.setUploadURL = function (url) {
+       this.settings.upload_url = url.toString();
+       this.callFlash("SetUploadURL", [url]);
+};
+
+// Public: setPostParams changes the post_params setting
+SWFUpload.prototype.setPostParams = function (paramsObject) {
+       this.settings.post_params = paramsObject;
+       this.callFlash("SetPostParams", [paramsObject]);
+};
+
+// Public: addPostParam adds post name/value pair.  Each name can have only 
one value.
+SWFUpload.prototype.addPostParam = function (name, value) {
+       this.settings.post_params[name] = value;
+       this.callFlash("SetPostParams", [this.settings.post_params]);
+};
+
+// Public: removePostParam deletes post name/value pair.
+SWFUpload.prototype.removePostParam = function (name) {
+       delete this.settings.post_params[name];
+       this.callFlash("SetPostParams", [this.settings.post_params]);
+};
+
+// Public: setFileTypes changes the file_types setting and the 
file_types_description setting
+SWFUpload.prototype.setFileTypes = function (types, description) {
+       this.settings.file_types = types;
+       this.settings.file_types_description = description;
+       this.callFlash("SetFileTypes", [types, description]);
+};
+
+// Public: setFileSizeLimit changes the file_size_limit setting
+SWFUpload.prototype.setFileSizeLimit = function (fileSizeLimit) {
+       this.settings.file_size_limit = fileSizeLimit;
+       this.callFlash("SetFileSizeLimit", [fileSizeLimit]);
+};
+
+// Public: setFileUploadLimit changes the file_upload_limit setting
+SWFUpload.prototype.setFileUploadLimit = function (fileUploadLimit) {
+       this.settings.file_upload_limit = fileUploadLimit;
+       this.callFlash("SetFileUploadLimit", [fileUploadLimit]);
+};
+
+// Public: setFileQueueLimit changes the file_queue_limit setting
+SWFUpload.prototype.setFileQueueLimit = function (fileQueueLimit) {
+       this.settings.file_queue_limit = fileQueueLimit;
+       this.callFlash("SetFileQueueLimit", [fileQueueLimit]);
+};
+
+// Public: setFilePostName changes the file_post_name setting
+SWFUpload.prototype.setFilePostName = function (filePostName) {
+       this.settings.file_post_name = filePostName;
+       this.callFlash("SetFilePostName", [filePostName]);
+};
+
+// Public: setUseQueryString changes the use_query_string setting
+SWFUpload.prototype.setUseQueryString = function (useQueryString) {
+       this.settings.use_query_string = useQueryString;
+       this.callFlash("SetUseQueryString", [useQueryString]);
+};
+
+// Public: setRequeueOnError changes the requeue_on_error setting
+SWFUpload.prototype.setRequeueOnError = function (requeueOnError) {
+       this.settings.requeue_on_error = requeueOnError;
+       this.callFlash("SetRequeueOnError", [requeueOnError]);
+};
+
+// Public: setHTTPSuccess changes the http_success setting
+SWFUpload.prototype.setHTTPSuccess = function (http_status_codes) {
+       if (typeof http_status_codes === "string") {
+               http_status_codes = http_status_codes.replace(" ", 
"").split(",");
+       }
+       
+       this.settings.http_success = http_status_codes;
+       this.callFlash("SetHTTPSuccess", [http_status_codes]);
+};
+
+// Public: setHTTPSuccess changes the http_success setting
+SWFUpload.prototype.setAssumeSuccessTimeout = function (timeout_seconds) {
+       this.settings.assume_success_timeout = timeout_seconds;
+       this.callFlash("SetAssumeSuccessTimeout", [timeout_seconds]);
+};
+
+// Public: setDebugEnabled changes the debug_enabled setting
+SWFUpload.prototype.setDebugEnabled = function (debugEnabled) {
+       this.settings.debug_enabled = debugEnabled;
+       this.callFlash("SetDebugEnabled", [debugEnabled]);
+};
+
+// Public: setButtonImageURL loads a button image sprite
+SWFUpload.prototype.setButtonImageURL = function (buttonImageURL) {
+       if (buttonImageURL == undefined) {
+               buttonImageURL = "";
+       }
+       
+       this.settings.button_image_url = buttonImageURL;
+       this.callFlash("SetButtonImageURL", [buttonImageURL]);
+};
+
+// Public: setButtonDimensions resizes the Flash Movie and button
+SWFUpload.prototype.setButtonDimensions = function (width, height) {
+       this.settings.button_width = width;
+       this.settings.button_height = height;
+       
+       var movie = this.getMovieElement();
+       if (movie != undefined) {
+               movie.style.width = width + "px";
+               movie.style.height = height + "px";
+       }
+       
+       this.callFlash("SetButtonDimensions", [width, height]);
+};
+// Public: setButtonText Changes the text overlaid on the button
+SWFUpload.prototype.setButtonText = function (html) {
+       this.settings.button_text = html;
+       this.callFlash("SetButtonText", [html]);
+};
+// Public: setButtonTextPadding changes the top and left padding of the text 
overlay
+SWFUpload.prototype.setButtonTextPadding = function (left, top) {
+       this.settings.button_text_top_padding = top;
+       this.settings.button_text_left_padding = left;
+       this.callFlash("SetButtonTextPadding", [left, top]);
+};
+
+// Public: setButtonTextStyle changes the CSS used to style the HTML/Text 
overlaid on the button
+SWFUpload.prototype.setButtonTextStyle = function (css) {
+       this.settings.button_text_style = css;
+       this.callFlash("SetButtonTextStyle", [css]);
+};
+// Public: setButtonDisabled disables/enables the button
+SWFUpload.prototype.setButtonDisabled = function (isDisabled) {
+       this.settings.button_disabled = isDisabled;
+       this.callFlash("SetButtonDisabled", [isDisabled]);
+};
+// Public: setButtonAction sets the action that occurs when the button is 
clicked
+SWFUpload.prototype.setButtonAction = function (buttonAction) {
+       this.settings.button_action = buttonAction;
+       this.callFlash("SetButtonAction", [buttonAction]);
+};
+
+// Public: setButtonCursor changes the mouse cursor displayed when hovering 
over the button
+SWFUpload.prototype.setButtonCursor = function (cursor) {
+       this.settings.button_cursor = cursor;
+       this.callFlash("SetButtonCursor", [cursor]);
+};
+
+/* *******************************
+       Flash Event Interfaces
+       These functions are used by Flash to trigger the various
+       events.
+       
+       All these functions a Private.
+       
+       Because the ExternalInterface library is buggy the event calls
+       are added to a queue and the queue then executed by a setTimeout.
+       This ensures that events are executed in a determinate order and that
+       the ExternalInterface bugs are avoided.
+******************************* */
+
+SWFUpload.prototype.queueEvent = function (handlerName, argumentArray) {
+       // Warning: Don't call this.debug inside here or you'll create an 
infinite loop
+       var self = this;
+       
+       if (argumentArray == undefined) {
+               argumentArray = [];
+       } else if (!(argumentArray instanceof Array)) {
+               argumentArray = [argumentArray];
+       }
+       
+       if (typeof this.settings[handlerName] === "function") {
+               // Queue the event
+               this.eventQueue.push(function () {
+                       this.settings[handlerName].apply(this, argumentArray);
+               });
+               
+               // Execute the next queued event
+               setTimeout(function () {
+                       self.executeNextEvent();
+               }, 0);
+               
+       } else if (this.settings[handlerName] !== null) {
+               throw "Event handler " + handlerName + " is unknown or is not a 
function";
+       }
+};
+
+// Private: Causes the next event in the queue to be executed.  Since events 
are queued using a setTimeout
+// we must queue them in order to garentee that they are executed in order.
+SWFUpload.prototype.executeNextEvent = function () {
+       // Warning: Don't call this.debug inside here or you'll create an 
infinite loop
+
+       var  f = this.eventQueue ? this.eventQueue.shift() : null;
+       if (typeof(f) === "function") {
+               f.apply(this);
+       }
+};
+
+// Private: unescapeFileParams is part of a workaround for a flash bug where 
objects passed through ExternalInterface cannot have
+// properties that contain characters that are not valid for JavaScript 
identifiers. To work around this
+// the Flash Component escapes the parameter names and we must unescape again 
before passing them along.
+SWFUpload.prototype.unescapeFilePostParams = function (file) {
+       var reg = /[$]([0-9a-f]{4})/i, unescapedPost = {}, uk, k, match;
+
+       if (file != undefined) {
+               for (k in file.post) {
+                       if (file.post.hasOwnProperty(k)) {
+                               uk = k;
+                               while ((match = reg.exec(uk)) !== null) {
+                                       uk = uk.replace(match[0], 
String.fromCharCode(parseInt("0x" + match[1], 16)));
+                               }
+                               unescapedPost[uk] = file.post[k];
+                       }
+               }
+
+               file.post = unescapedPost;
+       }
+
+       return file;
+};
+
+// Private: This event is called by SWFUpload Init after we've determined what 
the user's Flash Player supports.
+// Use the swfupload_preload_handler event setting to execute custom code when 
SWFUpload has loaded.
+// Return false to prevent SWFUpload from loading and allow your script to do 
something else if your required feature is
+// not supported
+SWFUpload.prototype.swfuploadPreload = function () {
+       var returnValue;
+       if (typeof this.settings.swfupload_preload_handler === "function") {
+               returnValue = 
this.settings.swfupload_preload_handler.call(this);
+       } else if (this.settings.swfupload_preload_handler != undefined) {
+               throw "upload_start_handler must be a function";
+       }
+
+       // Convert undefined to true so if nothing is returned from the 
upload_start_handler it is
+       // interpretted as 'true'.
+       if (returnValue === undefined) {
+               returnValue = true;
+       }
+       
+       return !!returnValue;
+}
+
+// Private: This event is called by Flash when it has finished loading. Don't 
modify this.
+// Use the swfupload_loaded_handler event setting to execute custom code when 
SWFUpload has loaded.
+SWFUpload.prototype.flashReady = function () {
+       // Check that the movie element is loaded correctly with its 
ExternalInterface methods defined
+       var movieElement =      this.cleanUp();
+
+       if (!movieElement) {
+               this.debug("Flash called back ready but the flash movie can't 
be found.");
+               return;
+       }
+
+       this.queueEvent("swfupload_loaded_handler");
+};
+
+// Private: removes Flash added fuctions to the DOM node to prevent memory 
leaks in IE.
+// This function is called by Flash each time the ExternalInterface functions 
are created.
+SWFUpload.prototype.cleanUp = function () {
+       var key, movieElement = this.getMovieElement();
+       
+       // Pro-actively unhook all the Flash functions
+       try {
+               if (movieElement && typeof(movieElement.CallFunction) === 
"unknown") { // We only want to do this in IE
+                       this.debug("Removing Flash functions hooks (this should 
only run in IE and should prevent memory leaks)");
+                       for (key in movieElement) {
+                               try {
+                                       if (typeof(movieElement[key]) === 
"function") {
+                                               movieElement[key] = null;
+                                       }
+                               } catch (ex) {
+                               }
+                       }
+               }
+       } catch (ex1) {
+       
+       }
+
+       // Fix Flashes own cleanup code so if the SWF Movie was removed from 
the page
+       // it doesn't display errors.
+       window["__flash__removeCallback"] = function (instance, name) {
+               try {
+                       if (instance) {
+                               instance[name] = null;
+                       }
+               } catch (flashEx) {
+               
+               }
+       };
+       
+       return movieElement;
+};
+
+/* When the button_action is set to None this event gets fired and executes 
the mouse_click_handler */
+SWFUpload.prototype.mouseClick = function () {
+       this.queueEvent("mouse_click_handler");
+};
+SWFUpload.prototype.mouseOver = function () {
+       this.queueEvent("mouse_over_handler");
+};
+SWFUpload.prototype.mouseOut = function () {
+       this.queueEvent("mouse_out_handler");
+};
+
+/* This is a chance to do something before the browse window opens */
+SWFUpload.prototype.fileDialogStart = function () {
+       this.queueEvent("file_dialog_start_handler");
+};
+
+
+/* Called when a file is successfully added to the queue. */
+SWFUpload.prototype.fileQueued = function (file) {
+       file = this.unescapeFilePostParams(file);
+       this.queueEvent("file_queued_handler", file);
+};
+
+
+/* Handle errors that occur when an attempt to queue a file fails. */
+SWFUpload.prototype.fileQueueError = function (file, errorCode, message) {
+       file = this.unescapeFilePostParams(file);
+       this.queueEvent("file_queue_error_handler", [file, errorCode, message]);
+};
+
+/* Called after the file dialog has closed and the selected files have been 
queued.
+       You could call startUpload here if you want the queued files to begin 
uploading immediately. */
+SWFUpload.prototype.fileDialogComplete = function (numFilesSelected, 
numFilesQueued, numFilesInQueue) {
+       this.queueEvent("file_dialog_complete_handler", [numFilesSelected, 
numFilesQueued, numFilesInQueue]);
+};
+
+SWFUpload.prototype.uploadResizeStart = function (file, resizeSettings) {
+       file = this.unescapeFilePostParams(file);
+       this.queueEvent("upload_resize_start_handler", [file, 
resizeSettings.width, resizeSettings.height, resizeSettings.encoding, 
resizeSettings.quality]);
+};
+
+SWFUpload.prototype.uploadStart = function (file) {
+       file = this.unescapeFilePostParams(file);
+       this.queueEvent("return_upload_start_handler", file);
+};
+
+SWFUpload.prototype.returnUploadStart = function (file) {
+       var returnValue;
+       if (typeof this.settings.upload_start_handler === "function") {
+               file = this.unescapeFilePostParams(file);
+               returnValue = this.settings.upload_start_handler.call(this, 
file);
+       } else if (this.settings.upload_start_handler != undefined) {
+               throw "upload_start_handler must be a function";
+       }
+
+       // Convert undefined to true so if nothing is returned from the 
upload_start_handler it is
+       // interpretted as 'true'.
+       if (returnValue === undefined) {
+               returnValue = true;
+       }
+       
+       returnValue = !!returnValue;
+       
+       this.callFlash("ReturnUploadStart", [returnValue]);
+};
+
+
+
+SWFUpload.prototype.uploadProgress = function (file, bytesComplete, 
bytesTotal) {
+       file = this.unescapeFilePostParams(file);
+       this.queueEvent("upload_progress_handler", [file, bytesComplete, 
bytesTotal]);
+};
+
+SWFUpload.prototype.uploadError = function (file, errorCode, message) {
+       file = this.unescapeFilePostParams(file);
+       this.queueEvent("upload_error_handler", [file, errorCode, message]);
+};
+
+SWFUpload.prototype.uploadSuccess = function (file, serverData, 
responseReceived) {
+       file = this.unescapeFilePostParams(file);
+       this.queueEvent("upload_success_handler", [file, serverData, 
responseReceived]);
+};
+
+SWFUpload.prototype.uploadComplete = function (file) {
+       file = this.unescapeFilePostParams(file);
+       this.queueEvent("upload_complete_handler", file);
+};
+
+/* Called by SWFUpload JavaScript and Flash functions when debug is enabled. 
By default it writes messages to the
+   internal debug console.  You can override this event and have messages 
written where you want. */
+SWFUpload.prototype.debug = function (message) {
+       this.queueEvent("debug_handler", message);
+};
+
+
+/* **********************************
+       Debug Console
+       The debug console is a self contained, in page location
+       for debug message to be sent.  The Debug Console adds
+       itself to the body if necessary.
+
+       The console is automatically scrolled as messages appear.
+       
+       If you are using your own debug handler or when you deploy to 
production and
+       have debug disabled you can remove these functions to reduce the file 
size
+       and complexity.
+********************************** */
+   
+// Private: debugMessage is the default debug_handler.  If you want to print 
debug messages
+// call the debug() function.  When overriding the function your own function 
should
+// check to see if the debug setting is true before outputting debug 
information.
+SWFUpload.prototype.debugMessage = function (message) {
+       var exceptionMessage, exceptionValues, key;
+
+       if (this.settings.debug) {
+               exceptionValues = [];
+
+               // Check for an exception object and print it nicely
+               if (typeof message === "object" && typeof message.name === 
"string" && typeof message.message === "string") {
+                       for (key in message) {
+                               if (message.hasOwnProperty(key)) {
+                                       exceptionValues.push(key + ": " + 
message[key]);
+                               }
+                       }
+                       exceptionMessage = exceptionValues.join("\n") || "";
+                       exceptionValues = exceptionMessage.split("\n");
+                       exceptionMessage = "EXCEPTION: " + 
exceptionValues.join("\nEXCEPTION: ");
+                       SWFUpload.Console.writeLine(exceptionMessage);
+               } else {
+                       SWFUpload.Console.writeLine(message);
+               }
+       }
+};
+
+SWFUpload.Console = {};
+SWFUpload.Console.writeLine = function (message) {
+       var console, documentForm;
+
+       try {
+               console = document.getElementById("SWFUpload_Console");
+
+               if (!console) {
+                       documentForm = document.createElement("form");
+                       
document.getElementsByTagName("body")[0].appendChild(documentForm);
+
+                       console = document.createElement("textarea");
+                       console.id = "SWFUpload_Console";
+                       console.style.fontFamily = "monospace";
+                       console.setAttribute("wrap", "off");
+                       console.wrap = "off";
+                       console.style.overflow = "auto";
+                       console.style.width = "700px";
+                       console.style.height = "350px";
+                       console.style.margin = "5px";
+                       documentForm.appendChild(console);
+               }
+
+               console.value += message + "\n";
+
+               console.scrollTop = console.scrollHeight - console.clientHeight;
+       } catch (ex) {
+               alert("Exception: " + ex.name + " Message: " + ex.message);
+       }
+};
+
+
+/*     SWFObject v2.2 <http://code.google.com/p/swfobject/> 
+       is released under the MIT License 
<http://www.opensource.org/licenses/mit-license.php> 
+*/
+swfobject = function(){var D="undefined",r="object",S="Shockwave 
Flash",W="ShockwaveFlash.ShockwaveFlash",q="application/x-shockwave-flash",R="SWFObjectExprInst",x="onreadystatechange",O=window,j=document,t=navigator,T=false,U=[h],o=[],N=[],I=[],l,Q,E,B,J=false,a=false,n,G,m=true,M=function(){var
 aa=typeof j.getElementById!=D&&typeof j.getElementsByTagName!=D&&typeof 
j.createElement!=D,ah=t.userAgent.toLowerCase(),Y=t.platform.toLowerCase(),ae=Y?/win/.test(Y):/win/.test(ah),ac=Y?/mac/.test(Y):/mac/.test(ah),af=/webkit/.test(ah)?parseFloat(ah.replace(/^.*webkit\/(\d+(\.\d+)?).*$/,"$1")):false,X=!+"\v1",ag=[0,0,0],ab=null;if(typeof
 t.plugins!=D&&typeof 
t.plugins[S]==r){ab=t.plugins[S].description;if(ab&&!(typeof 
t.mimeTypes!=D&&t.mimeTypes[q]&&!t.mimeTypes[q].enabledPlugin)){T=true;X=false;ab=ab.replace(/^.*\s+(\S+\s+\S+$)/,"$1");ag[0]=parseInt(ab.replace(/^(.*)\..*$/,"$1"),10);ag[1]=parseInt(ab.replace(/^.*\.(.*)\s.*$/,"$1"),10);ag[2]=/[a-zA-Z]/.test(ab)?parseInt(ab.replace(/^.*[a-zA-Z]+(.*)$/,"$1"),10):0}}else{if(typeof
 O.ActiveXObject!=D){try{var ad=new 
ActiveXObject(W);if(ad){ab=ad.GetVariable("$version");if(ab){X=true;ab=ab.split("
 
")[1].split(",");ag=[parseInt(ab[0],10),parseInt(ab[1],10),parseInt(ab[2],10)]}}}catch(Z){}}}return{w3:aa,pv:ag,wk:af,ie:X,win:ae,mac:ac}}(),k=function(){if(!M.w3){return}if((typeof
 j.readyState!=D&&j.readyState=="complete")||(typeof 
j.readyState==D&&(j.getElementsByTagName("body")[0]||j.body))){f()}if(!J){if(typeof
 
j.addEventListener!=D){j.addEventListener("DOMContentLoaded",f,false)}if(M.ie&&M.win){j.attachEvent(x,function(){if(j.readyState=="complete"){j.detachEvent(x,arguments.callee);f()}});if(O==top){(function(){if(J){return}try{j.documentElement.doScroll("left")}catch(X){setTimeout(arguments.callee,0);return}f()})()}}if(M.wk){(function(){if(J){return}if(!/loaded|complete/.test(j.readyState)){setTimeout(arguments.callee,0);return}f()})()}s(f)}}();function
 f(){if(J){return}try{var 
Z=j.getElementsByTagName("body")[0].appendChild(C("span"));Z.parentNode.removeChild(Z)}catch(aa){return}J=true;var
 X=U.length;for(var Y=0;Y<X;Y++){U[Y]()}}function 
K(X){if(J){X()}else{U[U.length]=X}}function s(Y){if(typeof 
O.addEventListener!=D){O.addEventListener("load",Y,false)}else{if(typeof 
j.addEventListener!=D){j.addEventListener("load",Y,false)}else{if(typeof 
O.attachEvent!=D){i(O,"onload",Y)}else{if(typeof O.onload=="function"){var 
X=O.onload;O.onload=function(){X();Y()}}else{O.onload=Y}}}}}function 
h(){if(T){V()}else{H()}}function V(){var 
X=j.getElementsByTagName("body")[0];var aa=C(r);aa.setAttribute("type",q);var 
Z=X.appendChild(aa);if(Z){var Y=0;(function(){if(typeof Z.GetVariable!=D){var 
ab=Z.GetVariable("$version");if(ab){ab=ab.split(" 
")[1].split(",");M.pv=[parseInt(ab[0],10),parseInt(ab[1],10),parseInt(ab[2],10)]}}else{if(Y<10){Y++;setTimeout(arguments.callee,10);return}}X.removeChild(aa);Z=null;H()})()}else{H()}}function
 H(){var ag=o.length;if(ag>0){for(var af=0;af<ag;af++){var Y=o[af].id;var 
ab=o[af].callbackFn;var aa={success:false,id:Y};if(M.pv[0]>0){var 
ae=c(Y);if(ae){if(F(o[af].swfVersion)&&!(M.wk&&M.wk<312)){w(Y,true);if(ab){aa.success=true;aa.ref=z(Y);ab(aa)}}else{if(o[af].expressInstall&&A()){var
 
ai={};ai.data=o[af].expressInstall;ai.width=ae.getAttribute("width")||"0";ai.height=ae.getAttribute("height")||"0";if(ae.getAttribute("class")){ai.styleclass=ae.getAttribute("class")}if(ae.getAttribute("align")){ai.align=ae.getAttribute("align")}var
 ah={};var X=ae.getElementsByTagName("param");var ac=X.length;for(var 
ad=0;ad<ac;ad++){if(X[ad].getAttribute("name").toLowerCase()!="movie"){ah[X[ad].getAttribute("name")]=X[ad].getAttribute("value")}}P(ai,ah,Y,ab)}else{p(ae);if(ab){ab(aa)}}}}}else{w(Y,true);if(ab){var
 Z=z(Y);if(Z&&typeof 
Z.SetVariable!=D){aa.success=true;aa.ref=Z}ab(aa)}}}}}function z(aa){var 
X=null;var Y=c(aa);if(Y&&Y.nodeName=="OBJECT"){if(typeof 
Y.SetVariable!=D){X=Y}else{var 
Z=Y.getElementsByTagName(r)[0];if(Z){X=Z}}}return X}function A(){return 
!a&&F("6.0.65")&&(M.win||M.mac)&&!(M.wk&&M.wk<312)}function 
P(aa,ab,X,Z){a=true;E=Z||null;B={success:false,id:X};var 
ae=c(X);if(ae){if(ae.nodeName=="OBJECT"){l=g(ae);Q=null}else{l=ae;Q=X}aa.id=R;if(typeof
 
aa.width==D||(!/%$/.test(aa.width)&&parseInt(aa.width,10)<310)){aa.width="310"}if(typeof
 
aa.height==D||(!/%$/.test(aa.height)&&parseInt(aa.height,10)<137)){aa.height="137"}j.title=j.title.slice(0,47)+"
 - Flash Player Installation";var 
ad=M.ie&&M.win?"ActiveX":"PlugIn",ac="MMredirectURL="+O.location.toString().replace(/&/g,"%26")+"&MMplayerType="+ad+"&MMdoctitle="+j.title;if(typeof
 
ab.flashvars!=D){ab.flashvars+="&"+ac}else{ab.flashvars=ac}if(M.ie&&M.win&&ae.readyState!=4){var
 
Y=C("div");X+="SWFObjectNew";Y.setAttribute("id",X);ae.parentNode.insertBefore(Y,ae);ae.style.display="none";(function(){if(ae.readyState==4){ae.parentNode.removeChild(ae)}else{setTimeout(arguments.callee,10)}})()}u(aa,ab,X)}}function
 p(Y){if(M.ie&&M.win&&Y.readyState!=4){var 
X=C("div");Y.parentNode.insertBefore(X,Y);X.parentNode.replaceChild(g(Y),X);Y.style.display="none";(function(){if(Y.readyState==4){Y.parentNode.removeChild(Y)}else{setTimeout(arguments.callee,10)}})()}else{Y.parentNode.replaceChild(g(Y),Y)}}function
 g(ab){var aa=C("div");if(M.win&&M.ie){aa.innerHTML=ab.innerHTML}else{var 
Y=ab.getElementsByTagName(r)[0];if(Y){var ad=Y.childNodes;if(ad){var 
X=ad.length;for(var 
Z=0;Z<X;Z++){if(!(ad[Z].nodeType==1&&ad[Z].nodeName=="PARAM")&&!(ad[Z].nodeType==8)){aa.appendChild(ad[Z].cloneNode(true))}}}}}return
 aa}function u(ai,ag,Y){var X,aa=c(Y);if(M.wk&&M.wk<312){return 
X}if(aa){if(typeof ai.id==D){ai.id=Y}if(M.ie&&M.win){var ah="";for(var ae in 
ai){if(ai[ae]!=Object.prototype[ae]){if(ae.toLowerCase()=="data"){ag.movie=ai[ae]}else{if(ae.toLowerCase()=="styleclass"){ah+='
 class="'+ai[ae]+'"'}else{if(ae.toLowerCase()!="classid"){ah+=" 
"+ae+'="'+ai[ae]+'"'}}}}}var af="";for(var ad in 
ag){if(ag[ad]!=Object.prototype[ad]){af+='<param name="'+ad+'" 
value="'+ag[ad]+'" />'}}aa.outerHTML='<object 
classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"'+ah+">"+af+"</object>";N[N.length]=ai.id;X=c(ai.id)}else{var
 Z=C(r);Z.setAttribute("type",q);for(var ac in 
ai){if(ai[ac]!=Object.prototype[ac]){if(ac.toLowerCase()=="styleclass"){Z.setAttribute("class",ai[ac])}else{if(ac.toLowerCase()!="classid"){Z.setAttribute(ac,ai[ac])}}}}for(var
 ab in 
ag){if(ag[ab]!=Object.prototype[ab]&&ab.toLowerCase()!="movie"){e(Z,ab,ag[ab])}}aa.parentNode.replaceChild(Z,aa);X=Z}}return
 X}function e(Z,X,Y){var 
aa=C("param");aa.setAttribute("name",X);aa.setAttribute("value",Y);Z.appendChild(aa)}function
 y(Y){var 
X=c(Y);if(X&&X.nodeName=="OBJECT"){if(M.ie&&M.win){X.style.display="none";(function(){if(X.readyState==4){b(Y)}else{setTimeout(arguments.callee,10)}})()}else{X.parentNode.removeChild(X)}}}function
 b(Z){var Y=c(Z);if(Y){for(var X in Y){if(typeof 
Y[X]=="function"){Y[X]=null}}Y.parentNode.removeChild(Y)}}function c(Z){var 
X=null;try{X=j.getElementById(Z)}catch(Y){}return X}function C(X){return 
j.createElement(X)}function 
i(Z,X,Y){Z.attachEvent(X,Y);I[I.length]=[Z,X,Y]}function F(Z){var 
Y=M.pv,X=Z.split(".");X[0]=parseInt(X[0],10);X[1]=parseInt(X[1],10)||0;X[2]=parseInt(X[2],10)||0;return(Y[0]>X[0]||(Y[0]==X[0]&&Y[1]>X[1])||(Y[0]==X[0]&&Y[1]==X[1]&&Y[2]>=X[2]))?true:false}function
 v(ac,Y,ad,ab){if(M.ie&&M.mac){return}var 
aa=j.getElementsByTagName("head")[0];if(!aa){return}var X=(ad&&typeof 
ad=="string")?ad:"screen";if(ab){n=null;G=null}if(!n||G!=X){var 
Z=C("style");Z.setAttribute("type","text/css");Z.setAttribute("media",X);n=aa.appendChild(Z);if(M.ie&&M.win&&typeof
 
j.styleSheets!=D&&j.styleSheets.length>0){n=j.styleSheets[j.styleSheets.length-1]}G=X}if(M.ie&&M.win){if(n&&typeof
 n.addRule==r){n.addRule(ac,Y)}}else{if(n&&typeof 
j.createTextNode!=D){n.appendChild(j.createTextNode(ac+" {"+Y+"}"))}}}function 
w(Z,X){if(!m){return}var 
Y=X?"visible":"hidden";if(J&&c(Z)){c(Z).style.visibility=Y}else{v("#"+Z,"visibility:"+Y)}}function
 L(Y){var Z=/[\\\"<>\.;]/;var X=Z.exec(Y)!=null;return X&&typeof 
encodeURIComponent!=D?encodeURIComponent(Y):Y}var 
d=function(){if(M.ie&&M.win){window.attachEvent("onunload",function(){var 
ac=I.length;for(var 
ab=0;ab<ac;ab++){I[ab][0].detachEvent(I[ab][1],I[ab][2])}var Z=N.length;for(var 
aa=0;aa<Z;aa++){y(N[aa])}for(var Y in M){M[Y]=null}M=null;for(var X in 
swfobject){swfobject[X]=null}swfobject=null})}}();return{registerObject:function(ab,X,aa,Z){if(M.w3&&ab&&X){var
 
Y={};Y.id=ab;Y.swfVersion=X;Y.expressInstall=aa;Y.callbackFn=Z;o[o.length]=Y;w(ab,false)}else{if(Z){Z({success:false,id:ab})}}},getObjectById:function(X){if(M.w3){return
 z(X)}},embedSWF:function(ab,ah,ae,ag,Y,aa,Z,ad,af,ac){var 
X={success:false,id:ah};if(M.w3&&!(M.wk&&M.wk<312)&&ab&&ah&&ae&&ag&&Y){w(ah,false);K(function(){ae+="";ag+="";var
 aj={};if(af&&typeof af===r){for(var al in 
af){aj[al]=af[al]}}aj.data=ab;aj.width=ae;aj.height=ag;var am={};if(ad&&typeof 
ad===r){for(var ak in ad){am[ak]=ad[ak]}}if(Z&&typeof Z===r){for(var ai in 
Z){if(typeof 
am.flashvars!=D){am.flashvars+="&"+ai+"="+Z[ai]}else{am.flashvars=ai+"="+Z[ai]}}}if(F(Y)){var
 
an=u(aj,am,ah);if(aj.id==ah){w(ah,true)}X.success=true;X.ref=an}else{if(aa&&A()){aj.data=aa;P(aj,am,ah,ac);return}else{w(ah,true)}}if(ac){ac(X)}})}else{if(ac){ac(X)}}},switchOffAutoHideShow:function(){m=false},ua:M,getFlashPlayerVersion:function(){return{major:M.pv[0],minor:M.pv[1],release:M.pv[2]}},hasFlashPlayerVersion:F,createSWF:function(Z,Y,X){if(M.w3){return
 u(Z,Y,X)}else{return 
undefined}},showExpressInstall:function(Z,aa,X,Y){if(M.w3&&A()){P(Z,aa,X,Y)}},removeSWF:function(X){if(M.w3){y(X)}},createCSS:function(aa,Z,Y,X){if(M.w3){v(aa,Z,Y,X)}},addDomLoadEvent:K,addLoadEvent:s,getQueryParamValue:function(aa){var
 
Z=j.location.search||j.location.hash;if(Z){if(/\?/.test(Z)){Z=Z.split("?")[1]}if(aa==null){return
 L(Z)}var Y=Z.split("&");for(var 
X=0;X<Y.length;X++){if(Y[X].substring(0,Y[X].indexOf("="))==aa){return 
L(Y[X].substring((Y[X].indexOf("=")+1)))}}}return""},expressInstallCallback:function(){if(a){var
 
X=c(R);if(X&&l){X.parentNode.replaceChild(l,X);if(Q){w(Q,true);if(M.ie&&M.win){l.style.display="block"}}if(E){E(B)}}a=false}}}}();
+swfobject.addDomLoadEvent(function () {
+       if (typeof(SWFUpload.onload) === "function") {
+               SWFUpload.onload.call(window);
+       }
+});

Added: trunk/phpgwapi/js/swfupload/swfupload.proxy.js
===================================================================
--- trunk/phpgwapi/js/swfupload/swfupload.proxy.js                              
(rev 0)
+++ trunk/phpgwapi/js/swfupload/swfupload.proxy.js      2010-12-02 10:07:28 UTC 
(rev 6627)
@@ -0,0 +1,96 @@
+/*
+       Proxy Plug-in
+       
+       Features:
+               Times an upload to see if it appear suspiciously fast which 
might indicate a proxy server or anti-virus suite intercepting the upload. 
+               If the upload seems too fast an uploadError event is fired with 
PROXY error code after the final uploadProgress event.
+               
+               Adds a SWFUpload setting allowing you to tweak the bytes/s for 
triggering the error:
+                       proxy_detect_threshold : 256000
+                       
+               Adds an UPLOAD_ERROR entry called PROXY:
+                       function uploadError(file, errorCode, message) {
+                               if (errorCode === SWFUpload.UPLOAD_ERROR.PROXY) 
{
+                                       alert("You might have a proxy!");
+                               }
+                       }
+       */
+
+var SWFUpload;
+if (typeof(SWFUpload) === "function") {
+       SWFUpload.proxyDetect = {};
+       SWFUpload.UPLOAD_ERROR.PROXY = -30300;
+       
+       SWFUpload.prototype.initSettings = (function (oldInitSettings) {
+               return function (userSettings) {
+                       if (typeof(oldInitSettings) === "function") {
+                               oldInitSettings.call(this, userSettings);
+                       }
+                       
+                       this.ensureDefault = function (settingName, 
defaultValue) {
+                               this.settings[settingName] = 
(userSettings[settingName] == undefined) ? defaultValue : 
userSettings[settingName];
+                       };
+
+                       // List used to keep the speed stats for the files we 
are tracking
+                       this.proxyDetectFileStartTimes = {};
+                       this.proxyDetectSettings = {};
+
+                       this.ensureDefault("proxy_detect_threshold", 256000); 
// Default is 250 KB per second
+                       
+                       this.proxyDetectSettings.user_upload_progress_handler = 
this.settings.upload_progress_handler;
+                       this.proxyDetectSettings.user_upload_complete_handler = 
this.settings.upload_complete_handler;
+                       
+                       this.settings.upload_progress_handler = 
SWFUpload.proxyDetect.uploadProgressHandler;
+                       this.settings.upload_complete_handler = 
SWFUpload.proxyDetect.uploadCompleteHandler;
+                       
+                       
+                       delete this.ensureDefault;
+               };
+       }(SWFUpload.prototype.initSettings));
+
+       SWFUpload.proxyDetect.uploadProgressHandler = function (file, 
bytesComplete, bytesTotal) {
+               var ex1 = null, time, differenceMS, bps;
+               try {
+                       if (typeof 
this.proxyDetectSettings.user_upload_progress_handler === "function") {
+                               
this.proxyDetectSettings.user_upload_progress_handler.call(this, file, 
bytesComplete, bytesTotal);
+                       }
+               } catch (ex1) { }
+                       
+               
+               if (bytesComplete === 0) {
+                       this.proxyDetectFileStartTimes[file.ID] = new Date();
+
+               } else if (bytesComplete === bytesTotal) {
+                       try {
+                               // Calculate the Bps and decide if we should 
trigger the error
+                               time = new Date();
+                               differenceMS = time.getTime() - 
this.proxyDetectFileStartTimes[file.ID].getTime();
+                               
+                               if (differenceMS === 0) {
+                                       differenceMS = 1;
+                               }
+                               
+                               bps = bytesTotal / (differenceMS * 1000);
+                               if (bps > 
parseInt(this.settings.proxy_detect_threshold, 10)) {
+                                       this.queueEvent("upload_error_handler", 
[file, SWFUpload.UPLOAD_ERROR.PROXY, bps]);
+                               }                                       
+                       } catch (ex) {
+                       }
+               }
+               
+               if (ex1 !== null) {
+                       throw(ex1);
+               }
+       };
+       
+       SWFUpload.proxyDetect.uploadCompleteHandler = function (file) {
+               try {
+                       delete this.proxyDetectFileStartTimes[file.ID];
+               } catch (ex) {
+               }
+               
+               if (typeof 
this.proxyDetectSettings.user_upload_progress_handler === "function") {
+                       return 
this.proxyDetectSettings.user_upload_progress_handler.call(this, file);
+               }
+       };      
+}
\ No newline at end of file

Added: trunk/phpgwapi/js/swfupload/swfupload.queue.js
===================================================================
--- trunk/phpgwapi/js/swfupload/swfupload.queue.js                              
(rev 0)
+++ trunk/phpgwapi/js/swfupload/swfupload.queue.js      2010-12-02 10:07:28 UTC 
(rev 6627)
@@ -0,0 +1,98 @@
+/*
+       Queue Plug-in
+       
+       Features:
+               *Adds a cancelQueue() method for cancelling the entire queue.
+               *All queued files are uploaded when startUpload() is called.
+               *If false is returned from uploadComplete then the queue upload 
is stopped.
+                If false is not returned (strict comparison) then the queue 
upload is continued.
+               *Adds a QueueComplete event that is fired when all the queued 
files have finished uploading.
+                Set the event handler with the queue_complete_handler setting.
+               
+       */
+
+var SWFUpload;
+if (typeof(SWFUpload) === "function") {
+       SWFUpload.queue = {};
+       
+       SWFUpload.prototype.initSettings = (function (oldInitSettings) {
+               return function (userSettings) {
+                       if (typeof(oldInitSettings) === "function") {
+                               oldInitSettings.call(this, userSettings);
+                       }
+                       
+                       this.queueSettings = {};
+                       
+                       this.queueSettings.queue_cancelled_flag = false;
+                       this.queueSettings.queue_upload_count = 0;
+                       
+                       this.queueSettings.user_upload_complete_handler = 
this.settings.upload_complete_handler;
+                       this.queueSettings.user_upload_start_handler = 
this.settings.upload_start_handler;
+                       this.settings.upload_complete_handler = 
SWFUpload.queue.uploadCompleteHandler;
+                       this.settings.upload_start_handler = 
SWFUpload.queue.uploadStartHandler;
+                       
+                       this.settings.queue_complete_handler = 
userSettings.queue_complete_handler || null;
+               };
+       })(SWFUpload.prototype.initSettings);
+
+       SWFUpload.prototype.startUpload = function (fileID) {
+               this.queueSettings.queue_cancelled_flag = false;
+               this.callFlash("StartUpload", [fileID]);
+       };
+
+       SWFUpload.prototype.cancelQueue = function () {
+               this.queueSettings.queue_cancelled_flag = true;
+               this.stopUpload();
+               
+               var stats = this.getStats();
+               while (stats.files_queued > 0) {
+                       this.cancelUpload();
+                       stats = this.getStats();
+               }
+       };
+       
+       SWFUpload.queue.uploadStartHandler = function (file) {
+               var returnValue;
+               if (typeof(this.queueSettings.user_upload_start_handler) === 
"function") {
+                       returnValue = 
this.queueSettings.user_upload_start_handler.call(this, file);
+               }
+               
+               // To prevent upload a real "FALSE" value must be returned, 
otherwise default to a real "TRUE" value.
+               returnValue = (returnValue === false) ? false : true;
+               
+               this.queueSettings.queue_cancelled_flag = !returnValue;
+
+               return returnValue;
+       };
+       
+       SWFUpload.queue.uploadCompleteHandler = function (file) {
+               var user_upload_complete_handler = 
this.queueSettings.user_upload_complete_handler;
+               var continueUpload;
+               
+               if (file.filestatus === SWFUpload.FILE_STATUS.COMPLETE) {
+                       this.queueSettings.queue_upload_count++;
+               }
+
+               if (typeof(user_upload_complete_handler) === "function") {
+                       continueUpload = 
(user_upload_complete_handler.call(this, file) === false) ? false : true;
+               } else if (file.filestatus === SWFUpload.FILE_STATUS.QUEUED) {
+                       // If the file was stopped and re-queued don't restart 
the upload
+                       continueUpload = false;
+               } else {
+                       continueUpload = true;
+               }
+               
+               if (continueUpload) {
+                       var stats = this.getStats();
+                       if (stats.files_queued > 0 && 
this.queueSettings.queue_cancelled_flag === false) {
+                               this.startUpload();
+                       } else if (this.queueSettings.queue_cancelled_flag === 
false) {
+                               this.queueEvent("queue_complete_handler", 
[this.queueSettings.queue_upload_count]);
+                               this.queueSettings.queue_upload_count = 0;
+                       } else {
+                               this.queueSettings.queue_cancelled_flag = false;
+                               this.queueSettings.queue_upload_count = 0;
+                       }
+               }
+       };
+}
\ No newline at end of file

Added: trunk/phpgwapi/js/swfupload/swfupload.speed.js
===================================================================
--- trunk/phpgwapi/js/swfupload/swfupload.speed.js                              
(rev 0)
+++ trunk/phpgwapi/js/swfupload/swfupload.speed.js      2010-12-02 10:07:28 UTC 
(rev 6627)
@@ -0,0 +1,346 @@
+/*
+       Speed Plug-in
+       
+       Features:
+               *Adds several properties to the 'file' object indicated upload 
speed, time left, upload time, etc.
+                       - currentSpeed -- String indicating the upload speed, 
bits per second
+                       - averageSpeed -- Overall average upload speed, bits 
per second
+                       - movingAverageSpeed -- Speed over averaged over the 
last several measurements, bits per second
+                       - timeRemaining -- Estimated remaining upload time in 
seconds
+                       - timeElapsed -- Number of seconds passed for this 
upload
+                       - percentUploaded -- Percentage of the file uploaded (0 
to 100)
+                       - sizeUploaded -- Formatted size uploaded so far, bytes
+               
+               *Adds setting 'moving_average_history_size' for defining the 
window size used to calculate the moving average speed.
+               
+               *Adds several Formatting functions for formatting that values 
provided on the file object.
+                       - SWFUpload.speed.formatBPS(bps) -- outputs string 
formatted in the best units (Gbps, Mbps, Kbps, bps)
+                       - SWFUpload.speed.formatTime(seconds) -- outputs string 
formatted in the best units (x Hr y M z S)
+                       - SWFUpload.speed.formatSize(bytes) -- outputs string 
formatted in the best units (w GB x MB y KB z B )
+                       - SWFUpload.speed.formatPercent(percent) -- outputs 
string formatted with a percent sign (x.xx %)
+                       - SWFUpload.speed.formatUnits(baseNumber, 
divisionArray, unitLabelArray, fractionalBoolean)
+                               - Formats a number using the division array to 
determine how to apply the labels in the Label Array
+                               - factionalBoolean indicates whether the number 
should be returned as a single fractional number with a unit (speed)
+                                   or as several numbers labeled with units 
(time)
+       */
+
+var SWFUpload;
+if (typeof(SWFUpload) === "function") {
+       SWFUpload.speed = {};
+       
+       SWFUpload.prototype.initSettings = (function (oldInitSettings) {
+               return function (userSettings) {
+                       if (typeof(oldInitSettings) === "function") {
+                               oldInitSettings.call(this, userSettings);
+                       }
+                       
+                       this.ensureDefault = function (settingName, 
defaultValue) {
+                               this.settings[settingName] = 
(userSettings[settingName] == undefined) ? defaultValue : 
userSettings[settingName];
+                       };
+
+                       // List used to keep the speed stats for the files we 
are tracking
+                       this.fileSpeedStats = {};
+                       this.speedSettings = {};
+
+                       this.ensureDefault("moving_average_history_size", "10");
+                       
+                       this.speedSettings.user_file_queued_handler = 
this.settings.file_queued_handler;
+                       this.speedSettings.user_file_queue_error_handler = 
this.settings.file_queue_error_handler;
+                       this.speedSettings.user_upload_start_handler = 
this.settings.upload_start_handler;
+                       this.speedSettings.user_upload_error_handler = 
this.settings.upload_error_handler;
+                       this.speedSettings.user_upload_progress_handler = 
this.settings.upload_progress_handler;
+                       this.speedSettings.user_upload_success_handler = 
this.settings.upload_success_handler;
+                       this.speedSettings.user_upload_complete_handler = 
this.settings.upload_complete_handler;
+                       
+                       this.settings.file_queued_handler = 
SWFUpload.speed.fileQueuedHandler;
+                       this.settings.file_queue_error_handler = 
SWFUpload.speed.fileQueueErrorHandler;
+                       this.settings.upload_start_handler = 
SWFUpload.speed.uploadStartHandler;
+                       this.settings.upload_error_handler = 
SWFUpload.speed.uploadErrorHandler;
+                       this.settings.upload_progress_handler = 
SWFUpload.speed.uploadProgressHandler;
+                       this.settings.upload_success_handler = 
SWFUpload.speed.uploadSuccessHandler;
+                       this.settings.upload_complete_handler = 
SWFUpload.speed.uploadCompleteHandler;
+                       
+                       delete this.ensureDefault;
+               };
+       })(SWFUpload.prototype.initSettings);
+
+       
+       SWFUpload.speed.fileQueuedHandler = function (file) {
+               if (typeof this.speedSettings.user_file_queued_handler === 
"function") {
+                       file = SWFUpload.speed.extendFile(file);
+                       
+                       return 
this.speedSettings.user_file_queued_handler.call(this, file);
+               }
+       };
+       
+       SWFUpload.speed.fileQueueErrorHandler = function (file, errorCode, 
message) {
+               if (typeof this.speedSettings.user_file_queue_error_handler === 
"function") {
+                       file = SWFUpload.speed.extendFile(file);
+                       
+                       return 
this.speedSettings.user_file_queue_error_handler.call(this, file, errorCode, 
message);
+               }
+       };
+
+       SWFUpload.speed.uploadStartHandler = function (file) {
+               if (typeof this.speedSettings.user_upload_start_handler === 
"function") {
+                       file = SWFUpload.speed.extendFile(file, 
this.fileSpeedStats);
+                       return 
this.speedSettings.user_upload_start_handler.call(this, file);
+               }
+       };
+       
+       SWFUpload.speed.uploadErrorHandler = function (file, errorCode, 
message) {
+               file = SWFUpload.speed.extendFile(file, this.fileSpeedStats);
+               SWFUpload.speed.removeTracking(file, this.fileSpeedStats);
+
+               if (typeof this.speedSettings.user_upload_error_handler === 
"function") {
+                       return 
this.speedSettings.user_upload_error_handler.call(this, file, errorCode, 
message);
+               }
+       };
+       SWFUpload.speed.uploadProgressHandler = function (file, bytesComplete, 
bytesTotal) {
+               this.updateTracking(file, bytesComplete);
+               file = SWFUpload.speed.extendFile(file, this.fileSpeedStats);
+
+               if (typeof this.speedSettings.user_upload_progress_handler === 
"function") {
+                       return 
this.speedSettings.user_upload_progress_handler.call(this, file, bytesComplete, 
bytesTotal);
+               }
+       };
+       
+       SWFUpload.speed.uploadSuccessHandler = function (file, serverData) {
+               if (typeof this.speedSettings.user_upload_success_handler === 
"function") {
+                       file = SWFUpload.speed.extendFile(file, 
this.fileSpeedStats);
+                       return 
this.speedSettings.user_upload_success_handler.call(this, file, serverData);
+               }
+       };
+       SWFUpload.speed.uploadCompleteHandler = function (file) {
+               file = SWFUpload.speed.extendFile(file, this.fileSpeedStats);
+               SWFUpload.speed.removeTracking(file, this.fileSpeedStats);
+
+               if (typeof this.speedSettings.user_upload_complete_handler === 
"function") {
+                       return 
this.speedSettings.user_upload_complete_handler.call(this, file);
+               }
+       };
+       
+       // Private: extends the file object with the speed plugin values
+       SWFUpload.speed.extendFile = function (file, trackingList) {
+               var tracking;
+               
+               if (!file) {
+                       return file;
+               }
+               
+               if (trackingList) {
+                       tracking = trackingList[file.id];
+               }
+               
+               if (tracking) {
+                       file.currentSpeed = tracking.currentSpeed;
+                       file.averageSpeed = tracking.averageSpeed;
+                       file.movingAverageSpeed = tracking.movingAverageSpeed;
+                       file.timeRemaining = tracking.timeRemaining;
+                       file.timeElapsed = tracking.timeElapsed;
+                       file.percentUploaded = tracking.percentUploaded;
+                       file.sizeUploaded = tracking.bytesUploaded;
+
+               } else {
+                       file.currentSpeed = 0;
+                       file.averageSpeed = 0;
+                       file.movingAverageSpeed = 0;
+                       file.timeRemaining = 0;
+                       file.timeElapsed = 0;
+                       file.percentUploaded = 0;
+                       file.sizeUploaded = 0;
+               }
+               
+               return file;
+       };
+       
+       // Private: Updates the speed tracking object, or creates it if 
necessary
+       SWFUpload.prototype.updateTracking = function (file, bytesUploaded) {
+               var tracking = this.fileSpeedStats[file.id];
+               if (!tracking) {
+                       this.fileSpeedStats[file.id] = tracking = {};
+               }
+               
+               // Sanity check inputs
+               bytesUploaded = bytesUploaded || tracking.bytesUploaded || 0;
+               if (bytesUploaded < 0) {
+                       bytesUploaded = 0;
+               }
+               if (bytesUploaded > file.size) {
+                       bytesUploaded = file.size;
+               }
+               
+               var tickTime = (new Date()).getTime();
+               if (!tracking.startTime) {
+                       tracking.startTime = (new Date()).getTime();
+                       tracking.lastTime = tracking.startTime;
+                       tracking.currentSpeed = 0;
+                       tracking.averageSpeed = 0;
+                       tracking.movingAverageSpeed = 0;
+                       tracking.movingAverageHistory = [];
+                       tracking.timeRemaining = 0;
+                       tracking.timeElapsed = 0;
+                       tracking.percentUploaded = bytesUploaded / file.size;
+                       tracking.bytesUploaded = bytesUploaded;
+               } else if (tracking.startTime > tickTime) {
+                       this.debug("When backwards in time");
+               } else {
+                       // Get time and deltas
+                       var now = (new Date()).getTime();
+                       var lastTime = tracking.lastTime;
+                       var deltaTime = now - lastTime;
+                       var deltaBytes = bytesUploaded - tracking.bytesUploaded;
+                       
+                       if (deltaBytes === 0 || deltaTime === 0) {
+                               return tracking;
+                       }
+                       
+                       // Update tracking object
+                       tracking.lastTime = now;
+                       tracking.bytesUploaded = bytesUploaded;
+                       
+                       // Calculate speeds
+                       tracking.currentSpeed = (deltaBytes * 8 ) / (deltaTime 
/ 1000);
+                       tracking.averageSpeed = (tracking.bytesUploaded * 8) / 
((now - tracking.startTime) / 1000);
+
+                       // Calculate moving average
+                       
tracking.movingAverageHistory.push(tracking.currentSpeed);
+                       if (tracking.movingAverageHistory.length > 
this.settings.moving_average_history_size) {
+                               tracking.movingAverageHistory.shift();
+                       }
+                       
+                       tracking.movingAverageSpeed = 
SWFUpload.speed.calculateMovingAverage(tracking.movingAverageHistory);
+                       
+                       // Update times
+                       tracking.timeRemaining = (file.size - 
tracking.bytesUploaded) * 8 / tracking.movingAverageSpeed;
+                       tracking.timeElapsed = (now - tracking.startTime) / 
1000;
+                       
+                       // Update percent
+                       tracking.percentUploaded = (tracking.bytesUploaded / 
file.size * 100);
+               }
+               
+               return tracking;
+       };
+       SWFUpload.speed.removeTracking = function (file, trackingList) {
+               try {
+                       trackingList[file.id] = null;
+                       delete trackingList[file.id];
+               } catch (ex) {
+               }
+       };
+       
+       SWFUpload.speed.formatUnits = function (baseNumber, unitDivisors, 
unitLabels, singleFractional) {
+               var i, unit, unitDivisor, unitLabel;
+
+               if (baseNumber === 0) {
+                       return "0 " + unitLabels[unitLabels.length - 1];
+               }
+               
+               if (singleFractional) {
+                       unit = baseNumber;
+                       unitLabel = unitLabels.length >= unitDivisors.length ? 
unitLabels[unitDivisors.length - 1] : "";
+                       for (i = 0; i < unitDivisors.length; i++) {
+                               if (baseNumber >= unitDivisors[i]) {
+                                       unit = (baseNumber / 
unitDivisors[i]).toFixed(2);
+                                       unitLabel = unitLabels.length >= i ? " 
" + unitLabels[i] : "";
+                                       break;
+                               }
+                       }
+                       
+                       return unit + unitLabel;
+               } else {
+                       var formattedStrings = [];
+                       var remainder = baseNumber;
+                       
+                       for (i = 0; i < unitDivisors.length; i++) {
+                               unitDivisor = unitDivisors[i];
+                               unitLabel = unitLabels.length > i ? " " + 
unitLabels[i] : "";
+                               
+                               unit = remainder / unitDivisor;
+                               if (i < unitDivisors.length -1) {
+                                       unit = Math.floor(unit);
+                               } else {
+                                       unit = unit.toFixed(2);
+                               }
+                               if (unit > 0) {
+                                       remainder = remainder % unitDivisor;
+                                       
+                                       formattedStrings.push(unit + unitLabel);
+                               }
+                       }
+                       
+                       return formattedStrings.join(" ");
+               }
+       };
+       
+       SWFUpload.speed.formatBPS = function (baseNumber) {
+               var bpsUnits = [1073741824, 1048576, 1024, 1], bpsUnitLabels = 
["Gbps", "Mbps", "Kbps", "bps"];
+               return SWFUpload.speed.formatUnits(baseNumber, bpsUnits, 
bpsUnitLabels, true);
+       
+       };
+       SWFUpload.speed.formatTime = function (baseNumber) {
+               var timeUnits = [86400, 3600, 60, 1], timeUnitLabels = ["d", 
"h", "m", "s"];
+               return SWFUpload.speed.formatUnits(baseNumber, timeUnits, 
timeUnitLabels, false);
+       
+       };
+       SWFUpload.speed.formatBytes = function (baseNumber) {
+               var sizeUnits = [1073741824, 1048576, 1024, 1], sizeUnitLabels 
= ["GB", "MB", "KB", "bytes"];
+               return SWFUpload.speed.formatUnits(baseNumber, sizeUnits, 
sizeUnitLabels, true);
+       
+       };
+       SWFUpload.speed.formatPercent = function (baseNumber) {
+               return baseNumber.toFixed(2) + " %";
+       };
+       
+       SWFUpload.speed.calculateMovingAverage = function (history) {
+               var vals = [], size, sum = 0.0, mean = 0.0, varianceTemp = 0.0, 
variance = 0.0, standardDev = 0.0;
+               var i;
+               var mSum = 0, mCount = 0;
+               
+               size = history.length;
+               
+               // Check for sufficient data
+               if (size >= 8) {
+                       // Clone the array and Calculate sum of the values 
+                       for (i = 0; i < size; i++) {
+                               vals[i] = history[i];
+                               sum += vals[i];
+                       }
+
+                       mean = sum / size;
+
+                       // Calculate variance for the set
+                       for (i = 0; i < size; i++) {
+                               varianceTemp += Math.pow((vals[i] - mean), 2);
+                       }
+
+                       variance = varianceTemp / size;
+                       standardDev = Math.sqrt(variance);
+                       
+                       //Standardize the Data
+                       for (i = 0; i < size; i++) {
+                               vals[i] = (vals[i] - mean) / standardDev;
+                       }
+
+                       // Calculate the average excluding outliers
+                       var deviationRange = 2.0;
+                       for (i = 0; i < size; i++) {
+                               
+                               if (vals[i] <= deviationRange && vals[i] >= 
-deviationRange) {
+                                       mCount++;
+                                       mSum += history[i];
+                               }
+                       }
+                       
+               } else {
+                       // Calculate the average (not enough data points to 
remove outliers)
+                       mCount = size;
+                       for (i = 0; i < size; i++) {
+                               mSum += history[i];
+                       }
+               }
+
+               return mSum / mCount;
+       };
+       
+}
\ No newline at end of file

Added: trunk/phpgwapi/js/swfupload/swfupload.swf
===================================================================
(Binary files differ)


Property changes on: trunk/phpgwapi/js/swfupload/swfupload.swf
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/phpgwapi/js/swfupload/swfupload_fp9.swf
===================================================================
(Binary files differ)


Property changes on: trunk/phpgwapi/js/swfupload/swfupload_fp9.swf
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Modified: trunk/phpgwapi/templates/base/login.tpl
===================================================================
--- trunk/phpgwapi/templates/base/login.tpl     2010-11-22 13:33:58 UTC (rev 
6626)
+++ trunk/phpgwapi/templates/base/login.tpl     2010-12-02 10:07:28 UTC (rev 
6627)
@@ -33,6 +33,7 @@
                }
        -->
        </script>
+       {hide_lightbox}
 </head>
 
 <body>
@@ -88,6 +89,7 @@
                                                                        <label 
for="modlgn_username">{lang_username}</label>
                                                                        <input 
type="text" value="{last_loginid}" name="login" id="modlgn_username" 
{login_read_only} class="inputbox" size="15" >
                                                                        <input 
type="hidden" name="skip_remote" value="{skip_remote}">
+                                                                       <input 
type="hidden" name="lightbox" value="{lightbox}">
                                                                </p>
                                                                <!-- END 
loging_block -->
                                                                <!-- BEGIN 
domain_from_host -->

Modified: trunk/phpgwapi/templates/portico/footer.tpl
===================================================================
--- trunk/phpgwapi/templates/portico/footer.tpl 2010-11-22 13:33:58 UTC (rev 
6626)
+++ trunk/phpgwapi/templates/portico/footer.tpl 2010-12-02 10:07:28 UTC (rev 
6627)
@@ -19,6 +19,11 @@
                                                </div>
                                        </div>
                                </div>
+                               <div id="lightbox-login" 
style="background-color:#000000;color:#FFFFFF;display:none">
+                                       <div class="hd" 
style="background-color:#000000;color:#000000; border:0; text-align:center"> 
{lang_login} </div>
+                                       <div class="bd" 
style="text-align:center;"> </div>
+                               </div>
+
                        </div>
                </div>
        </body>

Modified: trunk/phpgwapi/templates/portico/js/base.js
===================================================================
--- trunk/phpgwapi/templates/portico/js/base.js 2010-11-22 13:33:58 UTC (rev 
6626)
+++ trunk/phpgwapi/templates/portico/js/base.js 2010-12-02 10:07:28 UTC (rev 
6627)
@@ -244,3 +244,39 @@
 
 YAHOO.util.Event.onDOMReady( YAHOO.PORTICO.NavBar );
 YAHOO.util.Event.onDOMReady( YAHOO.PORTICO.BorderLayout );
+
+       this.lightboxlogin = function()
+       {
+               var oArgs = {lightbox:1};
+               var strURL = phpGWLink('login.php', oArgs);
+
+               var onDialogShow = function(e, args, o)
+               {
+                       var frame = document.createElement('iframe');
+                       frame.src = strURL;
+                       frame.width = "100%";
+                       frame.height = "400";
+                       o.setBody(frame);
+               };
+               lightbox_login.showEvent.subscribe(onDialogShow, 
lightbox_login);
+               lightbox_login.show();
+       }
+
+
+YAHOO.util.Event.addListener(window, "load", function()
+{
+               lightbox_login = new YAHOO.widget.Dialog("lightbox-login",
+               {
+                       width : "600px",
+                       fixedcenter : true,
+                       visible : false,
+                       modal : false
+                       //draggable: true,
+                       //constraintoviewport : true
+               });
+
+               lightbox_login.render();
+
+               YAHOO.util.Dom.setStyle('lightbox-login', 'display', 'block');
+});
+

Modified: trunk/phpgwapi/templates/portico/navbar.inc.php
===================================================================
--- trunk/phpgwapi/templates/portico/navbar.inc.php     2010-11-22 13:33:58 UTC 
(rev 6626)
+++ trunk/phpgwapi/templates/portico/navbar.inc.php     2010-12-02 10:07:28 UTC 
(rev 6627)
@@ -209,9 +209,14 @@
 
 HTML;
                }
+               $target = '';
+               if(isset($item['target']))
+               {
+                       $target = "target = '{$item['target']}'";
+               }
                return <<<HTML
 $out
-                                       <a 
href="{$item['url']}"{$link_class}{$icon_style} id="{$id}">
+                                       <a 
href="{$item['url']}"{$link_class}{$icon_style} id="{$id}" {$target}>
                                                <span>{$item['text']}</span>
                                        </a>
 {$children}
@@ -264,7 +269,8 @@
                
                $var = array
                (
-                       'powered_by'    => $powered_by
+                       'powered_by'    => $powered_by,
+                       'lang_login'    => lang('login')
                );
 
                $GLOBALS['phpgw']->template->set_var($var);

Modified: trunk/property/inc/class.bocommon.inc.php
===================================================================
--- trunk/property/inc/class.bocommon.inc.php   2010-11-22 13:33:58 UTC (rev 
6626)
+++ trunk/property/inc/class.bocommon.inc.php   2010-12-02 10:07:28 UTC (rev 
6627)
@@ -47,7 +47,7 @@
 
                var $public_functions = array
                (
-                       'select_part_of_town'   => true,
+                       'confirm_session'       => true,
                );
 
                var $soap_functions = array(
@@ -168,6 +168,15 @@
                        return $moneyformat;
                }
 
+               function confirm_session()
+               {
+                       if($GLOBALS['phpgw']->session->verify())
+                       {
+                               header('Content-Type: application/json');
+                               echo 
json_encode(array('sessionExpired'=>false));
+                               $GLOBALS['phpgw']->common->phpgw_exit();
+                       }
+               }
 
                function date_to_timestamp($date=array())
                {

Modified: trunk/property/inc/class.fileuploader.inc.php
===================================================================
--- trunk/property/inc/class.fileuploader.inc.php       2010-11-22 13:33:58 UTC 
(rev 6626)
+++ trunk/property/inc/class.fileuploader.inc.php       2010-12-02 10:07:28 UTC 
(rev 6627)
@@ -24,7 +24,7 @@
        * @internal Development of this application was funded by 
http://www.bergen.kommune.no/bbb_/ekstern/
        * @package property
        * @subpackage location
-       * @version $Id: class.uilocation.inc.php 5083 2010-03-19 14:29:26Z 
sigurd $
+       * @version $Id: class.fileuploader.inc.php 5083 2010-03-19 14:29:26Z 
sigurd $
        */
 
        /**
@@ -43,7 +43,7 @@
 
                function __construct()
                {
-                       $GLOBALS['phpgw_info']['flags']['xslt_app']             
        = true;
+                       $GLOBALS['phpgw_info']['flags']['xslt_app']             
        = false;
                        $GLOBALS['phpgw_info']['flags']['noframework']          
= true;
                        $GLOBALS['phpgw_info']['flags']['no_reset_fonts']       
= true;
                }
@@ -53,206 +53,341 @@
                        $upload_target  = phpgw::get_var('upload_target');
                        $id                             = phpgw::get_var('id');
 
-                       $link_data = array
-                       (
-                               'menuaction'                    => 
$upload_target,
-                               'id'                                    => $id,
-                               'last_loginid'                  => 
phpgw::get_var('last_loginid'),
-                               'last_domain'                   => 
phpgw::get_var('last_domain'),
-                               'sessionphpgwsessid'    => 
phpgw::get_var('sessionphpgwsessid'),
-                               'domain'                                => 
phpgw::get_var('domain')
-                       );
+                       $oArgs = "{menuaction:'$upload_target',"
+                               ."id:'$id',"
+                               ."last_loginid:'". 
phpgw::get_var('last_loginid')."',"
+                               ."last_domain:'" . 
phpgw::get_var('last_domain')."',"
+                               ."sessionphpgwsessid:'" . 
phpgw::get_var('sessionphpgwsessid')."',"
+                               ."domain:'" . phpgw::get_var('domain')."'";
                                
                        foreach ($_GET as $varname => $value)
                        {
                                if(strpos($varname, '_')===0)
                                {
-                                       
$link_data[substr($varname,1,strlen($varname)-1)] =  $value;
+                                       $oArgs .= ',' . 
substr($varname,1,strlen($varname)-1) . ":'{$value}'";
                                }
                        }
+                       $oArgs .= '}';
 
-                       $upload_url     = $GLOBALS['phpgw']->link('/index.php', 
$link_data);
+                       $js_code = self::get_js($oArgs);
 
-                       $js_code = self::get_js($upload_url);
-               
-                       
$GLOBALS['phpgw']->css->add_external_file('phpgwapi/js/yahoo/datatable/assets/skins/sam/datatable.css');
-                       
$GLOBALS['phpgw']->css->add_external_file('phpgwapi/js/yahoo/fonts/fonts-min.css');
-                       phpgwapi_yui::load_widget('uploader');
-
-                       
$GLOBALS['phpgw']->xslttpl->add_file(array('fileuploader'));
-                       $data = array
-                       (
-                               'js_code' => $js_code,
-                       );
-                       $GLOBALS['phpgw']->xslttpl->set_var('phpgw', 
array('fileuploader' => $data));
+                       $title = lang('fileuploader');
+                       $html = <<<HTML
+                       <!DOCTYPE html>
+                       <html>
+                               <head>
+                                       <title>{$title}</title>
+                                       <link 
href="{$GLOBALS['phpgw_info']['server']['webserver_url']}/phpgwapi/js/swfupload/default.css"
 rel="stylesheet" type="text/css" />
+                                       <script type="text/javascript" 
src="{$GLOBALS['phpgw_info']['server']['webserver_url']}/phpgwapi/js/core/base.js"></script>
+                                       <script type="text/javascript" 
src="{$GLOBALS['phpgw_info']['server']['webserver_url']}/phpgwapi/js/swfupload/swfupload.js"></script>
+                                       <script type="text/javascript" 
src="{$GLOBALS['phpgw_info']['server']['webserver_url']}/phpgwapi/js/swfupload/swfupload.queue.js"></script>
+                                       <script type="text/javascript" 
src="{$GLOBALS['phpgw_info']['server']['webserver_url']}/phpgwapi/js/swfupload/fileprogress.js"></script>
+                                       <script type="text/javascript" 
src="{$GLOBALS['phpgw_info']['server']['webserver_url']}/phpgwapi/js/swfupload/handlers.js"></script>
+                                       $js_code
+                               </head>
+                               <body>
+
+                               <div id="content">
+                                       <h2>{$title}</h2>
+                                       <form id="form1" action="index.php" 
method="post" enctype="multipart/form-data">
+
+                                                       <div class="fieldset 
flash" id="fsUploadProgress">
+                                                       <span 
class="legend">Upload Queue</span>
+                                                       </div>
+                                               <div id="divStatus">0 Files 
Uploaded</div>
+                                                       <div>
+                                                               <span 
id="spanButtonPlaceHolder"></span>
+                                                               <input 
id="btnCancel" type="button" value="Cancel All Uploads" 
onclick="swfu.cancelQueue();" disabled="disabled" style="margin-left: 2px; 
font-size: 8pt; height: 29px;" />
+                                                       </div>
+                                       </form>
+                               </div>
+                       </body>
+               </html>
+HTML;
+                       echo $html;
                }
 
                
-               static function get_js($upload_url = '')
+               static function get_js($oArgs = '')
                {
+                       $button_text = lang('Select Files');
+                       $str_base_url = 'http';
+                       $str_base_url .= phpgw::get_var('HTTPS', 'bool', 
'SERVER') ? 's' : '' ;
+                       $str_base_url .= '://';
+                       $str_base_url .= phpgw::get_var('HTTP_HOST', 'string', 
'SERVER');
+
+                       $str_base_url .= $GLOBALS['phpgw']->link('/', array(), 
true);
                        $js_code = <<<JS
-                       YAHOO.util.Event.onDOMReady(function () { 
-                       var uiLayer = YAHOO.util.Dom.getRegion('selectLink');
-                       var overlay = YAHOO.util.Dom.get('uploaderOverlay');
-                       YAHOO.util.Dom.setStyle(overlay, 'width', 
uiLayer.right-uiLayer.left + "px");
-                       YAHOO.util.Dom.setStyle(overlay, 'height', 
uiLayer.bottom-uiLayer.top + "px");
-                       });
+<script type="text/javascript">
+               var swfu;
+               var strBaseURL = '$str_base_url';
+
+               var sUrl = phpGWLink('index.php', $oArgs);
+
+               window.onload = function() {
+                       var settings = {
+                               flash_url : 
"{$GLOBALS['phpgw_info']['server']['webserver_url']}/phpgwapi/js/swfupload/swfupload.swf",
+                               flash9_url : 
"{$GLOBALS['phpgw_info']['server']['webserver_url']}/phpgwapi/js/swfupload/swfupload_fp9.swf",
+                               upload_url: sUrl,
+//                             post_params: {"PHPSESSID" : "<?php echo 
session_id(); ?>"},
+                               file_size_limit : "100 MB",
+                               file_types : "*.*",
+                               file_types_description : "All Files",
+                               file_upload_limit : 100,
+                               file_queue_limit : 0,
+                               custom_settings : {
+                                       progressTarget : "fsUploadProgress",
+                                       cancelButtonId : "btnCancel"
+                               },
+                               debug: false,
+
+                               // Button settings
+                               button_image_url: 
"images/TestImageNoText_65x29.png",
+                               button_width: "65",
+                               button_height: "29",
+                               button_placeholder_id: "spanButtonPlaceHolder",
+                               button_text: '<span 
class="theFont">{$button_text}</span>',
+                               button_text_style: ".theFont { font-size: 16; 
}",
+                               button_text_left_padding: 12,
+                               button_text_top_padding: 3,
+                               
+                               // The event handler functions are defined in 
handlers.js
+                               swfupload_preload_handler : preLoad,
+                               swfupload_load_failed_handler : loadFailed,
+                               file_queued_handler : fileQueued,
+                               file_queue_error_handler : fileQueueError,
+                               file_dialog_complete_handler : 
fileDialogComplete,
+                               upload_start_handler : uploadStart,
+                               upload_progress_handler : uploadProgress,
+                               upload_error_handler : uploadError,
+                               upload_success_handler : uploadSuccess,
+                               upload_complete_handler : uploadComplete,
+                               queue_complete_handler : queueComplete  // 
Queue plugin event
+                       };
 
-                       // Custom URL for the uploader swf file (same folder).
+                       swfu = new SWFUpload(settings);
+            };
+       </script>
+JS;
+                       return $js_code;
+               }
 
-                       YAHOO.widget.Uploader.SWFURL = 
"{$GLOBALS['phpgw_info']['server']['webserver_url']}/phpgwapi/js/yahoo/uploader/assets/uploader.swf";
 
-                       // Instantiate the uploader and write it to its 
placeholder div.
-                       var uploader = new YAHOO.widget.Uploader( 
"uploaderOverlay" );
+/*
+This is an upload script for SWFUpload that attempts to properly handle 
uploaded files
+in a secure way.
                        
-                       // Add event listeners to various events on the 
uploader.
-                       // Methods on the uploader should only be called once 
the 
-                       // contentReady event has fired.
+Notes:
        
-                       uploader.addListener('contentReady', 
handleContentReady);
-                       uploader.addListener('fileSelect', onFileSelect)
-                       uploader.addListener('uploadStart', onUploadStart);
-                       uploader.addListener('uploadProgress', 
onUploadProgress);
-                       uploader.addListener('uploadCancel', onUploadCancel);
-                       uploader.addListener('uploadComplete', 
onUploadComplete);
-                       uploader.addListener('uploadCompleteData', 
onUploadResponse);
-                       uploader.addListener('uploadError', onUploadError);
-                       uploader.addListener('rollOver', handleRollOver);
-                       uploader.addListener('rollOut', handleRollOut);
-                       uploader.addListener('click', handleClick);
+       SWFUpload doesn't send a MIME-TYPE. In my opinion this is ok since 
MIME-TYPE is no better than
+        file extension and is probably worse because it can vary from OS to OS 
and browser to browser (for the same file).
+        The best thing to do is content sniff the file but this can be 
resource intensive, is difficult, and can still be fooled or inaccurate.
+        Accepting uploads can never be 100% secure.
        
-                       // Variable for holding the filelist.
-                       var fileList;
+       You can't guarantee that SWFUpload is really the source of the upload.  
A malicious user
+        will probably be uploading from a tool that sends invalid or false 
metadata about the file.
+        The script should properly handle this.
        
-                       // When the mouse rolls over the uploader, this function
-                       // is called in response to the rollOver event.
-                       // It changes the appearance of the UI element below 
the Flash overlay.
-                       function handleRollOver () {
-                               
YAHOO.util.Dom.setStyle(YAHOO.util.Dom.get('selectLink'), 'color', "#FFFFFF");
-                               
YAHOO.util.Dom.setStyle(YAHOO.util.Dom.get('selectLink'), 'background-color', 
"#000000");
-                       }
+       The script should not over-write existing files.
 
-                       // On rollOut event, this function is called, which 
changes the appearance of the
-                       // UI element below the Flash layer back to its 
original state.
-                       function handleRollOut () {
-                               
YAHOO.util.Dom.setStyle(YAHOO.util.Dom.get('selectLink'), 'color', "#0000CC");
-                               
YAHOO.util.Dom.setStyle(YAHOO.util.Dom.get('selectLink'), 'background-color', 
"#FFFFFF");
-                       }
+       The script should strip away invalid characters from the file name or 
reject the file.
 
-                       // When the Flash layer is clicked, the "Browse" dialog 
is invoked.
-                       // The click event handler allows you to do something 
else if you need to.
-                       function handleClick () {
-                       }
+       The script should not allow files to be saved that could then be 
executed on the webserver (such as .php files).
+        To keep things simple we will use an extension whitelist for allowed 
file extensions.  Which files should be allowed
+        depends on your server configuration. The extension white-list is 
_not_ tied your SWFUpload file_types setting
 
-                       // When contentReady event is fired, you can call 
methods on the uploader.
-                       function handleContentReady () {
-                           // Allows the uploader to send log messages to 
trace, as well as to YAHOO.log
-                               uploader.setAllowLogging(true);
+       For better security uploaded files should be stored outside the 
webserver's document root.  Downloaded files
+        should be accessed via a download script that proxies from the file 
system to the webserver.  This prevents
+        users from executing malicious uploaded files.  It also gives the 
developer control over the outgoing mime-type,
+        access restrictions, etc.  This, however, is outside the scope of this 
script.
 
-                               // Allows multiple file selection in "Browse" 
dialog.
-                               uploader.setAllowMultipleFiles(true);
+       SWFUpload sends each file as a separate POST rather than several files 
in a single post. This is a better
+        method in my opinion since it better handles file size limits, e.g., 
if post_max_size is 100 MB and I post two 60 MB files then
+        the post would fail (2x60MB = 120MB). In SWFupload each 60 MB is 
posted as separate post and we stay within the limits. This
+        also simplifies the upload script since we only have to handle a 
single file.
 
-                               // New set of file filters.
-                               var ff = new Array({description:"Images", 
extensions:"*.jpg;*.png;*.gif"},
-                                                  {description:"Videos", 
extensions:"*.avi;*.mov;*.mpg"});
+       The script should properly handle situations where the post was too 
large or the posted file is larger than
+        our defined max.  These values are not tied to your SWFUpload 
file_size_limit setting.
 
-                               // Apply new set of file filters to the 
uploader.
-//                             uploader.setFileFilters(ff);
-                       }
+*/
+
+               function upload($bofiles, $save_path = '')
+               {
+                       $use_vfs = true;
+                       // Check post_max_size 
(http://us3.php.net/manual/en/features.file-upload.php#73762)
+                       $POST_MAX_SIZE = ini_get('post_max_size');
+                       $unit = strtoupper(substr($POST_MAX_SIZE, -1));
+                       $multiplier = ($unit == 'M' ? 1048576 : ($unit == 'K' ? 
1024 : ($unit == 'G' ? 1073741824 : 1)));
 
-                       // Actually uploads the files. In this case,
-                       // uploadAll() is used for automated queueing and 
upload 
-                       // of all files on the list.
-                       // You can manage the queue on your own and use 
"upload" instead,
-                       // if you need to modify the properties of the request 
for each
-                       // individual file.
-                       function upload() {
-                               if (fileList != null) {
-                                       
uploader.setSimUploadLimit(parseInt(document.getElementById("simulUploads").value));
-                                       uploader.uploadAll("{$upload_url}", 
"POST", null, "Filedata");
+                       if ((int)$_SERVER['CONTENT_LENGTH'] > 
$multiplier*(int)$POST_MAX_SIZE && $POST_MAX_SIZE)
+                       {
+                               header("HTTP/1.1 500 Internal Server Error"); 
// This will trigger an uploadError event in SWFUpload
+                               echo "POST exceeded maximum allowed size.";
+                               $GLOBALS['phpgw']->common->phpgw_exit();
                                }       
+
+               // Settings
+
+                       if(!$save_path)
+                       {
+                               $save_path = 
"{$GLOBALS['phpgw_info']['server']['temp_dir']}";
+                               $use_vfs = false;
                        }
+                       $upload_name = "Filedata";
+                       $max_file_size_in_bytes = 2147483647;                   
        // 2GB in bytes
+                       $extension_whitelist = array("jpg", "gif", "png");      
// Allowed file extensions
+                       $valid_chars_regex = '.A-Z0-9_ 
address@hidden&()+={}\[\]\',~`-';                                // Characters 
allowed in the file name (in a Regular Expression format)
+               
+                       // Other variables      
+                       $MAX_FILENAME_LENGTH = 260;
+                       $file_name = "";
+                       $file_extension = "";
+                       $uploadErrors = array
+                       (
+                       0=>"There is no error, the file uploaded successfully",
+                       1=>"The uploaded file exceeds the upload_max_filesize 
directive in php.ini",
+                       2=>"The uploaded file exceeds the MAX_FILE_SIZE 
directive that was specified in the HTML form",
+                       3=>"The uploaded file was only partially uploaded",
+                       4=>"No file was uploaded",
+                       6=>"Missing a temporary folder"
+                       );
 
-                       // Fired when the user selects files in the "Browse" 
dialog
-                       // and clicks "Ok".
-                       function onFileSelect(event) {
-                               if('fileList' in event && event.fileList != 
null) {
-                                       fileList = event.fileList;
-                                       createDataTable(fileList);
+
+               // Validate the upload
+                       if (!isset($_FILES[$upload_name]))
+                       {
+                               $this->HandleError("No upload found in \$_FILES 
for " . $upload_name);
+                               $GLOBALS['phpgw']->common->phpgw_exit();
+                       }
+                       else if (isset($_FILES[$upload_name]["error"]) && 
$_FILES[$upload_name]["error"] != 0)
+                       {
+                               
$this->HandleError($uploadErrors[$_FILES[$upload_name]["error"]]);
+                               $GLOBALS['phpgw']->common->phpgw_exit();
+                       }
+                       else if (!isset($_FILES[$upload_name]["tmp_name"]) || 
address@hidden($_FILES[$upload_name]["tmp_name"]))
+                       {
+                               $this->HandleError("Upload failed 
is_uploaded_file test.");
+                               $GLOBALS['phpgw']->common->phpgw_exit();
+                       }
+                       else if (!isset($_FILES[$upload_name]['name']))
+                       {
+                               $this->HandleError("File has no name.");
+                               $GLOBALS['phpgw']->common->phpgw_exit();
                                }
+       
+               // Validate the file size (Warning: the largest files supported 
by this code is 2GB)
+                       $file_size = 
@filesize($_FILES[$upload_name]["tmp_name"]);
+                       if (!$file_size || $file_size > $max_file_size_in_bytes)
+                       {
+                               $this->HandleError("File exceeds the maximum 
allowed size");
+                               $GLOBALS['phpgw']->common->phpgw_exit();
                        }
 
-                       function createDataTable(entries) {
-                         rowCounter = 0;
-                         this.fileIdHash = {};
-                         this.dataArr = [];
-                         for(var i in entries) {
-                            var entry = entries[i];
-                                entry["progress"] = "<div 
style='height:5px;width:100px;background-color:#CCC;'></div>";
-                            dataArr.unshift(entry);
+                       if ($file_size <= 0)
+                       {
+                               $this->HandleError("File size outside allowed 
lower bound");
+                               $GLOBALS['phpgw']->common->phpgw_exit();
                          }
 
-                         for (var j = 0; j < dataArr.length; j++) {
-                           this.fileIdHash[dataArr[j].id] = j;
+               // Validate file name (for our purposes we'll just remove 
invalid characters)
+                       $file_name = 
preg_replace('/[^'.$valid_chars_regex.']|\.+$/i', "", 
basename($_FILES[$upload_name]['name']));
+                       if (strlen($file_name) == 0 || strlen($file_name) > 
$MAX_FILENAME_LENGTH)
+                       {
+                               $this->HandleError("Invalid file name");
+                               $GLOBALS['phpgw']->common->phpgw_exit();
                          }
 
-                           var myColumnDefs = [
-                               {key:"name", label: "File Name", 
sortable:false},
-                               {key:"size", label: "Size", sortable:false},
-                               {key:"progress", label: "Upload progress", 
sortable:false}
-                           ];
 
-                       this.myDataSource = new YAHOO.util.DataSource(dataArr);
-                       this.myDataSource.responseType = 
YAHOO.util.DataSource.TYPE_JSARRAY;
-                       this.myDataSource.responseSchema = {
-                       fields: ["id","name","created","modified","type", 
"size", "progress"]
-               };
+                       $to_file        = "{$save_path}/{$file_name}";
 
-                       this.singleSelectDataTable = new 
YAHOO.widget.DataTable("dataTableContainer",
-                                  myColumnDefs, this.myDataSource, {
-                                      caption:"Files To Upload",
-                                      selectionMode:"single"
-                                  });
+                       // Validate that we won't over-write an existing file
+                       if ($bofiles->vfs->file_exists(array(
+                                       'string' => $to_file,
+                                       'relatives' => Array(RELATIVE_NONE)
+                               )))
+                       {
+                               $receipt['error'][]=array('msg'=>lang('This 
file already exists !'));
+                               $this->HandleError("File with this name already 
exists");
+                               exit(0);
                        }
 
-                       // Do something on each file's upload start.
-                       function onUploadStart(event) {
+                       $bofiles->create_document_dir($save_path);
                        
+/*
+               // Validate that we won't over-write an existing file
+                       if (file_exists("{$save_path}/{$file_name}"))
+                       {
+                               $this->HandleError("File with this name already 
exists");
+                               exit(0);
                        }
-
-                       // Do something on each file's upload progress event.
-                       function onUploadProgress(event) {
-                               rowNum = fileIdHash[event["id"]];
-                               prog = 
Math.round(100*(event["bytesLoaded"]/event["bytesTotal"]));
-                               progbar = "<div 
style='height:5px;width:100px;background-color:#CCC;'><div 
style='height:5px;background-color:#F00;width:" + prog + "px;'></div></div>";
-                               singleSelectDataTable.updateRow(rowNum, {name: 
dataArr[rowNum]["name"], size: dataArr[rowNum]["size"], progress: progbar});    
 
+*/
+               // Validate file extension
+                       $path_info = pathinfo($_FILES[$upload_name]['name']);
+                       $file_extension = $path_info["extension"];
+                       $is_valid_extension = false;
+                       foreach ($extension_whitelist as $extension)
+                       {
+                               if (strcasecmp($file_extension, $extension) == 
0)
+                               {
+                                       $is_valid_extension = true;
+                                       break;
                        }
-
-                       // Do something when each file's upload is complete.
-                       function onUploadComplete(event) {
-                               rowNum = fileIdHash[event["id"]];
-                               prog = 
Math.round(100*(event["bytesLoaded"]/event["bytesTotal"]));
-                               progbar = "<div 
style='height:5px;width:100px;background-color:#CCC;'><div 
style='height:5px;background-color:#F00;width:100px;'></div></div>";
-                               singleSelectDataTable.updateRow(rowNum, {name: 
dataArr[rowNum]["name"], size: dataArr[rowNum]["size"], progress: progbar});
+                       }
+                       if (!$is_valid_extension)
+                       {
+                               $this->HandleError("Invalid file extension");
+                               $GLOBALS['phpgw']->common->phpgw_exit();
                        }
 
-                       // Do something if a file upload throws an error.
-                       // (When uploadAll() is used, the Uploader will
-                       // attempt to continue uploading.
-                       function onUploadError(event) {
+               // Validate file contents (extension and mime-type can't be 
trusted)
+                       /*
+                               Validating the file contents is OS and web 
server configuration dependant.  Also, it may not be reliable.
+                               See the comments on this page: 
http://us2.php.net/fileinfo
 
-                       }
+                               Also see 
http://72.14.253.104/search?q=cache:3YGZfcnKDrYJ:www.scanit.be/uploads/php-file-upload.pdf+php+file+command&hl=en&ct=clnk&cd=8&gl=us&client=firefox-a
+                                which describes how a PHP script can be 
embedded within a GIF image file.
+               
+                               Therefore, no sample code will be provided 
here.  Research the issue, decide how much security is
+                               needed, and implement a solution that meets the 
need.
+                       */
 
-                       // Do something if an upload is cancelled.
-                       function onUploadCancel(event) {
 
+               // Process the file
+                       /*
+                               At this point we are ready to process the valid 
file. This sample code shows how to save the file. Other tasks
+                                could be done such as creating an entry in a 
database or generating a thumbnail.
+                
+                               Depending on your server OS and needs you may 
need to set the Security Permissions on the file after it has
+                               been saved.
+                       */
+
+                       $bofiles->vfs->override_acl = 1;
+                       if(!$bofiles->vfs->cp (array (
+                               'from'  => $_FILES[$upload_name]["tmp_name"],
+                               'to'    => "{$save_path}/{$file_name}",
+                               'relatives'     => array 
(RELATIVE_NONE|VFS_REAL, RELATIVE_ALL))))
+                       {
+                               $receipt['error'][]=array('msg'=>lang('Failed 
to upload file !'));
+                               $this->HandleError("File could not be saved.");
+                               exit(0);
                        }
 
-                       // Do something when data is received back from the 
server.
-                       function onUploadResponse(event) {
+                       $bofiles->vfs->override_acl = 0;
 
+/*
+                       if (address@hidden($_FILES[$upload_name]["tmp_name"], 
"{$save_path}/{$file_name}"))
+                       {
+                               $this->HandleError("File could not be saved.");
+                               exit(0);
                        }
-JS;
-                       return $js_code;
+*/
+//                     exit(0);
+               }
+
+               /* Handles the error output. This error message will be sent to 
the uploadSuccess event handler.  The event handler
+               will have to check for any error messages and react as needed. 
*/
+               function HandleError($message)
+               {
+                       echo $message;
                }
  }

Modified: trunk/property/inc/class.menu.inc.php

@@ Diff output truncated at 153600 characters. @@



reply via email to

[Prev in Thread] Current Thread [Next in Thread]