c7bd8e090e2e6b90bb8aea8894ef05f35135e60c
[Packages/TYPO3.CMS.git] / typo3 / sysext / fluid / Classes / ViewHelpers / Format / BytesViewHelper.php
1 <?php
2 namespace TYPO3\CMS\Fluid\ViewHelpers\Format;
3
4 /*
5 * This file is part of the TYPO3 CMS project.
6 *
7 * It is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License, either version 2
9 * of the License, or any later version.
10 *
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
13 *
14 * The TYPO3 project - inspiring people to share!
15 */
16
17 use TYPO3\CMS\Core\Utility\GeneralUtility;
18 use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
19 use TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper;
20 use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
21
22 /**
23 * Formats an integer with a byte count into human-readable form.
24 *
25 * = Examples =
26 *
27 * <code title="Defaults">
28 * {fileSize -> f:format.bytes()}
29 * </code>
30 * <output>
31 * 123 KB
32 * // depending on the value of {fileSize}
33 * </output>
34 *
35 * <code title="Defaults">
36 * {fileSize -> f:format.bytes(decimals: 2, decimalSeparator: '.', thousandsSeparator: ',')}
37 * </code>
38 * <output>
39 * 1,023.00 B
40 * // depending on the value of {fileSize}
41 * </output>
42 *
43 * You may provide an own set of units, like this: B,KB,MB,GB,TB,PB,EB,ZB,YB
44 * <code title="custom units">
45 * {fileSize -> f:format.bytes(units: '{f:translate(\'viewhelper.format.bytes.units\', \'fluid\')}'
46 * </code>
47 * <output>
48 * 123 KB
49 * // depending on the value of {fileSize}
50 * </output>
51 *
52 * @api
53 */
54 class BytesViewHelper extends AbstractViewHelper
55 {
56
57 /**
58 * Output is escaped already. We must not escape children, to avoid double encoding.
59 *
60 * @var bool
61 */
62 protected $escapeChildren = false;
63
64 /**
65 * Initialize ViewHelper arguments
66 *
67 * @return void
68 */
69 public function initializeArguments()
70 {
71 parent::initializeArguments();
72 $this->registerArgument('value', 'int',
73 'The incoming data to convert, or NULL if VH children should be used');
74 $this->registerArgument('decimals', 'int', 'The number of digits after the decimal point');
75 $this->registerArgument('decimalSeparator', 'string', 'The decimal point character', false,
76 '.');
77 $this->registerArgument('thousandsSeparator', 'string',
78 'The character for grouping the thousand digits', false, ',');
79 $this->registerArgument('units', 'string',
80 'comma separated list of available units, default is LocalizationUtility::translate(\'viewhelper.format.bytes.units\', \'fluid\')');
81 }
82
83 /**
84 * Render the supplied byte count as a human readable string.
85 *
86 * @return string Formatted byte count
87 * @api
88 */
89 public function render()
90 {
91 return static::renderStatic(
92 $this->arguments,
93 $this->buildRenderChildrenClosure(),
94 $this->renderingContext
95 );
96 }
97
98 /**
99 * Applies htmlspecialchars() on the specified value.
100 *
101 * @param array $arguments
102 * @param \Closure $renderChildrenClosure
103 * @param \TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface $renderingContext
104 *
105 * @return string
106 */
107 public static function renderStatic(
108 array $arguments,
109 \Closure $renderChildrenClosure,
110 RenderingContextInterface $renderingContext
111 ) {
112 if ($arguments['units'] !== null) {
113 $units = $arguments['units'];
114 } else {
115 $units = LocalizationUtility::translate('viewhelper.format.bytes.units', 'fluid');
116 }
117 $units = GeneralUtility::trimExplode(',', $units, true);
118
119 $value = $arguments['value'];
120 if ($value === null) {
121 $value = $renderChildrenClosure();
122 }
123
124 if (is_numeric($value)) {
125 $value = (float)$value;
126 }
127 if (!is_int($value) && !is_float($value)) {
128 $value = 0;
129 }
130 $bytes = max($value, 0);
131 $pow = floor(($bytes ? log($bytes) : 0) / log(1024));
132 $pow = min($pow, count($units) - 1);
133 $bytes /= pow(2, 10 * $pow);
134
135 return sprintf(
136 '%s %s',
137 number_format(round($bytes, 4 * $arguments['decimals']), $arguments['decimals'],
138 $arguments['decimalSeparator'], $arguments['thousandsSeparator']),
139 $units[$pow]
140 );
141 }
142 }