weekly release 3.1dev
[moodle.git] / lib / classes / progress / display.php
1 <?php
2 // This file is part of Moodle - http://moodle.org/
3 //
4 // Moodle is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // Moodle is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
17 namespace core\progress;
19 defined('MOODLE_INTERNAL') || die();
21 /**
22  * Progress handler that uses a standard Moodle progress bar to display
23  * progress. The Moodle progress bar cannot show indeterminate progress,
24  * so we do extra output in addition to the bar.
25  *
26  * @package core_progress
27  * @copyright 2013 The Open University
28  * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
29  */
30 class display extends base {
31     /**
32      * @var int Number of wibble states (state0...stateN-1 classes in CSS)
33      */
34     const WIBBLE_STATES = 13;
36     /**
37      * @var \progress_bar Current progress bar.
38      */
39     private $bar;
41     private $lastwibble, $currentstate = 0, $direction = 1;
43     /**
44      * @var bool True to display names
45      */
46     protected $displaynames = false;
48     /**
49      * Constructs the progress reporter. This will output HTML code for the
50      * progress bar, and an indeterminate wibbler below it.
51      *
52      * @param bool $startnow If true, outputs HTML immediately.
53      */
54     public function __construct($startnow = true) {
55         if ($startnow) {
56             $this->start_html();
57         }
58     }
60     /**
61      * By default, the progress section names do not display because
62      * these will probably be untranslated and incomprehensible. To make them
63      * display, call this method.
64      *
65      * @param bool $displaynames True to display names
66      */
67     public function set_display_names($displaynames = true) {
68         $this->displaynames = $displaynames;
69     }
71     /**
72      * Starts to output progress.
73      *
74      * Called in constructor and in update_progress if required.
75      *
76      * @throws \coding_exception If already started
77      */
78     public function start_html() {
79         if ($this->bar) {
80             throw new \coding_exception('Already started');
81         }
82         $this->bar = new \progress_bar();
83         $this->bar->create();
84         echo \html_writer::start_div('wibbler');
85     }
87     /**
88      * Finishes output. (Progress can begin again later if there are more
89      * calls to update_progress.)
90      *
91      * Automatically called from update_progress when progress finishes.
92      */
93     public function end_html() {
94         // Finish progress bar.
95         $this->bar->update_full(100, '');
96         $this->bar = null;
98         // End wibbler div.
99         echo \html_writer::end_div();
100     }
102     /**
103      * When progress is updated, updates the bar.
104      *
105      * @see \core\progress\base::update_progress()
106      */
107     public function update_progress() {
108         // If finished...
109         if (!$this->is_in_progress_section()) {
110             if ($this->bar) {
111                 $this->end_html();
112             }
113         } else {
114             if (!$this->bar) {
115                 $this->start_html();
116             }
117             // In case of indeterminate or small progress, update the wibbler
118             // (up to once per second).
119             if (time() != $this->lastwibble) {
120                 $this->lastwibble = time();
121                 echo \html_writer::div('', 'wibble state' . $this->currentstate);
123                 // Go on to next colour.
124                 $this->currentstate += $this->direction;
125                 if ($this->currentstate < 0 || $this->currentstate >= self::WIBBLE_STATES) {
126                     $this->direction = -$this->direction;
127                     $this->currentstate += 2 * $this->direction;
128                 }
129                 $buffersize = ini_get('output_buffering');
130                 if ($buffersize) {
131                     // Force the buffer full.
132                     echo str_pad('', $buffersize);
133                 }
134             }
136             // Get progress.
137             list ($min, $max) = $this->get_progress_proportion_range();
139             // Update progress bar.
140             $message = '';
141             if ($this->displaynames) {
142                 $message = $this->get_current_description();
143             }
144             $this->bar->update_full($min * 100, $message);
146             // Flush output.
147             flush();
148         }
149     }