} else {
$tools['edit'] = ['photos/' . $a->data['user']['nickname'] . '/image/' . $datum . '/edit', DI::l10n()->t('Edit photo')];
$tools['delete'] = ['photos/' . $a->data['user']['nickname'] . '/image/' . $datum . '/drop', DI::l10n()->t('Delete photo')];
- $tools['profile'] = ['profile_photo/use/'.$ph[0]['resource-id'], DI::l10n()->t('Use as profile photo')];
+ $tools['profile'] = ['settings/profile/photo/crop/' . $ph[0]['resource-id'], DI::l10n()->t('Use as profile photo')];
}
if (
+++ /dev/null
-<?php
-/**
- * @file mod/profile_photo.php
- */
-
-use Friendica\App;
-use Friendica\BaseModule;
-use Friendica\Core\Renderer;
-use Friendica\Core\Worker;
-use Friendica\Database\DBA;
-use Friendica\DI;
-use Friendica\Model\Contact;
-use Friendica\Model\Photo;
-use Friendica\Model\Profile;
-use Friendica\Object\Image;
-use Friendica\Util\Strings;
-
-function profile_photo_init(App $a)
-{
- if (!local_user()) {
- return;
- }
-
- Profile::load($a, $a->user['nickname']);
-}
-
-function profile_photo_post(App $a)
-{
- if (!local_user()) {
- notice(DI::l10n()->t('Permission denied.') . EOL);
- return;
- }
-
- BaseModule::checkFormSecurityTokenRedirectOnError('/profile_photo', 'profile_photo');
-
- if (!empty($_POST['cropfinal']) && $_POST['cropfinal'] == 1) {
-
- // unless proven otherwise
- $is_default_profile = 1;
-
- if ($_REQUEST['profile']) {
- $r = q("select id, `is-default` from profile where id = %d and uid = %d limit 1", intval($_REQUEST['profile']),
- intval(local_user())
- );
-
- if (DBA::isResult($r) && (!intval($r[0]['is-default']))) {
- $is_default_profile = 0;
- }
- }
-
-
-
- // phase 2 - we have finished cropping
-
- if ($a->argc != 2) {
- notice(DI::l10n()->t('Image uploaded but image cropping failed.') . EOL);
- return;
- }
-
- $image_id = $a->argv[1];
-
- if (substr($image_id, -2, 1) == '-') {
- $scale = substr($image_id, -1, 1);
- $image_id = substr($image_id, 0, -2);
- }
-
-
- $srcX = $_POST['xstart'];
- $srcY = $_POST['ystart'];
- $srcW = $_POST['xfinal'] - $srcX;
- $srcH = $_POST['yfinal'] - $srcY;
-
- $base_image = Photo::selectFirst([], ['resource-id' => $image_id, 'uid' => local_user(), 'scale' => $scale]);
-
- $path = 'profile/' . $a->user['nickname'];
- if (DBA::isResult($base_image)) {
-
- $Image = Photo::getImageForPhoto($base_image);
- if ($Image->isValid()) {
- $Image->crop(300, $srcX, $srcY, $srcW, $srcH);
-
- $r = Photo::store($Image, local_user(), 0, $base_image['resource-id'], $base_image['filename'],
- DI::l10n()->t('Profile Photos'), 4, $is_default_profile);
-
- if ($r === false) {
- notice(DI::l10n()->t('Image size reduction [%s] failed.', "300") . EOL);
- }
-
- $Image->scaleDown(80);
-
- $r = Photo::store($Image, local_user(), 0, $base_image['resource-id'], $base_image['filename'],
- DI::l10n()->t('Profile Photos'), 5, $is_default_profile);
-
- if ($r === false) {
- notice(DI::l10n()->t('Image size reduction [%s] failed.', "80") . EOL);
- }
-
- $Image->scaleDown(48);
-
- $r = Photo::store($Image, local_user(), 0, $base_image['resource-id'], $base_image['filename'],
- DI::l10n()->t('Profile Photos'), 6, $is_default_profile);
-
- if ($r === false) {
- notice(DI::l10n()->t('Image size reduction [%s] failed.', "48") . EOL);
- }
-
- // If setting for the default profile, unset the profile photo flag from any other photos I own
-
- if ($is_default_profile) {
- q("UPDATE `photo` SET `profile` = 0 WHERE `profile` = 1 AND `resource-id` != '%s' AND `uid` = %d",
- DBA::escape($base_image['resource-id']), intval(local_user())
- );
- } else {
- q("update profile set photo = '%s', thumb = '%s' where id = %d and uid = %d",
- DBA::escape(DI::baseUrl() . '/photo/' . $base_image['resource-id'] . '-4.' . $Image->getExt()),
- DBA::escape(DI::baseUrl() . '/photo/' . $base_image['resource-id'] . '-5.' . $Image->getExt()),
- intval($_REQUEST['profile']), intval(local_user())
- );
- }
-
- Contact::updateSelfFromUserID(local_user(), true);
-
- info(DI::l10n()->t('Shift-reload the page or clear browser cache if the new photo does not display immediately.') . EOL);
- // Update global directory in background
- if ($path && strlen(DI::config()->get('system', 'directory'))) {
- Worker::add(PRIORITY_LOW, "Directory", DI::baseUrl()->get() . '/' . $path);
- }
-
- Worker::add(PRIORITY_LOW, 'ProfileUpdate', local_user());
- } else {
- notice(DI::l10n()->t('Unable to process image') . EOL);
- }
- }
-
- DI::baseUrl()->redirect($path);
- return; // NOTREACHED
- }
-
- $src = $_FILES['userfile']['tmp_name'];
- $filename = basename($_FILES['userfile']['name']);
- $filesize = intval($_FILES['userfile']['size']);
- $filetype = $_FILES['userfile']['type'];
- if ($filetype == "") {
- $filetype = Image::guessType($filename);
- }
-
- $maximagesize = DI::config()->get('system', 'maximagesize');
-
- if (($maximagesize) && ($filesize > $maximagesize)) {
- notice(DI::l10n()->t('Image exceeds size limit of %s', Strings::formatBytes($maximagesize)) . EOL);
- @unlink($src);
- return;
- }
-
- $imagedata = @file_get_contents($src);
- $ph = new Image($imagedata, $filetype);
-
- if (!$ph->isValid()) {
- notice(DI::l10n()->t('Unable to process image.') . EOL);
- @unlink($src);
- return;
- }
-
- $ph->orient($src);
- @unlink($src);
-
- $imagecrop = profile_photo_crop_ui_head($ph);
- DI::baseUrl()->redirect('profile_photo/use/' . $imagecrop['hash']);
-}
-
-function profile_photo_content(App $a)
-{
-
- if (!local_user()) {
- notice(DI::l10n()->t('Permission denied.') . EOL);
- return;
- }
-
- $newuser = false;
-
- if ($a->argc == 2 && $a->argv[1] === 'new') {
- $newuser = true;
- }
-
- $imagecrop = [];
-
- if (isset($a->argv[1]) && $a->argv[1] == 'use' && $a->argc >= 3) {
- // BaseModule::checkFormSecurityTokenRedirectOnError('/profile_photo', 'profile_photo');
-
- $resource_id = $a->argv[2];
- //die(":".local_user());
-
- $r = Photo::selectToArray([], ["resource-id" => $resource_id, "uid" => local_user()], ["order" => ["scale" => false]]);
- if (!DBA::isResult($r)) {
- notice(DI::l10n()->t('Permission denied.') . EOL);
- return;
- }
-
- $havescale = false;
- foreach ($r as $rr) {
- if ($rr['scale'] == 5) {
- $havescale = true;
- }
- }
-
- // set an already uloaded photo as profile photo
- // if photo is in 'Profile Photos', change it in db
- if (($r[0]['album'] == DI::l10n()->t('Profile Photos')) && ($havescale)) {
- q("UPDATE `photo` SET `profile`=0 WHERE `profile`=1 AND `uid`=%d", intval(local_user()));
-
- q("UPDATE `photo` SET `profile`=1 WHERE `uid` = %d AND `resource-id` = '%s'", intval(local_user()),
- DBA::escape($resource_id)
- );
-
- Contact::updateSelfFromUserID(local_user(), true);
-
- // Update global directory in background
- $url = $_SESSION['my_url'];
- if ($url && strlen(DI::config()->get('system', 'directory'))) {
- Worker::add(PRIORITY_LOW, "Directory", $url);
- }
-
- DI::baseUrl()->redirect('profile/' . $a->user['nickname']);
- return; // NOTREACHED
- }
- $ph = Photo::getImageForPhoto($r[0]);
-
- $imagecrop = profile_photo_crop_ui_head($ph);
- // go ahead as we have jus uploaded a new photo to crop
- }
-
- $profiles = q("select `id`,`profile-name` as `name`,`is-default` as `default` from profile where uid = %d",
- intval(local_user())
- );
-
- if (empty($imagecrop)) {
- $tpl = Renderer::getMarkupTemplate('profile_photo.tpl');
-
- $o = Renderer::replaceMacros($tpl,
- [
- '$user' => $a->user['nickname'],
- '$lbl_upfile' => DI::l10n()->t('Upload File:'),
- '$lbl_profiles' => DI::l10n()->t('Select a profile:'),
- '$title' => DI::l10n()->t('Upload Profile Photo'),
- '$submit' => DI::l10n()->t('Upload'),
- '$profiles' => $profiles,
- '$form_security_token' => BaseModule::getFormSecurityToken("profile_photo"),
- '$select' => sprintf('%s %s', DI::l10n()->t('or'),
- ($newuser) ? '<a href="' . DI::baseUrl() . '">' . DI::l10n()->t('skip this step') . '</a>' : '<a href="' . DI::baseUrl() . '/photos/' . $a->user['nickname'] . '">' . DI::l10n()->t('select a photo from your photo albums') . '</a>')
- ]);
-
- return $o;
- } else {
- $filename = $imagecrop['hash'] . '-' . $imagecrop['resolution'] . '.' . $imagecrop['ext'];
- $tpl = Renderer::getMarkupTemplate("cropbody.tpl");
- $o = Renderer::replaceMacros($tpl,
- [
- '$filename' => $filename,
- '$profile' => (isset($_REQUEST['profile']) ? intval($_REQUEST['profile']) : 0),
- '$resource' => $imagecrop['hash'] . '-' . $imagecrop['resolution'],
- '$image_url' => DI::baseUrl() . '/photo/' . $filename,
- '$title' => DI::l10n()->t('Crop Image'),
- '$desc' => DI::l10n()->t('Please adjust the image cropping for optimum viewing.'),
- '$form_security_token' => BaseModule::getFormSecurityToken("profile_photo"),
- '$done' => DI::l10n()->t('Done Editing')
- ]);
- return $o;
- }
-}
-
-function profile_photo_crop_ui_head(Image $image)
-{
- $max_length = DI::config()->get('system', 'max_image_length');
- if (!$max_length) {
- $max_length = MAX_IMAGE_LENGTH;
- }
- if ($max_length > 0) {
- $image->scaleDown($max_length);
- }
-
- $width = $image->getWidth();
- $height = $image->getHeight();
-
- if ($width < 175 || $height < 175) {
- $image->scaleUp(300);
- $width = $image->getWidth();
- $height = $image->getHeight();
- }
-
- $hash = Photo::newResource();
-
-
- $smallest = 0;
- $filename = '';
-
- $r = Photo::store($image, local_user(), 0, $hash, $filename, DI::l10n()->t('Profile Photos'), 0);
-
- if ($r) {
- info(DI::l10n()->t('Image uploaded successfully.') . EOL);
- } else {
- notice(DI::l10n()->t('Image upload failed.') . EOL);
- }
-
- if ($width > 640 || $height > 640) {
- $image->scaleDown(640);
- $r = Photo::store($image, local_user(), 0, $hash, $filename, DI::l10n()->t('Profile Photos'), 1);
-
- if ($r === false) {
- notice(DI::l10n()->t('Image size reduction [%s] failed.', "640") . EOL);
- } else {
- $smallest = 1;
- }
- }
-
- DI::page()['htmlhead'] .= Renderer::replaceMacros(Renderer::getMarkupTemplate("crophead.tpl"), []);
-
- $imagecrop = [
- 'hash' => $hash,
- 'resolution' => $smallest,
- 'ext' => $image->getExt(),
- ];
-
- return $imagecrop;
-}
if ($user_record['login_date'] <= DBA::NULL_DATETIME) {
info($this->l10n->t('Welcome %s', $user_record['username']));
info($this->l10n->t('Please upload a profile photo.'));
- $this->baseUrl->redirect('profile_photo/new');
+ $this->baseUrl->redirect('settings/profile/photo/new');
} else {
info($this->l10n->t("Welcome back %s", $user_record['username']));
}
--- /dev/null
+<?php
+
+namespace Friendica\Module\Settings\Profile\Photo;
+
+use Friendica\Core\Renderer;
+use Friendica\Core\Session;
+use Friendica\Core\Worker;
+use Friendica\Database\DBA;
+use Friendica\DI;
+use Friendica\Model\Contact;
+use Friendica\Model\Photo;
+use Friendica\Module\BaseSettingsModule;
+use Friendica\Network\HTTPException;
+
+class Crop extends BaseSettingsModule
+{
+ public static function post(array $parameters = [])
+ {
+ if (!Session::isAuthenticated()) {
+ return;
+ }
+
+ $photo_prefix = $parameters['guid'];
+ $resource_id = $photo_prefix;
+ $scale = 0;
+ if (substr($photo_prefix, -2, 1) == '-') {
+ list($resource_id, $scale) = explode('-', $photo_prefix);
+ }
+
+ self::checkFormSecurityTokenRedirectOnError('settings/profile/photo/crop/' . $photo_prefix, 'settings_profile_photo_crop');
+
+ $action = $_POST['action'] ?? 'crop';
+
+ // Image selection origin is top left
+ $selectionX = intval($_POST['xstart'] ?? 0);
+ $selectionY = intval($_POST['ystart'] ?? 0);
+ $selectionW = intval($_POST['width'] ?? 0);
+ $selectionH = intval($_POST['height'] ?? 0);
+
+ $path = 'profile/' . DI::app()->user['nickname'];
+
+ $base_image = Photo::selectFirst([], ['resource-id' => $resource_id, 'uid' => local_user(), 'scale' => $scale]);
+ if (DBA::isResult($base_image)) {
+ $Image = Photo::getImageForPhoto($base_image);
+ if ($Image->isValid()) {
+ // If setting for the default profile, unset the profile photo flag from any other photos I own
+ DBA::update('photo', ['profile' => 0], ['uid' => local_user()]);
+
+ // Normalizing expected square crop parameters
+ $selectionW = $selectionH = min($selectionW, $selectionH);
+
+ $imageIsSquare = $Image->getWidth() === $Image->getHeight();
+ $selectionIsFullImage = $selectionX === 0 && $selectionY === 0 && $selectionW === $Image->getWidth() && $selectionH === $Image->getHeight();
+
+ // Bypassed UI with a rectangle image, we force a square cropped image
+ if (!$imageIsSquare && $action == 'skip') {
+ $selectionX = $selectionY = 0;
+ $selectionW = $selectionH = min($Image->getWidth(), $Image->getHeight());
+ $action = 'crop';
+ }
+
+ // Selective crop if it was asked and the selection isn't the full image
+ if ($action == 'crop'
+ && !($imageIsSquare && !$selectionIsFullImage)
+ ) {
+ $Image->crop(300, $selectionX, $selectionY, $selectionW, $selectionH);
+ $resource_id = Photo::newResource();
+ } else {
+ $Image->scaleDown(300);
+ }
+
+ $r = Photo::store(
+ $Image,
+ local_user(),
+ 0,
+ $resource_id,
+ $base_image['filename'],
+ DI::l10n()->t('Profile Photos'),
+ 4,
+ 1
+ );
+ if ($r === false) {
+ notice(DI::l10n()->t('Image size reduction [%s] failed.', '300'));
+ }
+
+ $Image->scaleDown(80);
+
+ $r = Photo::store(
+ $Image,
+ local_user(),
+ 0,
+ $resource_id,
+ $base_image['filename'],
+ DI::l10n()->t('Profile Photos'),
+ 5,
+ 1
+ );
+ if ($r === false) {
+ notice(DI::l10n()->t('Image size reduction [%s] failed.', '80'));
+ }
+
+ $Image->scaleDown(48);
+
+ $r = Photo::store(
+ $Image,
+ local_user(),
+ 0,
+ $resource_id,
+ $base_image['filename'],
+ DI::l10n()->t('Profile Photos'),
+ 6,
+ 1
+ );
+ if ($r === false) {
+ notice(DI::l10n()->t('Image size reduction [%s] failed.', '48'));
+ }
+
+ Contact::updateSelfFromUserID(local_user(), true);
+
+ info(DI::l10n()->t('Shift-reload the page or clear browser cache if the new photo does not display immediately.'));
+ // Update global directory in background
+ if ($path && strlen(DI::config()->get('system', 'directory'))) {
+ Worker::add(PRIORITY_LOW, 'Directory', DI::baseUrl()->get() . '/' . $path);
+ }
+
+ Worker::add(PRIORITY_LOW, 'ProfileUpdate', local_user());
+ } else {
+ notice(DI::l10n()->t('Unable to process image'));
+ }
+ }
+
+ DI::baseUrl()->redirect($path);
+ }
+
+ public static function content(array $parameters = [])
+ {
+ if (!Session::isAuthenticated()) {
+ throw new HTTPException\ForbiddenException(DI::l10n()->t('Permission denied.'));
+ }
+
+ parent::content();
+
+ $resource_id = $parameters['guid'];
+
+ $photos = Photo::selectToArray([], ['resource-id' => $resource_id, 'uid' => local_user()], ['order' => ['scale' => false]]);
+ if (!DBA::isResult($photos)) {
+ throw new HTTPException\NotFoundException(DI::l10n()->t('Photo not found.'));
+ }
+
+ $havescale = false;
+ $smallest = 0;
+ foreach ($photos as $photo) {
+ $smallest = $photo['scale'] == 1 ? 1 : $smallest;
+ $havescale = $havescale || $photo['scale'] == 5;
+ }
+
+ // set an already uloaded photo as profile photo
+ // if photo is in 'Profile Photos', change it in db
+ if ($photos[0]['album'] == DI::l10n()->t('Profile Photos') && $havescale) {
+ Photo::update(['profile' => false], ['uid' => local_user()]);
+
+ Photo::update(['profile' => true], ['resource-id' => $resource_id, 'uid' => local_user()]);
+
+ Contact::updateSelfFromUserID(local_user(), true);
+
+ // Update global directory in background
+ if (Session::get('my_url') && strlen(DI::config()->get('system', 'directory'))) {
+ Worker::add(PRIORITY_LOW, 'Directory', Session::get('my_url'));
+ }
+
+ notice(DI::l10n()->t('Profile picture successfully updated.'));
+
+ DI::baseUrl()->redirect('profile/' . DI::app()->user['nickname']);
+ }
+
+ $Image = Photo::getImageForPhoto($photos[0]);
+
+ $imagecrop = [
+ 'resource-id' => $resource_id,
+ 'scale' => $smallest,
+ 'ext' => $Image->getExt(),
+ ];
+
+ $isSquare = $Image->getWidth() === $Image->getHeight();
+
+ DI::page()['htmlhead'] .= Renderer::replaceMacros(Renderer::getMarkupTemplate('settings/profile/photo/crop_head.tpl'), []);
+
+ $filename = $imagecrop['resource-id'] . '-' . $imagecrop['scale'] . '.' . $imagecrop['ext'];
+ $tpl = Renderer::getMarkupTemplate('settings/profile/photo/crop.tpl');
+ $o = Renderer::replaceMacros($tpl, [
+ '$filename' => $filename,
+ '$resource' => $imagecrop['resource-id'] . '-' . $imagecrop['scale'],
+ '$image_url' => DI::baseUrl() . '/photo/' . $filename,
+ '$title' => DI::l10n()->t('Crop Image'),
+ '$desc' => DI::l10n()->t('Please adjust the image cropping for optimum viewing.'),
+ '$form_security_token' => self::getFormSecurityToken('settings_profile_photo_crop'),
+ '$skip' => $isSquare ? DI::l10n()->t('Use Image As Is') : '',
+ '$crop' => DI::l10n()->t('Crop Image'),
+ ]);
+
+ return $o;
+ }
+}
--- /dev/null
+<?php
+
+namespace Friendica\Module\Settings\Profile\Photo;
+
+use Friendica\App\Arguments;
+use Friendica\Core\Renderer;
+use Friendica\Core\Session;
+use Friendica\DI;
+use Friendica\Model\Contact;
+use Friendica\Model\Photo;
+use Friendica\Module\BaseSettingsModule;
+use Friendica\Network\HTTPException;
+use Friendica\Object\Image;
+use Friendica\Util\Images;
+use Friendica\Util\Strings;
+
+class Index extends BaseSettingsModule
+{
+ public static function post(array $parameters = [])
+ {
+ if (!Session::isAuthenticated()) {
+ return;
+ }
+
+ self::checkFormSecurityTokenRedirectOnError('/settings/profile/photo', 'settings_profile_photo');
+
+ if (empty($_FILES['userfile'])) {
+ notice(DI::l10n()->t('Missing uploaded image.'));
+ return;
+ }
+
+ $src = $_FILES['userfile']['tmp_name'];
+ $filename = basename($_FILES['userfile']['name']);
+ $filesize = intval($_FILES['userfile']['size']);
+ $filetype = $_FILES['userfile']['type'];
+ if ($filetype == '') {
+ $filetype = Images::guessType($filename);
+ }
+
+ $maximagesize = DI::config()->get('system', 'maximagesize', 0);
+
+ if ($maximagesize && $filesize > $maximagesize) {
+ notice(DI::l10n()->t('Image exceeds size limit of %s', Strings::formatBytes($maximagesize)));
+ @unlink($src);
+ return;
+ }
+
+ $imagedata = @file_get_contents($src);
+ $Image = new Image($imagedata, $filetype);
+
+ if (!$Image->isValid()) {
+ notice(DI::l10n()->t('Unable to process image.'));
+ @unlink($src);
+ return;
+ }
+
+ $Image->orient($src);
+ @unlink($src);
+
+ $max_length = DI::config()->get('system', 'max_image_length', 0);
+ if ($max_length > 0) {
+ $Image->scaleDown($max_length);
+ }
+
+ $width = $Image->getWidth();
+ $height = $Image->getHeight();
+
+ if ($width < 175 || $height < 175) {
+ $Image->scaleUp(300);
+ $width = $Image->getWidth();
+ $height = $Image->getHeight();
+ }
+
+ $resource_id = Photo::newResource();
+
+ $filename = '';
+
+ if (Photo::store($Image, local_user(), 0, $resource_id, $filename, DI::l10n()->t('Profile Photos'), 0)) {
+ info(DI::l10n()->t('Image uploaded successfully.'));
+ } else {
+ notice(DI::l10n()->t('Image upload failed.'));
+ }
+
+ if ($width > 640 || $height > 640) {
+ $Image->scaleDown(640);
+ if (!Photo::store($Image, local_user(), 0, $resource_id, $filename, DI::l10n()->t('Profile Photos'), 1)) {
+ notice(DI::l10n()->t('Image size reduction [%s] failed.', '640'));
+ }
+ }
+
+ DI::baseUrl()->redirect('settings/profile/photo/crop/' . $resource_id);
+ }
+
+ public static function content(array $parameters = [])
+ {
+ if (!Session::isAuthenticated()) {
+ throw new HTTPException\ForbiddenException(DI::l10n()->t('Permission denied.'));
+ }
+
+ parent::content();
+
+ /** @var Arguments $args */
+ $args = DI::args();
+
+ $newuser = $args->get($args->getArgc() - 1) === 'new';
+
+ $contact = Contact::selectFirst(['avatar'], ['uid' => local_user(), 'self' => true]);
+
+ $tpl = Renderer::getMarkupTemplate('settings/profile/photo/index.tpl');
+ $o = Renderer::replaceMacros($tpl, [
+ '$title' => DI::l10n()->t('Profile Picture Settings'),
+ '$current_picture' => DI::l10n()->t('Current Profile Picture'),
+ '$upload_picture' => DI::l10n()->t('Upload Profile Picture'),
+ '$lbl_upfile' => DI::l10n()->t('Upload Picture:'),
+ '$submit' => DI::l10n()->t('Upload'),
+ '$avatar' => $contact['avatar'],
+ '$form_security_token' => self::getFormSecurityToken('settings_profile_photo'),
+ '$select' => sprintf('%s %s',
+ DI::l10n()->t('or'),
+ ($newuser) ?
+ '<a href="' . DI::baseUrl() . '">' . DI::l10n()->t('skip this step') . '</a>'
+ : '<a href="' . DI::baseUrl() . '/photos/' . DI::app()->user['nickname'] . '">'
+ . DI::l10n()->t('select a photo from your photo albums') . '</a>'
+ ),
+ ]);
+
+ return $o;
+ }
+}
'/verify' => [Module\Settings\TwoFactor\Verify::class, [R::GET, R::POST]],
],
'/delegation[/{action}/{user_id}]' => [Module\Settings\Delegation::class, [R::GET, R::POST]],
+ '/profile' => [
+ '/photo[/new]' => [Module\Settings\Profile\Photo\Index::class, [R::GET, R::POST]],
+ '/photo/crop/{guid}' => [Module\Settings\Profile\Photo\Crop::class, [R::GET, R::POST]],
+ ],
'/userexport[/{action}]' => [Module\Settings\UserExport::class, [R::GET, R::POST]],
],
+++ /dev/null
-<h1>{{$title}}</h1>
-<p id="cropimage-desc">
- {{$desc nofilter}}
-</p>
-
-<div id="cropimage-wrapper">
- <img src="{{$image_url}}" id="croppa" class="imgCrop" alt="{{$title}}" />
-</div>
-
-<div id="cropimage-preview-wrapper" >
- <div id="previewWrap" class="crop-preview"></div>
-</div>
-
-<script type="text/javascript" language="javascript">
-
- var image = document.getElementById('croppa');
- var cropper = new Cropper(image, {
- aspectRatio: 1 / 1,
- viewMode: 1,
- preview: '#profile-photo-wrapper, .crop-preview',
- crop: function(e) {
- $( '#x1' ).val(e.detail.x);
- $( '#y1' ).val(e.detail.y);
- $( '#x2' ).val(e.detail.x + e.detail.width);
- $( '#y2' ).val(e.detail.y + e.detail.height);
- $( '#width' ).val(e.detail.scaleX);
- $( '#height' ).val(e.detail.scaleY);
- },
- ready: function() {
- // Add the "crop-preview" class to the preview element ("profile-photo-wrapper").
- var cwrapper = document.getElementById("profile-photo-wrapper");
- cwrapper.classList.add("crop-preview");
- }
- });
-
-</script>
-
-<form action="profile_photo/{{$resource}}" id="crop-image-form" method="post" />
- <input type='hidden' name='form_security_token' value='{{$form_security_token}}'>
-
- <input type='hidden' name='profile' value='{{$profile}}'>
- <input type="hidden" name="cropfinal" value="1" />
- <input type="hidden" name="xstart" id="x1" />
- <input type="hidden" name="ystart" id="y1" />
- <input type="hidden" name="xfinal" id="x2" />
- <input type="hidden" name="yfinal" id="y2" />
- <input type="hidden" name="height" id="height" />
- <input type="hidden" name="width" id="width" />
-
- <div id="crop-image-submit-wrapper" >
- <input type="submit" name="submit" value="{{$done}}" />
- </div>
-
-</form>
+++ /dev/null
-<script type="text/javascript" src="view/asset/cropperjs/dist/cropper.min.js"></script>
-<link rel="stylesheet" href="view/asset/cropperjs/dist/cropper.min.css" type="text/css" />
+++ /dev/null
-
-<h1>{{$title}}</h1>
-
-<form enctype="multipart/form-data" action="profile_photo" method="post">
-<input type='hidden' name='form_security_token' value='{{$form_security_token}}'>
-
-<div id="profile-photo-upload-wrapper">
-<label id="profile-photo-upload-label" for="profile-photo-upload">{{$lbl_upfile}} </label>
-<input name="userfile" type="file" id="profile-photo-upload" size="48" />
-</div>
-
-<label id="profile-photo-profiles-label" for="profile-photo-profiles">{{$lbl_profiles}} </label>
-<select name="profile" id="profile-photo-profiles" />
-{{foreach $profiles as $p}}
-<option value="{{$p.id}}" {{if $p.default}}selected="selected"{{/if}}>{{$p.name}}</option>
-{{/foreach}}
-</select>
-
-<div id="profile-photo-submit-wrapper">
-<input type="submit" name="submit" id="profile-photo-submit" value="{{$submit}}">
-</div>
-
-</form>
-
-<div id="profile-photo-link-select-wrapper">
-{{$select nofilter}}
-</div>
\ No newline at end of file
--- /dev/null
+<div class="generic-page-wrapper">
+ <h1>{{$title}}</h1>
+ <p id="cropimage-desc">
+ {{$desc nofilter}}
+ </p>
+
+ <div id="cropimage-wrapper">
+ <p><img src="{{$image_url}}" id="croppa" class="imgCrop" alt="{{$title}}"></p>
+ </div>
+
+ <div id="cropimage-preview-wrapper" >
+ <div id="previewWrap" class="crop-preview"></div>
+ </div>
+
+ <form action="settings/profile/photo/crop/{{$resource}}" id="crop-image-form" method="post">
+ <input type="hidden" name="form_security_token" value="{{$form_security_token}}">
+
+ <input type="hidden" name="xstart" id="x1" />
+ <input type="hidden" name="ystart" id="y1" />
+ <input type="hidden" name="height" id="height" />
+ <input type="hidden" name="width" id="width" />
+
+ <div id="settings-profile-photo-crop-submit-wrapper" class="pull-right settings-submit-wrapper">
+ {{if $skip}}
+ <button type="submit" name="action" id="settings-profile-photo-crop-skip" class="btn" value="skip">{{$skip}}</button>
+ {{/if}}
+ <button type="submit" name="action" id="settings-profile-photo-crop-submit" class="btn btn-primary" value="crop">{{$crop}}</button>
+ </div>
+
+ <div class="clear"></div>
+ </form>
+
+ <script type="text/javascript" language="javascript">
+
+ var image = document.getElementById('croppa');
+ var cropper = new Cropper(image, {
+ aspectRatio: 1,
+ viewMode: 1,
+ preview: '#profile-photo-wrapper, .crop-preview',
+ crop: function(e) {
+ $('#x1').val(e.detail.x);
+ $('#y1').val(e.detail.y);
+ $('#width').val(e.detail.width);
+ $('#height').val(e.detail.height);
+ },
+ });
+
+ var skip_button = document.getElementById('settings-profile-photo-crop-skip');
+
+ skip_button.addEventListener('click', function() {
+ let image_data = cropper.getImageData();
+ cropper.setData({x: 0, y: 0, width: image_data.width, height: image_data.height});
+ })
+ </script>
+</div>
--- /dev/null
+<script type="text/javascript" src="view/asset/cropperjs/dist/cropper.min.js"></script>
+<link rel="stylesheet" href="view/asset/cropperjs/dist/cropper.min.css" type="text/css" />
--- /dev/null
+<div class="generic-page-wrapper">
+ <h1>{{$title}}</h1>
+
+ <h2>{{$current_picture}}</h2>
+ <p><img src="{{$avatar}}" alt="{{$current_picture}}"/></p>
+ <h2>{{$upload_picture}}</h2>
+ <form enctype="multipart/form-data" action="settings/profile/photo" method="post">
+ <input type="hidden" name="form_security_token" value="{{$form_security_token}}">
+
+ <div id="profile-photo-upload-wrapper" class="form-group field input">
+ <label id="profile-photo-upload-label" for="profile-photo-upload">{{$lbl_upfile}} </label>
+ <input class="form-control" name="userfile" type="file" id="profile-photo-upload" size="48">
+ <div class="clear"></div>
+ </div>
+
+ <div id="profile-photo-submit-wrapper" class="pull-right settings-submit-wrapper">
+ <button type="submit" name="submit" id="profile-photo-submit" class="btn btn-primary" value="{{$submit}}">{{$submit}}</button>
+ </div>
+ <div class="clear"></div>
+ </form>
+
+ <p id="profile-photo-link-select-wrapper">
+ {{$select nofilter}}
+ </p>
+</div>
\ No newline at end of file
<h4>{{$profile nofilter}}</h4>
<ul>
<li>
- <a target="newmember" href="profile_photo">{{$profile_photo_link}}</a><br />
+ <a target="newmember" href="settings/profile/photo">{{$profile_photo_link}}</a><br />
{{$profile_photo_txt nofilter}}
</li>
<li>
* PAGES
*********/
-.generic-page-wrapper, .profile_photo-content-wrapper, .videos-content-wrapper,
+.generic-page-wrapper, .videos-content-wrapper,
.suggest-content-wrapper, .common-content-wrapper, .help-content-wrapper,
.allfriends-content-wrapper, .match-content-wrapper, .dirfind-content-wrapper,
.delegation-content-wrapper, .notes-content-wrapper,
#profile-listing-new-link-wrapper {
margin-bottom: 20px;
}
-.panel-group-settings {
- margin-left: -15px;
- margin-right: -15px;
-}
+
.panel-group-settings > .panel,
.panel-group-settings > form > .panel {
- padding-left: 15px;
- padding-right: 15px;
+ padding-left: 10px;
+ padding-right: 10px;
}
-.profiles-content-wrapper #profile-photo-upload-section {
+#profile-photo-upload-section {
display: none;
- margin-left: -15px;
- margin-right: -15px;
- margin-top: 15px;
- padding: 15px;
+ padding: 10px;
}
#profile-photo-upload-close {
font-size: 14px;
right: 10px;
}
- .generic-page-wrapper, .profile_photo-content-wrapper, .videos-content-wrapper, .suggest-content-wrapper, .common-content-wrapper, .help-content-wrapper, .allfriends-content-wrapper, .match-content-wrapper, .dirfind-content-wrapper, .directory-content-wrapper, .delegation-content-wrapper, .notes-content-wrapper, .message-content-wrapper, .apps-content-wrapper, #adminpage, .delegate-content-wrapper, .uexport-content-wrapper, .dfrn_request-content-wrapper, .friendica-content-wrapper, .credits-content-wrapper, .nogroup-content-wrapper, .profperm-content-wrapper, .invite-content-wrapper, .tos-content-wrapper, .fsuggest-content-wrapper {
+ .generic-page-wrapper, .videos-content-wrapper, .suggest-content-wrapper, .common-content-wrapper, .help-content-wrapper, .allfriends-content-wrapper, .match-content-wrapper, .dirfind-content-wrapper, .directory-content-wrapper, .delegation-content-wrapper, .notes-content-wrapper, .message-content-wrapper, .apps-content-wrapper, #adminpage, .delegate-content-wrapper, .uexport-content-wrapper, .dfrn_request-content-wrapper, .friendica-content-wrapper, .credits-content-wrapper, .nogroup-content-wrapper, .profperm-content-wrapper, .invite-content-wrapper, .tos-content-wrapper, .fsuggest-content-wrapper {
border-radius: 0;
padding: 10px;
}