1 <?php
2
3 4 5 6 7 8 9 10
11
12 namespace Brickrouge;
13
14 use ICanBoogie\Uploaded;
15
16 class File extends Element
17 {
18 const FILE_WITH_LIMIT = '#file-with-limit';
19 const T_UPLOAD_URL = '#file-upload-url';
20 const BUTTON_LABEL = '#file-button-label';
21
22 static protected function add_assets(Document $document)
23 {
24 parent::add_assets($document);
25
26 $document->js->add('file.js');
27 $document->css->add('file.css');
28 }
29
30 public function __construct(array $attributes=array())
31 {
32 parent::__construct
33 (
34 'div', $attributes + array
35 (
36 Element::WIDGET_CONSTRUCTOR => 'File',
37
38 self::BUTTON_LABEL => 'Choose a file',
39
40 'class' => 'widget-file'
41 )
42 );
43 }
44
45 protected function infos()
46 {
47 $path = $this['value'];
48 $details = $this->details($path);
49 $preview = $this->preview($path);
50
51 $rc = '';
52
53 if ($preview)
54 {
55 $rc .= '<div class="preview">';
56 $rc .= $preview;
57 $rc .= '</div>';
58 }
59
60 if ($details)
61 {
62 $rc .= '<ul class="details">';
63
64 foreach ($details as $detail)
65 {
66 $rc .= '<li>' . $detail . '</li>';
67 }
68
69 $rc .= '</ul>';
70 }
71
72 return $rc;
73 }
74
75 protected function details($path)
76 {
77 $file = basename($path);
78
79 if (strlen($file) > 40)
80 {
81 $file = substr($file, 0, 16) . '…' . substr($file, -16, 16);
82 }
83
84 $rc[] = '<span title="Path: ' . $path . '">' . $file . '</span>';
85 $rc[] = Uploaded::getMIME(DOCUMENT_ROOT . $path);
86 $rc[] = format_size(filesize(DOCUMENT_ROOT . $path));
87
88 return $rc;
89 }
90
91 protected function preview($path)
92 {
93 $rc = '<a class="download" href="' . $path . '">' . t('download', array(), array('scope' => array('fileupload', 'element'))) . '</a>';
94
95 return $rc;
96 }
97
98 protected function render_inner_html()
99 {
100 $path = $this['value'];
101
102 $rc = new Text
103 (
104 array
105 (
106 'value' => $this['value'],
107 'readonly' => true,
108 'name' => $this['name'],
109 'class' => 'reminder'
110 )
111 )
112
113 . ' <div class="alert alert-error undissmisable"></div>'
114 . ' <label class="btn trigger"><i class="icon-file"></i> '
115 . t($this[self::BUTTON_LABEL], array(), array('scope' => 'button'))
116 . '<input type="file" /></label>';
117
118
119
120
121
122 $rc .= '<div class="uploading">';
123 $rc .= '<span class="progress like-input"><span class="position"><span class="text"> </span></span></span> ';
124 $rc .= '<button type="button" class="btn btn-danger cancel">' . t('cancel', array(), array('scope' => 'button')) . '</button>';
125 $rc .= '</div>';
126
127
128
129
130
131
132 $limit = $this[self::FILE_WITH_LIMIT];
133
134 if ($limit)
135 {
136 if ($limit === true)
137 {
138 $limit = ini_get('upload_max_filesize') * 1024;
139 }
140
141 $limit = format_size($limit * 1024);
142
143 $rc .= PHP_EOL . '<div class="file-size-limit small" style="margin-top: .5em">';
144 $rc .= t('The maximum file size must be less than :size.', array(':size' => $limit));
145 $rc .= '</div>';
146 }
147
148
149
150
151
152 $infos = null;
153
154 if ($path)
155 {
156 if (!is_file(DOCUMENT_ROOT . $path))
157 {
158 $infos = '<span class="warn">' . t('The file %file is missing !', array('%file' => basename($path))) . '</span>';
159 }
160 else
161 {
162 $infos = $this->infos();
163 }
164
165 if ($infos)
166 {
167 $this->add_class('has-info');
168 }
169 }
170
171 return $rc . <<<EOT
172 <div class="infos">$infos</div>
173 EOT;
174 }
175
176 protected function alter_dataset(array $dataset)
177 {
178 $limit = $this[self::FILE_WITH_LIMIT] ?: 2 * 1024;
179
180 if ($limit === true)
181 {
182 $limit = ini_get('upload_max_filesize') * 1024;
183 }
184
185 return parent::alter_dataset($dataset) + array
186 (
187 'name' => $this['name'],
188 'max-file-size' => $limit * 1024
189 );
190 }
191
192 protected function render_outer_html()
193 {
194 $upload_url = $this[self::T_UPLOAD_URL];
195
196 if ($upload_url)
197 {
198 $this->dataset['upload-url'] = $upload_url;
199 }
200
201 return parent::render_outer_html();
202 }
203 }