Examples TOCexamples

Web-HTTP ProgressBar uploader

$Date: 2005/07/25 11:43:56 $

 Table of contents

Introduction

This example requires :


This example allows you to upload files from a web browser to your web server and logs operations.

PEAR::HTML_QuickForm package is used to make and manage the form that will send file to your web server (top frame), while HTML_Progress is only used to display a horizontal progress meter running in indeterminate mode (bottom frame).

Be aware that your web server could returns a timeout on long upload operation, by running the HTML_Progress script (See technical notes below).

To logs all file uploads, we used the observer pattern with HTML_Progress_Observer class. Results are written in a series of files 'http4_[iso date].log', where iso date corresponding to current date in format YYYY-MM-DD.

[Top]

 Technical notes

The script time-out refers to the number of seconds a PHP page is given before the script is assumed to have failed and the page terminated. If you are uploading a large file the script that is receiving the transfer may time out before the file has been completely uploaded. To alter this setting you should insert the following code into your uploading page prior to creating any HTML_Progress and HTML_QuickForm objects.

1 <?php set_time_limit(300); // five minutes ?>

See also: set_time_limit manual.

[Top]

 Render options

increment = 10 (to make progress bar animation smoothest in indeterminate mode)
HTML_Progress::setIncrement()
speed = 100 (to make progress bar animation smoothest)
HTML_Progress::setAnimSpeed()
color = white
with  = 1px
style = inset
HTML_Progress_UI::setBorderAttributes()
width            = 60
font-size        = 10
background-color = #C3C6C3
HTML_Progress_UI::setStringAttributes()
active-color     = #000084
inactive-color   = #3A6EA5
width            = 25
spacing          = 0
background-image = download.gif
HTML_Progress_UI::setCellAttributes()

[Top]

 Output

Screenshot

[Top]

 PHP source syntax highlight

The form file selection:

  1. <?php
  2. /**
  3.  * Frameset Page Upload
  4.  * A form is used to select and submit any kind of file to webserver (frame 1) while
  5.  * a progress meter is running in indeterminate mode in the bottom of page (frame 2)
  6.  *
  7.  * @version    $Id: formbasic.php,v 1.3 2005/07/25 11:43:56 farell Exp $
  8.  * @author     Laurent Laville <pear@laurent-laville.org>
  9.  * @package    HTML_Progress
  10.  * @subpackage Examples
  11.  */
  12.  
  13. require_once 'HTML/QuickForm.php';
  14.  
  15. function myProcess($values)
  16. {
  17.     global $form;
  18.     $destination = './uploads/';
  19.  
  20.     $file =& $form->getElement('tstUpload');
  21.     if ($file->isUploadedFile()) {
  22.         $ok = $file->moveUploadedFile($destination);
  23.  
  24.         if ($ok) {
  25.             // write the semaphore to tell progress meter to stop
  26.             // in script 'progressbar.php'
  27.  
  28.             $fp = fopen($destination . $_GET['ID'],'w',false);
  29.             fwrite($fp, 'done');
  30.             fclose($fp);
  31.         }
  32.     }
  33. }
  34. ?>
  35. <html>
  36. <head>
  37. <script language="javascript">
  38. <!--
  39. function DoUpload() {
  40.   theUniqueID = (new Date()).getTime() % 1000000000;
  41.   parent.meter.window.location = "hbar.php?ID=" + theUniqueID;
  42.   parent.files.selfref.action = "formbasic.php?ID=" + theUniqueID;
  43.   parent.files.selfref.submit();
  44. }
  45. //-->
  46. </script>
  47. </head>
  48. <body>
  49. <?php
  50.  
  51. $form =& new HTML_QuickForm('selfref');
  52.  
  53. // We need an additional label below the element
  54. $renderer =& $form->defaultRenderer();
  55. $renderer->setElementTemplate(<<<EOT
  56. <tr>
  57.     <td align="right" valign="top" nowrap="nowrap"><!-- BEGIN required --><span style="color: #ff0000">*</span><!-- END required --><b>{label}</b></td>
  58.     <td valign="top" align="left">
  59.         <!-- BEGIN error --><span style="color: #ff0000">{error}</span><br /><!-- END error -->{element}
  60.         <!-- BEGIN label_2 --><br/><span style="font-size: 80%">{label_2}</span><!-- END label_2 -->
  61.     </td>
  62. </tr>
  63.  
  64. EOT
  65. );
  66.  
  67. $form->addElement('header', null, 'Uploaded file rules');
  68. $form->addElement('file', 'tstUpload', array('Upload file:', 'Rule types: \'uploadedfile\''));
  69. $form->addRule('tstUpload', 'Upload is required', 'uploadedfile');
  70.  
  71. $form->addElement('header', null, 'Submit the form');
  72. $submit[] =& $form->createElement('button', null, 'Upload', array('onClick'=>'DoUpload();'));
  73. $form->addGroup($submit, null, null, '&nbsp;', false);
  74.  
  75. $form->applyFilter('__ALL__', 'trim');
  76.  
  77. if ($form->validate()) {
  78.     // Form is validated, then processes the data
  79.     $form->freeze();
  80.     $form->process('myProcess', true);
  81.     echo '<p>&lt;&lt; <a target="_top" href="../index.html">Back examples TOC</a></p>';
  82.  
  83. } elseif (isset($_GET['ID'])) {
  84.     $destination = './uploads/';
  85.     $fp = fopen($destination . $_GET['ID'],'w',false);
  86.     fwrite($fp, 'error');
  87.     fclose($fp);
  88. }
  89. $form->display();
  90. ?>
  91. </body>
  92. </html>

