60 if (!$this->has_upload_file(
'upload_file')) {
64 $oUpload =
dbx()->get_system_obj(
'dbxUpload');
65 $oUpload->upload($_FILES[
'upload_file']);
66 $oUpload->allowed = array(
'image/jpeg',
'image/jpg',
'image/pjpeg',
'image/png',
'image/x-png',
'image/webp',
'image/x-webp',
'image/gif');
67 $oUpload->file_max_size = 2 * 1024 * 1024;
68 $oUpload->file_overwrite =
true;
69 $oUpload->file_new_name_body =
'avatar-' . $rid;
70 $oUpload->file_new_name_ext =
'webp';
71 $oUpload->image_convert =
'webp';
72 $oUpload->webp_quality = 86;
73 $oUpload->image_resize =
true;
74 $oUpload->image_ratio_crop =
true;
75 $oUpload->image_x = 640;
76 $oUpload->image_y = 640;
77 $oUpload->process($this->avatar_dir());
79 if ($oUpload->processed) {
80 $ok =
$db->update($this->ddUser, array(
'avatar' => $oUpload->file_dst_name), $rid);
82 $data[
'avatar'] = $oUpload->file_dst_name;
83 $this->remove_old_avatar_files($rid, $oUpload->file_dst_name);
87 $error =
$texts->get_fd_message(
'avatar_save_error');
89 $error =
$texts->format_fd_message(
91 array(
'error' => $oUpload->error)
99 public function run() {
100 $uid = (int)
dbx()->user();
104 $db =
dbx()->get_system_obj(
'dbxDB');
105 $data =
$db->select1($this->ddUser, $rid);
106 $oForm = new \dbxForm();
107 $oForm->init(
'dbxUser_avatar',
'form-avatar');
108 $oForm->_fd =
'dbxUser|user-profile';
109 $oForm->load_fd_messages();
110 if (!is_array($data)) {
111 return '<div class="alert alert-warning">'
112 . $oForm->get_fd_message(
'user_not_found')
115 $oForm->set_workflow_scope(
'self-' . $uid);
116 $oForm->_data = $data;
117 $oForm->_dd = $this->ddUser;
118 $oForm->_action =
'?dbx_modul=dbxUser&dbx_run1=user&dbx_run2=edit_avatar';
119 $oForm->_msg_info =
'';
121 $oForm->set_state_value(
'rid', $uid);
123 if ($oForm->submit()) {
124 if (!$this->has_upload_file(
'upload_file')) {
125 $oForm->_msg_error = $oForm->get_fd_message(
'avatar_select_file');
129 $oForm->_msg_success =
$ok ? $oForm->get_fd_message(
'avatar_saved') :
'';
130 $oForm->_msg_error =
$ok ?
'' : $avatarError;
137 '<img class="dbx-avatar-img" src="'
138 . $this->avatar_url($data[
'avatar'] ??
'')
140 .
'" alt="' .
dbx()->
esc($oForm->get_fd_message(
'avatar_alt')) .
'">'
142 $jsMessages = json_encode(
144 'upload_running' => $oForm->get_fd_message(
'upload_running'),
145 'file_selected' => $oForm->get_fd_message(
'upload_file_selected'),
146 'upload_ready' => $oForm->get_fd_message(
'upload_ready'),
147 'save_profile' => $oForm->get_fd_message(
'upload_save_profile'),
149 JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES
151 $oForm->add_js_code(str_replace(
'{dbx_avatar_messages}', $jsMessages ?:
'{}', <<<
'JS'
153 var messages = {dbx_avatar_messages};
154 var drop = document.getElementById(
'uploader_{i}');
155 var panel = document.getElementById(
'dbx_avatar_panel_{i}');
156 if (!drop || !panel || drop.dataset.ready ===
'1')
return;
157 drop.dataset.ready =
'1';
159 var input = panel.querySelector(
'input[type="file"][name="upload_file"]');
160 var title = drop.querySelector(
'.dbx-avatar-drop-title');
161 var meta = drop.querySelector(
'.dbx-avatar-drop-meta');
162 var defaultTitle = title ? title.textContent :
'';
163 var defaultMeta = meta ? meta.textContent :
'';
166 function setBusy(active) {
168 drop.classList.toggle(
'is-active', active);
169 drop.classList.toggle(
'is-uploading', active);
170 drop.setAttribute(
'aria-busy', active ?
'true' :
'false');
171 if (title) title.textContent = active ? messages.upload_running : (drop.dataset.fileName || defaultTitle);
172 if (meta && active) meta.textContent = messages.file_selected;
175 function setMessage(message) {
176 if (meta && message) meta.textContent = message;
179 function setSelected(file) {
181 drop.dataset.fileName = file.name || defaultTitle;
182 drop.classList.add(
'has-file');
183 if (title) title.textContent = file.name || defaultTitle;
184 if (meta) meta.textContent = messages.upload_ready;
187 function syncInput(file) {
188 if (!input || !file)
return false;
190 var transfer =
new DataTransfer();
191 transfer.items.add(file);
192 input.files = transfer.files;
193 return input.files && input.files.length === 1;
199 function send(file, fileAlreadyOnInput) {
200 if (!file || busy)
return;
202 fileAlreadyOnInput || syncInput(file);
204 setMessage(messages.save_profile);
207 function openPicker() {
208 if (!input || busy)
return;
210 if (title) title.textContent = defaultTitle;
211 if (meta) meta.textContent = defaultMeta;
212 drop.classList.remove(
'has-file');
216 drop.addEventListener(
'click',
function () {
217 if (busy)
return false;
219 if (title) title.textContent = defaultTitle;
220 if (meta) meta.textContent = defaultMeta;
221 drop.classList.remove(
'has-file');
223 drop.addEventListener(
'keydown',
function (event) {
224 if (event.key ===
'Enter' || event.key ===
' ') {
225 event.preventDefault();
231 input.addEventListener(
'change',
function () {
232 send(input.files && input.files[0],
true);
236 var outerForm = panel.closest(
'form');
238 outerForm.addEventListener(
'submit',
function () {
239 if (input && input.files && input.files[0]) setBusy(
true);
243 [
'dragenter',
'dragover'].forEach(
function (eventName) {
244 drop.addEventListener(eventName,
function (event) {
245 event.preventDefault();
250 [
'dragleave',
'drop'].forEach(
function (eventName) {
251 drop.addEventListener(eventName,
function (event) {
252 event.preventDefault();
257 drop.addEventListener(
'drop',
function (event) {
258 event.preventDefault();
259 event.stopPropagation();
260 var files =
event.dataTransfer &&
event.dataTransfer.files;
261 send(files && files[0],
false);
266 return $oForm->run();