1
0
Fork 0
mirror of https://github.com/Oreolek/ifhub.club.git synced 2024-05-19 09:18:18 +03:00

Загрузка фото в профиль пользователя

This commit is contained in:
Mzhelskiy Maxim 2014-02-20 11:13:30 +07:00
parent c1235f6507
commit 2e5c8677a0
8 changed files with 141 additions and 428 deletions

View file

@ -71,14 +71,13 @@ class ActionSettings extends Action {
$this->AddEventPreg('/^profile$/i','/^resize-avatar/i','/^$/i','EventResizeAvatar');
$this->AddEventPreg('/^profile$/i','/^remove-avatar/i','/^$/i','EventRemoveAvatar');
$this->AddEventPreg('/^profile$/i','/^cancel-avatar/i','/^$/i','EventCancelAvatar');
$this->AddEventPreg('/^profile$/i','/^upload-foto/i','/^$/i','EventUploadFoto');
$this->AddEventPreg('/^profile$/i','/^resize-foto/i','/^$/i','EventResizeFoto');
$this->AddEventPreg('/^profile$/i','/^remove-foto/i','/^$/i','EventRemoveFoto');
$this->AddEventPreg('/^profile$/i','/^cancel-foto/i','/^$/i','EventCancelFoto');
$this->AddEvent('profile','EventProfile');
$this->AddEvent('invite','EventInvite');
$this->AddEvent('tuning','EventTuning');
$this->AddEvent('account','EventAccount');
$this->AddEventPreg('/^ajax-upload-photo$/i','/^$/i','EventAjaxUploadPhoto');
$this->AddEventPreg('/^ajax-remove-photo$/i','/^$/i','EventAjaxRemovePhoto');
}
@ -87,145 +86,45 @@ class ActionSettings extends Action {
**********************************************************************************
*/
/**
* Загрузка временной картинки фото для последущего ресайза
*/
protected function EventUploadFoto() {
protected function EventAjaxUploadPhoto() {
/**
* Устанавливаем формат Ajax ответа
*/
$this->Viewer_SetResponseAjax('jsonIframe',false);
if(!isset($_FILES['foto']['tmp_name'])) {
if(!isset($_FILES['photo']['tmp_name'])) {
return $this->EventErrorDebug();
}
/**
* Копируем загруженный файл
*/
$sFileTmp=Config::Get('sys.cache.dir').func_generator();
if (!move_uploaded_file($_FILES['foto']['tmp_name'],$sFileTmp)) {
if (!$oUser=$this->User_GetUserById(getRequestStr('user_id'))) {
return $this->EventErrorDebug();
}
/**
* Ресайзим и сохраняем именьшенную копию
* Храним две копии - мелкую для показа пользователю и крупную в качестве исходной для ресайза
*/
$sDir=Config::Get('path.uploads.images')."/tmp/fotos/{$this->oUserCurrent->getId()}";
if ($sFile=$this->Image_Resize($sFileTmp,$sDir,'original',Config::Get('view.img_max_width'),Config::Get('view.img_max_height'),1000,null,true)) {
if ($sFilePreview=$this->Image_Resize($sFileTmp,$sDir,'preview',Config::Get('view.img_max_width'),Config::Get('view.img_max_height'),200,null,true)) {
/**
* Сохраняем в сессии временный файл с изображением
*/
$this->Session_Set('sFotoFileTmp',$sFile);
$this->Session_Set('sFotoFilePreviewTmp',$sFilePreview);
$this->Viewer_AssignAjax('sTmpFile',$this->Image_GetWebPath($sFilePreview));
unlink($sFileTmp);
return;
}
}
$this->Message_AddError($this->Image_GetLastError(),$this->Lang_Get('error'));
unlink($sFileTmp);
}
/**
* Вырезает из временной фотки область нужного размера, ту что задал пользователь
*/
protected function EventResizeFoto() {
/**
* Устанавливаем формат Ajax ответа
*/
$this->Viewer_SetResponseAjax('json');
/**
* Достаем из сессии временный файл
*/
$sFile=$this->Session_Get('sFotoFileTmp');
$sFilePreview=$this->Session_Get('sFotoFilePreviewTmp');
if (!file_exists($sFile)) {
if (!$oUser->isAllowEdit()) {
return $this->EventErrorDebug();
}
/**
* Определяем размер большого фото для подсчета множителя пропорции
*/
$fRation=1;
if ($aSizeFile=getimagesize($sFile) and isset($aSizeFile[0])) {
$fRation=$aSizeFile[0]/200; // 200 - размер превью по которой пользователь определяет область для ресайза
if ($fRation<1) {
$fRation=1;
}
}
/**
* Получаем размер области из параметров
*/
$aSize=array();
$aSizeTmp=getRequest('size');
if (isset($aSizeTmp['x']) and is_numeric($aSizeTmp['x'])
and isset($aSizeTmp['y']) and is_numeric($aSizeTmp['y'])
and isset($aSizeTmp['x2']) and is_numeric($aSizeTmp['x2'])
and isset($aSizeTmp['y2']) and is_numeric($aSizeTmp['y2'])) {
$aSize=array('x1'=>round($fRation*$aSizeTmp['x']),'y1'=>round($fRation*$aSizeTmp['y']),'x2'=>round($fRation*$aSizeTmp['x2']),'y2'=>round($fRation*$aSizeTmp['y2']));
}
/**
* Вырезаем аватарку
*/
if ($sFileWeb=$this->User_UploadFoto($sFile,$this->oUserCurrent,$aSize)) {
/**
* Удаляем старые аватарки
*/
$this->oUserCurrent->setProfileFoto($sFileWeb);
$this->User_Update($this->oUserCurrent);
$this->Image_RemoveFile($sFilePreview);
/**
* Удаляем из сессии
*/
$this->Session_Drop('sFotoFileTmp');
$this->Session_Drop('sFotoFilePreviewTmp');
$this->Viewer_AssignAjax('sFile',$this->oUserCurrent->getProfileFoto());
$this->Viewer_AssignAjax('sTitleUpload',$this->Lang_Get('settings_profile_photo_change'));
} else {
$this->Message_AddError($this->Lang_Get('settings_profile_avatar_error'),$this->Lang_Get('error'));
if (true!==$sResult=$this->User_UploadProfilePhoto($_FILES['photo'],$oUser)) {
$this->Message_AddError(is_bool($sResult) ? '' : $sResult,$this->Lang_Get('error'));
return false;
}
}
/**
* Удаляет фото
*/
protected function EventRemoveFoto() {
/**
* Устанавливаем формат Ajax ответа
*/
$this->Viewer_SetResponseAjax('json');
/**
* Удаляем
*/
$this->User_DeleteFoto($this->oUserCurrent);
$this->oUserCurrent->setProfileFoto(null);
$this->User_Update($this->oUserCurrent);
/**
* Возвращает дефолтную аватарку
*/
$this->Viewer_AssignAjax('sFile',$this->oUserCurrent->getProfileFotoDefault());
$this->Viewer_AssignAjax('sTitleUpload',$this->Lang_Get('settings_profile_photo_upload'));
}
/**
* Отмена ресайза фотки, необходимо удалить временный файл
*/
protected function EventCancelFoto() {
/**
* Устанавливаем формат Ajax ответа
*/
$this->Viewer_SetResponseAjax('json');
/**
* Достаем из сессии файл и удаляем
*/
$sFile=$this->Session_Get('sFotoFileTmp');
$this->Image_RemoveFile($sFile);
$sFile=$this->Session_Get('sFotoFilePreviewTmp');
$this->Image_RemoveFile($sFile);
/**
* Удаляем из сессии
*/
$this->Session_Drop('sFotoFileTmp');
$this->Session_Drop('sFotoFilePreviewTmp');
$this->Viewer_AssignAjax('sChooseText',$this->Lang_Get('settings_profile_photo_change'));
$this->Viewer_AssignAjax('sFile',$oUser->getProfileFotoPath());
}
protected function EventAjaxRemovePhoto() {
$this->Viewer_SetResponseAjax('json');
if (!$oUser=$this->User_GetUserById(getRequestStr('user_id'))) {
return $this->EventErrorDebug();
}
if (!$oUser->isAllowEdit()) {
return $this->EventErrorDebug();
}
$this->User_DeleteFoto($oUser);
$this->User_Update($oUser);
$this->Viewer_AssignAjax('sChooseText',$this->Lang_Get('settings_profile_photo_upload'));
$this->Viewer_AssignAjax('sFile',$oUser->getProfileFotoPath());
}
/**
* Загрузка временной картинки для аватара

View file

@ -1169,84 +1169,57 @@ class ModuleUser extends Module {
}
}
/**
* загрузка фотографии пользователя
* Загрузка фото в профиль пользователя
*
* @param string $sFileTmp Серверный путь до временной фотографии
* @param ModuleUser_EntityUser $oUser Объект пользователя
* @param array $aSize Размер области из которой нужно вырезать картинку - array('x1'=>0,'y1'=>0,'x2'=>100,'y2'=>100)
* @return string|bool
* @param $aFile
* @param $oUser
*
* @return bool
*/
public function UploadFoto($sFileTmp,$oUser,$aSize=array()) {
if (!file_exists($sFileTmp)) {
public function UploadProfilePhoto($aFile,$oUser) {
if(!is_array($aFile) || !isset($aFile['tmp_name'])) {
return false;
}
$sDirUpload=$this->Image_GetIdDir($oUser->getId());
$aParams=$this->Image_BuildParams('foto');
if ($aSize) {
$oImage = $this->Image_CreateImageObject($sFileTmp);
/**
* Если объект изображения не создан,
* возвращаем ошибку
*/
if($sError=$oImage->get_last_error()) {
// Вывод сообщения об ошибки, произошедшей при создании объекта изображения
// $this->Message_AddError($sError,$this->Lang_Get('error'));
@unlink($sFileTmp);
return false;
}
$iWSource=$oImage->get_image_params('width');
$iHSource=$oImage->get_image_params('height');
/**
* Достаем переменные x1 и т.п. из $aSize
*/
extract($aSize,EXTR_PREFIX_SAME,'ops');
if ($x1>$x2) {
// меняем значения переменных
$x1 = $x1 + $x2;
$x2 = $x1 - $x2;
$x1 = $x1 - $x2;
}
if ($y1>$y2) {
$y1 = $y1 + $y2;
$y2 = $y1 - $y2;
$y1 = $y1 - $y2;
}
if ($x1<0) {
$x1=0;
}
if ($y1<0) {
$y1=0;
}
if ($x2>$iWSource) {
$x2=$iWSource;
}
if ($y2>$iHSource) {
$y2=$iHSource;
}
$iW=$x2-$x1;
// Допускаем минимальный клип в 32px (исключая маленькие изображения)
if ($iW<32 && $x1+32<=$iWSource) {
$iW=32;
}
$iH=$y2-$y1;
$oImage->crop($iW,$iH,$x1,$y1);
$oImage->output(null,$sFileTmp);
$sFileTmp=Config::Get('sys.cache.dir').func_generator();
if (!move_uploaded_file($aFile['tmp_name'],$sFileTmp)) {
return false;
}
if ($sFileFoto=$this->Image_Resize($sFileTmp,$sDirUpload,func_generator(6),Config::Get('view.img_max_width'),Config::Get('view.img_max_height'),Config::Get('module.user.profile_photo_width'),null,true,$aParams)) {
@unlink($sFileTmp);
/**
* удаляем старое фото
*/
$this->DeleteFoto($oUser);
return $this->Image_GetWebPath($sFileFoto);
$aParams=$this->Image_BuildParams('profile_photo');
/**
* Если объект изображения не создан, возвращаем ошибку
*/
if(!$oImage=$this->Image_Open($sFileTmp,$aParams)) {
$this->Fs_RemoveFileLocal($sFileTmp);
return $this->Image_GetLastError();
}
@unlink($sFileTmp);
return false;
$sPath=$this->Image_GetIdDir($oUser->getId(),'users');
/**
* Имя файла для сохранения
*/
$sFileName=func_generator(8);
/**
* Сохраняем копию нужного размера
*/
$aSize=$this->Media_ParsedImageSize(Config::Get('module.user.profile_photo_size'));
if ($aSize['crop']) {
$oImage->cropProportion($aSize['w']/$aSize['h'],'center');
}
if (!$sFileResult=$oImage->resize($aSize['w'],$aSize['h'],true)->saveSmart($sPath,$sFileName)) {
return $this->Image_GetLastError();
}
/**
* Теперь можно удалить временный файл
*/
$this->Fs_RemoveFileLocal($sFileTmp);
/**
* Если было старое фото, то удаляем
*/
$this->DeleteFoto($oUser);
$oUser->setProfileFoto($sFileResult);
$this->User_Update($oUser);
return true;
}
/**
* Удаляет фото пользователя
@ -1254,7 +1227,10 @@ class ModuleUser extends Module {
* @param ModuleUser_EntityUser $oUser
*/
public function DeleteFoto($oUser) {
$this->Image_RemoveFile($this->Image_GetServerPath($oUser->getProfileFoto()));
if ($oUser->getProfileFoto()) {
$this->Image_RemoveFile($oUser->getProfileFoto());
$oUser->setProfileFoto(null);
}
}
/**
* Проверяет логин на корректность

View file

@ -380,7 +380,7 @@ class ModuleUser_EntityUser extends Entity {
*/
public function getProfileFotoPath() {
if ($this->getProfileFoto()) {
return $this->getProfileFoto();
return $this->Media_GetImageWebPath($this->getProfileFoto());
}
return $this->getProfileFotoDefault();
}
@ -463,6 +463,19 @@ class ModuleUser_EntityUser extends Entity {
public function getDisplayName() {
return $this->getLogin();
}
/**
* Проверяем возможность редактирования пользователя текущим юзером
*
* @return bool
*/
public function isAllowEdit() {
if ($oUser=$this->User_GetUserCurrent()) {
if ($oUser->getId()==$this->getId() or $oUser->isAdministrator()) {
return true;
}
}
return false;
}
/**

View file

@ -132,7 +132,7 @@ $config['module']['user']['time_active'] = 60*60*24*7; // Число секун
$config['module']['user']['usernote_text_max'] = 250; // Максимальный размер заметки о пользователе
$config['module']['user']['usernote_per_page'] = 20; // Число заметок на одну страницу
$config['module']['user']['userfield_max_identical'] = 2; // Максимальное число контактов одного типа
$config['module']['user']['profile_photo_width'] = 250; // ширина квадрата фотографии в профиле, px
$config['module']['user']['profile_photo_size'] = '370x'; // размер фото в профиле пользователя, формат вида: WxH[crop]
$config['module']['user']['name_max'] = 30; // максимальная длинна имени в профиле пользователя
$config['module']['user']['captcha_use_registration'] = true; // проверять поле капчи при регистрации пользователя
$config['module']['user']['complaint_captcha'] = true; // Использовать или нет каптчу при написании жалобы

View file

@ -50,42 +50,6 @@ ls.user = (function ($) {
ls.hook.run('ls_user_reactivation_after', [form, result]);
});
/* Аякс загрузка изображений */
this.ajaxUploadImageInit({
selectors: {
element: '.js-ajax-avatar-upload'
},
cropOptions: {
aspectRatio: 1
},
urls: {
upload: aRouter['settings'] + 'profile/upload-avatar/',
remove: aRouter['settings'] + 'profile/remove-avatar/',
cancel: aRouter['settings'] + 'profile/cancel-avatar/',
crop: aRouter['settings'] + 'profile/resize-avatar/'
}
});
this.ajaxUploadImageInit({
selectors: {
element: '.js-ajax-photo-upload'
},
urls: {
upload: aRouter['settings'] + 'profile/upload-foto/',
remove: aRouter['settings'] + 'profile/remove-foto/',
cancel: aRouter['settings'] + 'profile/cancel-foto/',
crop: aRouter['settings'] + 'profile/resize-foto/'
}
});
$('.js-ajax-image-upload-crop-cancel').on('click', function (e) {
self.ajaxUploadImageCropCancel();
});
$('.js-ajax-image-upload-crop-submit').on('click', function (e) {
self.ajaxUploadImageCropSubmit();
});
$('.js-modal-toggle-registration').on('click', function (e) {
$('[data-tab-target=tab-pane-registration]').tab('activate');
ls.captcha.update();
@ -141,6 +105,16 @@ ls.user = (function ($) {
$('#modal-users-select').modal('hide');
});
// Загрузка фотографии в профиль
$('.js-ajax-user-photo-upload').on('change', function () {
self.uploadProfilePhoto($(this));
});
// Удаление фотографии профиля
$('.js-ajax-user-photo-upload-remove').on('click', function () {
self.removeProfilePhoto($(this).data('userId'));
return false;
});
};
/**
@ -271,184 +245,45 @@ ls.user = (function ($) {
};
/**
* Загрузка временной аватарки
* @param form
* @param input
*/
this.ajaxUploadImageInit = function(options) {
var self = this;
var defaults = {
cropOptions: {
minSize: [32, 32]
},
selectors: {
element: '.js-ajax-image-upload',
image: '.js-ajax-image-upload-image',
image_crop: '.js-image-crop',
remove_button: '.js-ajax-image-upload-remove',
choose_button: '.js-ajax-image-upload-choose',
input_file: '.js-ajax-image-upload-file',
crop_cancel_button: '.js-ajax-image-upload-crop-cancel',
crop_submit_button: '.js-ajax-image-upload-crop-submit'
},
urls: {
upload: aRouter['settings'] + 'profile/upload-avatar/',
remove: aRouter['settings'] + 'profile/remove-avatar/',
cancel: aRouter['settings'] + 'profile/cancel-avatar/',
crop: aRouter['settings'] + 'profile/resize-avatar/'
}
};
var options = $.extend(true, {}, defaults, options);
$(options.selectors.element).each(function () {
var $element = $(this);
var elements = {
element: $element,
remove_button: $element.find(options.selectors.remove_button),
choose_button: $element.find(options.selectors.choose_button),
image: $element.find(options.selectors.image),
image_crop: $element.find(options.selectors.image_crop)
};
$element.find(options.selectors.input_file).on('change', function () {
self.currentElements = elements;
self.currentOptions = options;
self.ajaxUploadImage(null, $(this), options);
});
elements.remove_button.on('click', function (e) {
self.ajaxUploadImageRemove(options, elements);
e.preventDefault();
});
});
};
/**
* Загрузка временной аватарки
* @param form
* @param input
*/
this.ajaxUploadImage = function(form, input, options) {
if ( ! form && input ) {
var form = $('<form method="post" enctype="multipart/form-data"></form>').hide().appendTo('body');
input.clone(true).insertAfter(input);
input.appendTo(form);
}
ls.ajax.submit(options.urls.upload, form, function (data) {
if (data.bStateError) {
ls.msg.error(data.sMsgTitle,data.sMsg);
} else {
this.ajaxUploadImageModalCrop(data.sTmpFile, options);
}
form.remove();
}.bind(this));
};
/**
* Показывает форму для ресайза аватарки
* @param sImgFile
*/
this.ajaxUploadImageModalCrop = function(sImgFile, options) {
var self = this;
this.jcropImage && this.jcropImage.destroy();
$('.js-image-crop').attr('src', sImgFile + '?' + Math.random()).css({
'width': 'auto',
'height': 'auto'
});
if ($('#modal-image-crop').length)
$('#modal-image-crop').modal('show');
else {
ls.debug('Error [Ajax Image Upload]:\nМодальное окно ресайза изображения не найдено');
}
$('.js-image-crop').Jcrop(options.cropOptions, function () {
self.jcropImage = this;
this.setSelect([0, 0, 500, 500]);
});
};
/**
* Удаление аватарки
*/
this.ajaxUploadImageRemove = function(options, elements) {
ls.hook.marker('removeAvatarBefore');
ls.ajax.load(options.urls.remove, {}, function(result) {
if (result.bStateError) {
ls.msg.error(null,result.sMsg);
} else {
elements.image.attr('src', result.sFile + '?' + Math.random());
elements.remove_button.hide();
elements.choose_button.text(result.sTitleUpload);
ls.hook.run('ls_user_remove_avatar_after', [result]);
}
});
};
/**
* Отмена ресайза аватарки, подчищаем временный данные
*/
this.ajaxUploadImageCropCancel = function() {
ls.hook.marker('cancelAvatarBefore');
ls.ajax.load(this.currentOptions.urls.cancel, {}, function(result) {
if (result.bStateError) {
ls.msg.error(null,result.sMsg);
} else {
$('#modal-image-crop').modal('hide');
ls.hook.run('ls_user_cancel_avatar_after', [result]);
}
});
};
/**
* Выполняет ресайз аватарки
*/
this.ajaxUploadImageCropSubmit = function() {
var self = this;
if ( ! this.jcropImage ) {
return false;
}
var params = {
size: this.jcropImage.tellSelect()
};
ls.hook.marker('resizeAvatarBefore');
ls.ajax.load(self.currentOptions.urls.crop, params, function(result) {
if (result.bStateError) {
ls.msg.error(null,result.sMsg);
} else {
self.currentElements.image.attr('src',result.sFile+'?'+Math.random());
$('#modal-image-crop').modal('hide');
self.currentElements.remove_button.show();
self.currentElements.choose_button.text(result.sTitleUpload);
ls.hook.run('ls_user_resize_avatar_after', [params, result]);
}
});
return false;
};
this.addComplaint = function(form) {
ls.ajax.submit(aRouter.profile+'ajax-complaint-add/', form, function(result){
$('#modal-complaint-user').modal('hide');
});
};
this.uploadProfilePhoto = function(input) {
var form = $('<form method="post" enctype="multipart/form-data"></form>').hide().appendTo('body');
input.clone(true).insertAfter(input);
input.appendTo(form);
$('<input type="hidden" name="user_id" value="'+input.data('userId')+'" >').appendTo(form);
ls.ajax.submit(aRouter.settings+'ajax-upload-photo/', form, function (data) {
if (data.bStateError) {
ls.msg.error(data.sMsgTitle,data.sMsg);
} else {
$('.js-ajax-user-photo-image').attr('src',data.sFile);
$('.js-ajax-user-photo-upload-choose').html(data.sChooseText);
$('.js-ajax-user-photo-upload-remove').show();
}
form.remove();
}.bind(this));
};
this.removeProfilePhoto = function(idUser) {
var params = {user_id: idUser};
ls.ajax.load(aRouter.settings+'ajax-remove-photo/', params, function(result) {
if (result.bStateError) {
ls.msg.error(null,result.sMsg);
} else {
$('.js-ajax-user-photo-image').attr('src',result.sFile);
$('.js-ajax-user-photo-upload-choose').html(result.sChooseText);
$('.js-ajax-user-photo-upload-remove').hide();
}
});
return false;
};
return this;
}).call(ls.user || {},jQuery);

View file

@ -123,14 +123,6 @@
{/if}
</fieldset>
{* Аватар *}
{include file='forms/fields/form.field.file.image.tpl'
sFieldName = 'avatar'
sFieldImagePath = $oUserCurrent->getProfileAvatarPath(100)
bFieldIsImage = $oUserCurrent->getProfileAvatar()}
{hook run='form_settings_profile_end'}
{* Скрытые поля *}

View file

@ -31,18 +31,18 @@
{* Фото *}
<a href="{$oUserProfile->getUserWebPath()}">
<img src="{$oUserProfile->getProfileFotoPath()}" alt="{$oUserProfile->getDisplayName()} photo" class="profile-photo js-ajax-image-upload-image" />
<img src="{$oUserProfile->getProfileFotoPath()}" alt="{$oUserProfile->getDisplayName()} photo" class="profile-photo js-ajax-user-photo-image" />
</a>
</div>
{if $sAction=='settings' and $oUserCurrent and $oUserCurrent->getId() == $oUserProfile->getId()}
{if $oUserProfile->isAllowEdit()}
<p class="upload-photo">
<label for="foto" class="form-input-file">
<span class="js-ajax-image-upload-choose link-dotted">{if $oUserCurrent->getProfileFoto()}{$aLang.settings_profile_photo_change}{else}{$aLang.settings_profile_photo_upload}{/if}</span>
<input type="file" name="foto" id="foto" class="js-ajax-image-upload-file">
<label for="photo" class="form-input-file">
<span class="js-ajax-user-photo-upload-choose link-dotted">{if $oUserProfile->getProfileFoto()}{$aLang.settings_profile_photo_change}{else}{$aLang.settings_profile_photo_upload}{/if}</span>
<input type="file" name="photo" id="photo" class="js-ajax-user-photo-upload" data-user-id="{$oUserProfile->getId()}">
</label>
&nbsp;&nbsp;&nbsp;
<a href="#" class="js-ajax-image-upload-remove link-dotted" style="{if ! $oUserCurrent->getProfileFoto()}display:none;{/if}">{$aLang.settings_profile_foto_delete}</a>
<a href="#" data-user-id="{$oUserProfile->getId()}" class="js-ajax-user-photo-upload-remove link-dotted" style="{if !$oUserProfile->getProfileFoto()}display:none;{/if}">{$aLang.settings_profile_foto_delete}</a>
</p>
{/if}
{/block}

View file

@ -2,8 +2,6 @@
$config = array();
$config['module']['user']['profile_photo_width'] = 300;
/**
* Grid type:
*