The progress meter in indeterminate mode:

  1. <?php
  2. /**
  3.  * Progress meter is running in indeterminate mode while a file upload operation.
  4.  * This example may work with HTML_Progress 1.1
  5.  * but version 1.2.0 or better allows more easy facilities.
  6.  *
  7.  * @version    $Id: hbar.php,v 1.2 2005/07/25 11:43:56 farell Exp $
  8.  * @author     Laurent Laville <pear@laurent-laville.org>
  9.  * @package    HTML_Progress
  10.  * @subpackage Examples
  11.  */
  12.  
  13. require_once 'HTML/Progress.php';
  14. require_once 'HTML/Progress/observer.php';
  15.  
  16. class logsUpload extends HTML_Progress_Observer
  17. {
  18.     var $_console;
  19.  
  20.     function logsUpload()
  21.     {
  22.         $isodate = date('Y-m-d');
  23.         $this->_console = './uploads/http4_' . $isodate . '.log';
  24.         $this->HTML_Progress_Observer();
  25.     }
  26.  
  27.     function notify($event)
  28.     {
  29.         $semaphore = './uploads/'.$_GET['ID'];
  30.  
  31.         if (file_exists($semaphore) && $event['value'] < 100) {
  32.             $stop = file_get_contents($semaphore);
  33.             $date = date('H:i:s');
  34.             $ip = $_SERVER['REMOTE_ADDR'];
  35.             $msg = "$date - $ip - file upload: $stop";
  36.  
  37.             error_log("$msg \n", 3, $this->_console);
  38.         }
  39.     }
  40. }
  41.  
  42. function _methodExists($name)
  43. {
  44.     if (substr(PHP_VERSION,0,1) < '5') {
  45.         $n = strtolower($name);
  46.     } else {
  47.         $n = $name;
  48.     }
  49.     if (in_array($n, get_class_methods('HTML_Progress'))) {
  50.         return true;
  51.     }
  52.     return false;
  53. }
  54.  
  55. /*
  56.     User callback called pending progress meter is running, comes with version 1.2.0RC3
  57.  */
  58. function myFunctionHandler($progressValue, &$obj)
  59. {
  60.     global $version;
  61.     global $stop;
  62.     $semaphore = './uploads/'.$_GET['ID'];
  63.  
  64.     if (file_exists($semaphore)) {
  65.         $stop = file_get_contents($semaphore);
  66.         $obj->setValue(100);
  67.         $obj->setIndeterminate(false);
  68.         $obj->display();
  69.         unlink($semaphore);
  70.     }
  71.  
  72.     // sleep a bit ...
  73.     if ($version > 1.1) {
  74.         $obj->sleep();
  75.     } else {
  76.         for ($i=0; $i<($obj->_anim_speed*1000); $i++) { }
  77.     }
  78. }
  79.  
  80. /*
  81.     Which version of html_progress: (stable)1.1 or (beta)1.2.0 RC1, RC2 or RC3
  82.  */
  83. $version = _methodExists('run') ? 1.2 : 1.1;
  84.  
  85. $progress = new HTML_Progress();
  86. $observer = new logsUpload();          // prepare the progress meter to logs all upload operations
  87. $progress->addListener($observer);
  88. $progress->setIncrement(10);
  89. $progress->setAnimSpeed(100);
  90. $progress->setIndeterminate(true);     // progress bar run in indeterminate mode
  91. $progress->setStringPainted(true);     // get space for the string
  92. $progress->setBorderPainted(true);
  93. $progress->setString("");              // but don't paint it
  94. if ($version > 1.1) {
  95.     // set a progress handler required at least version 1.2.0RC3
  96.     $progress->setProgressHandler('myFunctionHandler');
  97. }
  98. $ui = & $progress->getUI();
  99. $ui->setBorderAttributes('width=1 style=inset color=white');
  100. $ui->setCellAttributes(array(
  101.     'active-color' => '#000084',
  102.     'inactive-color' => '#3A6EA5',
  103.     'width' => 25,
  104.     'spacing' => 0,
  105.     'background-image' => 'download.gif'
  106. ));
  107. $ui->setStringAttributes(array(
  108.     'width' => 60,
  109.     'font-size' => 10,
  110.     'background-color' => '#C3C6C3'
  111. ));
  112. ?>
  113. <!DOCTYPE html
  114.     PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  115.     "http://www.w3c.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
  116.  
  117. <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
  118. <head>
  119. <style type="text/css">
  120. <!--
  121. body {
  122.     background-color: #C3C6C3;
  123.     color: #000000;
  124.     font-family: Verdana, Arial;
  125. }
  126. <?php echo $progress->getStyle(); ?>
  127. // -->
  128. </style>
  129. <script type="text/javascript">
  130. <!--
  131. <?php echo $progress->getScript(); ?>
  132. //-->
  133. </script>
  134. </head>
  135. <body>
  136.  
  137. <?php
  138. echo $progress->toHtml();
  139.  
  140. if (isset($_GET['ID'])) {
  141.  
  142.     if ($version > 1.1) {
  143.         $progress->run();    // run method is born on version 1.2.0RC3
  144.     } else {
  145.         // do the same as run() method
  146.         do {
  147.             $progress->display();
  148.             myFunctionHandler($progress->getValue(), $progress);
  149.             if ($progress->getPercentComplete() == 1) {
  150.                 if ($progress->isIndeterminate()) {
  151.                     $progress->setValue(0);
  152.                 } else {
  153.                     break;
  154.                 }
  155.             }
  156.             $progress->incValue();
  157.         } while(1);
  158.     }
  159.     if ($stop == 'error') {
  160.         echo '<b>File was not uploaded !</b>';
  161.     } else {
  162.         echo '<b>Upload Complete...</b>';
  163.     }
  164. }
  165. ?>
  166.  
  167. </body>
  168. </html>

[Top]