1<?php
2/**
3 * An example of Listener usage with HTTP_Request. This downloads and saves
4 * the file displaying the progress bar in the process.
5 *
6 * Note two things:
7 * 1) The file should be run in console, not in browser;
8 * 2) You should turn output buffering OFF for this to work properly.
9 *
10 * @category    HTTP
11 * @package     HTTP_Request
12 * @version     CVS: $Id: download-progress.php,v 1.4 2007/10/26 13:45:56 avb Exp $
13 * @ignore
14 */
15
16/**
17 * Class for performing HTTP requests
18 */
19require_once 'HTTP/Request.php';
20require_once 'HTTP/Request/Listener.php';
21require_once 'Console/ProgressBar.php';
22
23PEAR::setErrorHandling(PEAR_ERROR_DIE);
24
25set_time_limit(0);
26
27/**
28 * A Listener for HTTP_Request that draws download progress indicator
29 *
30 * @category    HTTP
31 * @package     HTTP_Request
32 * @ignore
33 */
34class HTTP_Request_DownloadListener extends HTTP_Request_Listener
35{
36   /**
37    * Handle for the target file
38    * @var int
39    */
40    var $_fp;
41
42   /**
43    * Console_ProgressBar instance used to display the indicator
44    * @var object
45    */
46    var $_bar;
47
48   /**
49    * Name of the target file
50    * @var string
51    */
52    var $_target;
53
54   /**
55    * Number of bytes received so far
56    * @var int
57    */
58    var $_size = 0;
59
60    function HTTP_Request_DownloadListener()
61    {
62        $this->HTTP_Request_Listener();
63    }
64
65   /**
66    * Opens the target file
67    * @param string Target file name
68    * @throws PEAR_Error
69    */
70    function setTarget($target)
71    {
72        $this->_target = $target;
73        $this->_fp = @fopen($target, 'wb');
74        if (!$this->_fp) {
75            PEAR::raiseError("Cannot open '{$target}'");
76        }
77    }
78
79    function update(&$subject, $event, $data = null)
80    {
81        switch ($event) {
82            case 'sentRequest':
83                $this->_target = basename($subject->_url->path);
84                break;
85
86            case 'gotHeaders':
87                if (isset($data['content-disposition']) &&
88                    preg_match('/filename="([^"]+)"/', $data['content-disposition'], $matches)) {
89
90                    $this->setTarget(basename($matches[1]));
91                } else {
92                    $this->setTarget($this->_target);
93                }
94                $this->_bar =& new Console_ProgressBar(
95                    '* ' . $this->_target . ' %fraction% KB [%bar%] %percent%', '=>', '-',
96                    79, (isset($data['content-length'])? round($data['content-length'] / 1024): 100)
97                );
98                $this->_size = 0;
99                break;
100
101            case 'tick':
102                $this->_size += strlen($data);
103                $this->_bar->update(round($this->_size / 1024));
104                fwrite($this->_fp, $data);
105                break;
106
107            case 'gotBody':
108                fclose($this->_fp);
109                break;
110
111            case 'connect':
112            case 'disconnect':
113                break;
114
115            default:
116                PEAR::raiseError("Unhandled event '{$event}'");
117        } // switch
118    }
119}
120
121// Try using any other package if you like, but choose the bigger ones
122// to be able to see the progress bar
123$url = 'http://pear.php.net/get/HTML_QuickForm-stable';
124
125$req =& new HTTP_Request($url);
126
127$download =& new HTTP_Request_DownloadListener();
128$req->attach($download);
129$req->sendRequest(false);
130?>
131