## Apache Zeta Components Manual :: File Source for progressbar.php

## Source for file progressbar.php

Documentation is available at progressbar.php

1. <?php
2. /**
3. * File containing the ezcConsoleProgressbar class.
4. *
5. * Licensed to the Apache Software Foundation (ASF) under one
6. * or more contributor license agreements. See the NOTICE file
7. * distributed with this work for additional information
8. * regarding copyright ownership. The ASF licenses this file
9. * to you under the Apache License, Version 2.0 (the
10. * "License"); you may not use this file except in compliance
11. * with the License. You may obtain a copy of the License at
12. *
13. * http://www.apache.org/licenses/LICENSE-2.0
14. *
15. * Unless required by applicable law or agreed to in writing,
16. * software distributed under the License is distributed on an
17. * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
18. * KIND, either express or implied. See the License for the
19. * specific language governing permissions and limitations
20. * under the License.
21. *
22. * @package ConsoleTools
23. * @version //autogentag//
24. * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
25. * @filesource
26. */
28. /**
29. * Creating and maintaining progress-bars to be printed to the console.
30. *
31. * <code>
32. * $out = new ezcConsoleOutput();
33. *
34. * // Create progress bar itself
35. * $progress = new ezcConsoleProgressbar( $out, 100, array( 'step' => 5 ) );
36. *
37. * $progress->options->emptyChar = '-';
38. * $progress->options->progressChar = '#';
39. * $progress->options->formatString = "Uploading file </tmp/foobar.tar.bz2>: %act%/%max% kb [%bar%]";
40. *
41. * // Perform actions
42. * $i = 0;
43. * while ( $i++ < 20 )
44. * {
45. * // Do whatever you want to indicate progress for
46. * usleep( mt_rand( 20000, 2000000 ) );
47. * // Advance the progressbar by one step ( uploading 5k per run )
48. * $progress->advance();
49. * }
50. *
51. * // Finish progress bar and jump to next line.
52. * $progress->finish();
53. *
54. * $out->outputText( "Successfully uploaded </tmp/foobar.tar.bz2>.\n", 'success' );
55. * </code>
56. *
57. * @property ezcConsoleProgressbarOptions $options
58. * Contains the options for this class.
59. * @property int $max
60. * The maximum progress value to reach.
61. *
62. * @package ConsoleTools
63. * @version //autogen//
64. * @mainclass
65. */
66. class ezcConsoleProgressbar
67. {
68. /**
69. * Container to hold the properties
70. *
71. * @var array(string=>mixed)
72. */
73. protected $properties ;
75. /**
76. * Storage for actual values to be replaced in the format string.
77. * Actual values are stored here and will be inserted into the bar
78. * before printing it.
79. *
80. * @var array(string=>string)
81. */
82. protected $valueMap = array(
83. 'bar' => '',
84. 'fraction' => '',
85. 'act' => '',
86. 'max' => '',
87. );
89. /**
90. * Stores the bar utilization.
91. *
92. * This array saves how much space a specific part of the bar utilizes to not
93. * recalculate those on every step.
94. *
95. * @var array(string=>int)
96. */
97. protected $measures = array(
98. 'barSpace' => 0,
99. 'fractionSpace' => 0,
100. 'actSpace' => 0,
101. 'maxSpace' => 0,
102. 'fixedCharSpace' => 0,
103. );
105. /**
106. * The current step the progress bar should show.
107. *
108. * @var int
109. */
110. protected $currentStep = 0;
112. /**
113. * The maximum number of steps to go.
114. * Calculated once from the settings.
115. *
116. * @var int
117. */
118. protected $numSteps = 0;
120. /**
121. * The ezcConsoleOutput object to use.
122. *
123. * @var ezcConsoleOutput
124. */
125. protected $output ;
127. /**
128. * Indicates if the starting point for the bar has been stored.
129. * Per default this is false to indicate that no start position has been
130. * stored, yet.
131. *
132. * @var bool
133. */
134. protected $started = false;
136. /**
137. * Tool object to perform multi-byte encoding safe string operations.
138. *
139. * @var ezcConsoleStringTool
140. */
141. private $stringTool;
143. /**
144. * Creates a new progress bar.
145. *
146. * @param ezcConsoleOutput $outHandler Handler to utilize for output
147. * @param int $max Maximum value, where progressbar
148. * reaches 100%.
149. * @param array(string=>string) $options Options
150. *
151. * @see ezcConsoleProgressbar::$options
152. */
153. public function __construct ( ezcConsoleOutput $outHandler, $max, array $options = array() )
154. {
155. $this-> output = $outHandler;
156. $this->stringTool = new ezcConsoleStringTool();
157. $this->__set( 'max', $max );
158. $this-> properties ['options'] = new ezcConsoleProgressbarOptions ( $options );
159. }
161. /**
162. * Set new options.
163. * This method allows you to change the options of progressbar.
164. *
165. * @param ezcConsoleProgresbarOptions $options The options to set.
166. *
167. * @throws ezcBaseSettingNotFoundException
168. * If you tried to set a non-existent option value.
169. * @throws ezcBaseSettingValueException
170. * If the value is not valid for the desired option.
171. * @throws ezcBaseValueException
172. * If you submit neither an array nor an instance of
173. * ezcConsoleProgresbarOptions.
174. */
175. public function setOptions ( $options )
176. {
177. if ( is_array ( $options ) )
178. {
179. $this-> properties ['options']->merge( $options );
180. }
181. else if ( $options instanceof ezcConsoleProgressbarOptions )
182. {
183. $this-> properties ['options'] = $options;
184. }
185. else
186. {
187. throw new ezcBaseValueException ( "options", $options, "instance of ezcConsoleProgressbarOptions" );
188. }
189. }
191. /**
192. * Returns the current options.
193. * Returns the options currently set for this progressbar.
194. *
195. * @return ezcConsoleProgressbarOptions The current options.
196. */
197. public function getOptions ()
198. {
199. return $this-> properties ['options'];
200. }
202. /**
203. * Property read access.
204. *
205. * @param string $key Name of the property.
206. * @return mixed Value of the property or null.
207. *
208. * @throws ezcBasePropertyNotFoundException
209. * If the the desired property is not found.
210. * @ignore
211. */
212. public function __get( $key )
213. {
214. switch ( $key )
215. {
216. case 'options':
217. return $this-> properties ['options'];
218. case 'step':
219. // Step is now an option
220. return $this-> properties ['options']->step;
221. case 'max':
222. return $this-> properties [$key];
223. default:
224. break;
225. }
226. throw new ezcBasePropertyNotFoundException ( $key );
227. }
229. /**
230. * Property write access.
231. *
232. * @param string $key Name of the property.
233. * @param mixed $val The value for the property.
234. *
235. * @throws ezcBasePropertyNotFoundException
236. * If a desired property could not be found.
237. * @throws ezcBaseValueException
238. * If a desired property value is out of range.
239. * @ignore
240. */
241. public function __set( $key, $val )
242. {
243. switch ( $key )
244. {
245. case 'options':
246. if ( !( $val instanceof ezcConsoleProgressbarOptions ) )
247. {
248. throw new ezcBaseValueException ( 'options', $val, 'instance of ezcConsoleProgressbarOptions' );
249. };
250. break;
251. case 'max':
252. if ( ( ! is_int ( $val ) && ! is_float ( $val ) ) || $val < 0 )
253. {
254. throw new ezcBaseValueException ( $key, $val, 'number >= 0' );
255. }
256. break;
257. case 'step':
258. if ( ( ! is_int ( $val ) && ! is_float ( $val ) ) || $val < 0 )
259. {
260. throw new ezcBaseValueException ( $key, $val, 'number >= 0' );
261. }
262. // Step is now an option.
263. $this-> properties ['options']->step = $val;
264. return;
265. default:
266. throw new ezcBasePropertyNotFoundException ( $key );
267. break;
268. }
269. // Changes settings or options, need for recalculating measures
270. $this-> started = false;
271. $this-> properties [$key] = $val;
272. }
274. /**
275. * Property isset access.
276. *
277. * @param string $key Name of the property.
278. * @return bool True is the property is set, otherwise false.
279. * @ignore
280. */
281. public function __isset( $key )
282. {
283. switch ( $key )
284. {
285. case 'options':
286. case 'max':
287. case 'step':
288. return true;
289. }
290. return false;
291. }
293. /**
294. * Start the progress bar
295. * Starts the progress bar and sticks it to the current line.
296. * No output will be done yet. Call {@link ezcConsoleProgressbar::output()}
297. * to print the bar.
298. *
299. * @return void
300. */
301. public function start ()
302. {
303. $this-> calculateMeasures ();
304. $this-> output -> storePos ();
305. $this-> started = true;
306. }
308. /**
309. * Draw the progress bar.
310. * Prints the progress-bar to the screen. If start() has not been called
311. * yet, the current line is used for {@link ezcConsolProgressbar::start()}.
312. *
313. * @return void
314. */
315. public function output ()
316. {
317. if ( $this->options->minVerbosity > $this-> output ->options->verbosityLevel
318. || ( $this->options->maxVerbosity !== false
319. && $this->options->maxVerbosity < $this-> output ->options->verbosityLevel
320. )
321. )
322. {
323. // Do not print progress bar if verbosity level is lower than it's
324. // output objects value.
325. return;
326. }
328. if ( $this-> started === false )
329. {
330. $this-> start ();
331. }
333. $this-> output -> restorePos ();
334. if ( ezcBaseFeatures :: os () === "Windows" )
335. {
336. echo str_repeat ( "\x8", $this->options->width );
337. }
339. $this-> generateValues ();
340. echo $this-> insertValues ();
341. }
343. /**
344. * Advance the progress bar.
345. * Advances the progress bar by $step steps. Redraws the bar by default,
346. * using the {@link ezcConsoleProgressbar::output()} method.
347. *
348. * @param bool $redraw Whether to redraw the bar immediately.
349. * @param int $step How many steps to advance.
350. * @return void
351. */
352. public function advance ( $redraw = true, $step = 1 )
353. {
354. $this-> currentStep += $step;
355. if ( $redraw === true && $this-> currentStep % $this-> properties ['options']->redrawFrequency === 0 )
356. {
357. $this-> output ();
358. }
359. }
361. /**
362. * Finish the progress bar.
363. * Finishes the bar (jump to 100% if not happened yet,...) and jumps
364. * to the next line to allow new output. Also resets the values of the
365. * output handler used, if changed.
366. *
367. * @return void
368. */
369. public function finish ()
370. {
371. $this-> currentStep = $this-> numSteps ;
372. $this-> output ();
373. }
375. /**
376. * Generate all values to be replaced in the format string.
377. *
378. * @return void
379. */
380. protected function generateValues ()
381. {
382. // Bar
383. $barFilledSpace = ceil ( $this-> measures ['barSpace'] / $this-> numSteps * $this-> currentStep );
384. // Sanitize value if it gets to large by rounding
385. $barFilledSpace = $barFilledSpace > $this-> measures ['barSpace'] ? $this-> measures ['barSpace'] : $barFilledSpace;
386. $bar = $this->stringTool->strPad(
387. $this->stringTool->strPad(
388. $this-> properties ['options']->progressChar,
389. $barFilledSpace,
390. $this-> properties ['options']->barChar,
391. STR_PAD_LEFT
392. ),
393. $this-> measures ['barSpace'],
394. $this-> properties ['options']->emptyChar,
395. STR_PAD_RIGHT
396. );
397. $this-> valueMap ['bar'] = $bar;
399. // Fraction
400. $fractionVal = sprintf (
401. $this-> properties ['options']->fractionFormat,
402. ( $fractionVal = ( $this-> properties ['options']->step * $this-> currentStep ) / $this->max * 100 ) > 100 ? 100 : $fractionVal
403. );
404. $this-> valueMap ['fraction'] = $this->stringTool->strPad(
405. $fractionVal,
406. iconv_strlen ( sprintf ( $this-> properties ['options']->fractionFormat, 100 ), 'UTF-8' ),
407. ' ',
408. STR_PAD_LEFT
409. );
411. // Act / max
412. $actVal = sprintf (
413. $this-> properties ['options']->actFormat,
414. ( $actVal = $this-> currentStep * $this-> properties ['options']->step ) > $this->max ? $this->max : $actVal
415. );
416. $this-> valueMap ['act'] = $this->stringTool->strPad(
417. $actVal,
418. iconv_strlen ( sprintf ( $this-> properties ['options']->actFormat, $this->max ), 'UTF-8' ),
419. ' ',
420. STR_PAD_LEFT
421. );
422. $this-> valueMap ['max'] = sprintf ( $this-> properties ['options']->maxFormat, $this->max );
423. }
425. /**
426. * Insert values into bar format string.
427. *
428. * @return void
429. */
430. protected function insertValues ()
431. {
432. $bar = $this-> properties ['options']->formatString;
433. foreach ( $this-> valueMap as $name => $val )
434. {
435. $bar = str_replace ( "%{$name}%", $val, $bar );
436. }
437. return $bar;
438. }
440. /**
441. * Calculate several measures necessary to generate a bar.
442. *
443. * @return void
444. */
445. protected function calculateMeasures ()
446. {
447. // Calc number of steps bar goes through
448. $this-> numSteps = ( int ) round ( $this->max / $this-> properties ['options']->step );
449. // Calculate measures
450. $this-> measures ['fixedCharSpace'] = iconv_strlen ( $this-> stripEscapeSequences ( $this-> insertValues () ), 'UTF-8' );
451. if ( iconv_strpos ( $this-> properties ['options']->formatString, '%max%', 0, 'UTF-8' ) !== false )
452. {
453. $this-> measures ['maxSpace'] = iconv_strlen ( sprintf ( $this-> properties ['options']->maxFormat, $this->max ), 'UTF-8' );
455. }
456. if ( iconv_strpos ( $this-> properties ['options']->formatString, '%act%', 0, 'UTF-8' ) !== false )
457. {
458. $this-> measures ['actSpace'] = iconv_strlen ( sprintf ( $this-> properties ['options']->actFormat, $this->max ), 'UTF-8' );
459. }
460. if ( iconv_strpos ( $this-> properties ['options']->formatString, '%fraction%', 0, 'UTF-8' ) !== false )
461. {
462. $this-> measures ['fractionSpace'] = iconv_strlen ( sprintf ( $this-> properties ['options']->fractionFormat, 100 ), 'UTF-8' );
463. }
464. $this-> measures ['barSpace'] = $this-> properties ['options']->width - array_sum ( $this-> measures );
465. }
467. /**
468. * Strip all escape sequences from a string to measure it's size correctly.
469. *
470. * @param mixed $str
471. * @return void
472. */
473. protected function stripEscapeSequences ( $str )
474. {
475. return preg_replace ( '/\033\[[0-9a-f;]*m/i', '', $str );
476. }
477. }
478. ?>

Documentation generated by phpDocumentor 1.4.3