]> git.mxchange.org Git - friendica.git/commitdiff
Move /profile_photo to Module\Settings\Profile\Photo
authorHypolite Petovan <hypolite@mrpetovan.com>
Sun, 27 Oct 2019 13:56:27 +0000 (09:56 -0400)
committerHypolite Petovan <hypolite@mrpetovan.com>
Mon, 20 Jan 2020 12:27:12 +0000 (07:27 -0500)
14 files changed:
mod/photos.php
mod/profile_photo.php [deleted file]
src/App/Authentication.php
src/Module/Settings/Profile/Photo/Crop.php [new file with mode: 0644]
src/Module/Settings/Profile/Photo/Index.php [new file with mode: 0644]
static/routes.config.php
view/templates/cropbody.tpl [deleted file]
view/templates/crophead.tpl [deleted file]
view/templates/profile_photo.tpl [deleted file]
view/templates/settings/profile/photo/crop.tpl [new file with mode: 0644]
view/templates/settings/profile/photo/crop_head.tpl [new file with mode: 0644]
view/templates/settings/profile/photo/index.tpl [new file with mode: 0644]
view/templates/welcome.tpl
view/theme/frio/css/style.css

index c2fb8256968193ea9ecd95ad20523578043ae5a7..5b8d22b655fa7ec8fd9103f5b5045643ac77ecb8 100644 (file)
@@ -1236,7 +1236,7 @@ function photos_content(App $a)
                        } 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 (
diff --git a/mod/profile_photo.php b/mod/profile_photo.php
deleted file mode 100644 (file)
index d34c783..0000000
+++ /dev/null
@@ -1,324 +0,0 @@
-<?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;
-}
index c0408a8111e19deeac91bc1207e5cba599675370..2e1a823c71d2e9fb60b6fd282248ee563db4cab8 100644 (file)
@@ -373,7 +373,7 @@ class Authentication
                        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']));
                        }
diff --git a/src/Module/Settings/Profile/Photo/Crop.php b/src/Module/Settings/Profile/Photo/Crop.php
new file mode 100644 (file)
index 0000000..738e3fc
--- /dev/null
@@ -0,0 +1,203 @@
+<?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;
+       }
+}
diff --git a/src/Module/Settings/Profile/Photo/Index.php b/src/Module/Settings/Profile/Photo/Index.php
new file mode 100644 (file)
index 0000000..9cb5644
--- /dev/null
@@ -0,0 +1,129 @@
+<?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;
+       }
+}
index 115b8f5f6deb6ae980d018510b2a3271e07b568a..05f2599561a90ed777aa9d672f85937d1b236ad5 100644 (file)
@@ -228,6 +228,10 @@ return [
                        '/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]],
        ],
 
diff --git a/view/templates/cropbody.tpl b/view/templates/cropbody.tpl
deleted file mode 100644 (file)
index 8378e50..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-<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>
diff --git a/view/templates/crophead.tpl b/view/templates/crophead.tpl
deleted file mode 100644 (file)
index 3fd1579..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-<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" />
diff --git a/view/templates/profile_photo.tpl b/view/templates/profile_photo.tpl
deleted file mode 100644 (file)
index e7c6b89..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-
-<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
diff --git a/view/templates/settings/profile/photo/crop.tpl b/view/templates/settings/profile/photo/crop.tpl
new file mode 100644 (file)
index 0000000..679c9d1
--- /dev/null
@@ -0,0 +1,55 @@
+<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>
diff --git a/view/templates/settings/profile/photo/crop_head.tpl b/view/templates/settings/profile/photo/crop_head.tpl
new file mode 100644 (file)
index 0000000..3fd1579
--- /dev/null
@@ -0,0 +1,2 @@
+<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" />
diff --git a/view/templates/settings/profile/photo/index.tpl b/view/templates/settings/profile/photo/index.tpl
new file mode 100644 (file)
index 0000000..a819e11
--- /dev/null
@@ -0,0 +1,25 @@
+<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
index 9f343efbbbc5a4c5bb5298e01c4b40aa1de718c0..4e0ae7754d6d30d247f31758254e634fccad0111 100644 (file)
@@ -22,7 +22,7 @@
                <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>
index 94f0edfd7a324c465c091d9971499289ab64dca5..fd99a75fad7032a4d58153ba0861f11c6cf5a223 100644 (file)
@@ -2288,7 +2288,7 @@ ul.dropdown-menu li:hover {
  * 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,
@@ -2850,21 +2850,15 @@ ul li:hover .contact-wrapper .contact-action-link:hover {
 #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;
@@ -3537,7 +3531,7 @@ section .profile-match-wrapper {
                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;
        }