X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FModule%2FPhoto.php;h=bedc216fb20ab827d61568385c0e5e1721e38cf2;hb=fa14a02a192efdd061e5184585395a46968855e7;hp=3d3110fd8b702fa2458c6c1a2ff61fc775b68637;hpb=7dadc7f6dc0b1e68bfa5937b3a3fa3fd9cdcacd1;p=friendica.git diff --git a/src/Module/Photo.php b/src/Module/Photo.php index 3d3110fd8b..bedc216fb2 100644 --- a/src/Module/Photo.php +++ b/src/Module/Photo.php @@ -23,6 +23,7 @@ namespace Friendica\Module; use Friendica\BaseModule; use Friendica\Core\Logger; +use Friendica\Core\Protocol; use Friendica\Database\DBA; use Friendica\DI; use Friendica\Model\Contact; @@ -31,7 +32,11 @@ use Friendica\Model\Post; use Friendica\Model\Profile; use Friendica\Core\Storage\Type\ExternalResource; use Friendica\Core\Storage\Type\SystemResource; +use Friendica\Core\System; +use Friendica\Core\Worker; use Friendica\Model\User; +use Friendica\Network\HTTPClient\Client\HttpClientAccept; +use Friendica\Network\HTTPClient\Client\HttpClientOptions; use Friendica\Network\HTTPException; use Friendica\Network\HTTPException\NotModifiedException; use Friendica\Object\Image; @@ -123,7 +128,7 @@ class Photo extends BaseModule throw new HTTPException\NotFoundException(DI::l10n()->t('The Photo is not available.')); } - $photo = self::getPhotoByid($id, $this->parameters['type'], $customsize ?: Proxy::PIXEL_SMALL); + $photo = self::getPhotoById($id, $this->parameters['type'], $customsize ?: Proxy::PIXEL_SMALL); } else { $photoid = pathinfo($this->parameters['name'], PATHINFO_FILENAME); $scale = 0; @@ -220,13 +225,21 @@ class Photo extends BaseModule 'output' => number_format($output, 3), 'rest' => number_format($rest, 3)]); } - exit(); + System::exit(); } - private static function getPhotoByid(int $id, $type, $customsize) + /** + * Fetches photo record by given id number, type and custom size + * + * @param int $id Photo id + * @param string $type Photo type + * @param int $customsize Custom size (?) + * @return array|bool Array on success, false on error + */ + private static function getPhotoById(int $id, string $type, int $customsize) { switch($type) { - case "preview": + case 'preview': $media = DBA::selectFirst('post-media', ['preview', 'url', 'mimetype', 'type', 'uri-id'], ['id' => $id]); if (empty($media)) { return false; @@ -246,7 +259,7 @@ class Photo extends BaseModule } return MPhoto::createPhotoForExternalResource($url, (int)local_user(), $media['mimetype']); - case "media": + case 'media': $media = DBA::selectFirst('post-media', ['url', 'mimetype', 'uri-id'], ['id' => $id, 'type' => Post\Media::IMAGE]); if (empty($media)) { return false; @@ -257,22 +270,23 @@ class Photo extends BaseModule } return MPhoto::createPhotoForExternalResource($media['url'], (int)local_user(), $media['mimetype']); - case "link": + case 'link': $link = DBA::selectFirst('post-link', ['url', 'mimetype'], ['id' => $id]); if (empty($link)) { return false; } return MPhoto::createPhotoForExternalResource($link['url'], (int)local_user(), $link['mimetype']); - case "contact": - $contact = Contact::getById($id, ['uid', 'url', 'nurl', 'avatar', 'photo', 'xmpp', 'addr']); + case 'contact': + $fields = ['uid', 'uri-id', 'url', 'nurl', 'avatar', 'photo', 'xmpp', 'addr', 'network', 'failed', 'updated']; + $contact = Contact::getById($id, $fields); if (empty($contact)) { return false; } // For local users directly use the photo record that is marked as the profile if (Network::isLocalLink($contact['url'])) { - $contact = Contact::selectFirst(['uid', 'url', 'avatar', 'photo', 'xmpp', 'addr'], ['nurl' => $contact['nurl'], 'self' => true]); + $contact = Contact::selectFirst($fields, ['nurl' => $contact['nurl'], 'self' => true]); if (!empty($contact)) { if ($customsize <= Proxy::PIXEL_MICRO) { $scale = 6; @@ -281,7 +295,7 @@ class Photo extends BaseModule } else { $scale = 4; } - $photo = MPhoto::selectFirst([], ["scale" => $scale, "uid" => $contact['uid'], "profile" => 1]); + $photo = MPhoto::selectFirst([], ['scale' => $scale, 'uid' => $contact['uid'], 'profile' => 1]); if (!empty($photo)) { return $photo; } @@ -289,7 +303,7 @@ class Photo extends BaseModule } if (!empty($contact['uid']) && empty($contact['photo']) && empty($contact['avatar'])) { - $contact = Contact::getByURL($contact['url'], false, ['avatar', 'photo', 'xmpp', 'addr']); + $contact = Contact::getByURL($contact['url'], false, $fields); } if (!empty($contact['photo']) && !empty($contact['avatar'])) { @@ -299,24 +313,41 @@ class Photo extends BaseModule $photo = MPhoto::selectFirst([], ['resource-id' => $resourceid], ['order' => ['scale']]); if (!empty($photo)) { return $photo; + } else { + $url = $contact['avatar']; } + } else { + $url = $contact['photo']; } - // We continue with the avatar link when the photo link is invalid - $url = $contact['avatar']; } elseif (!empty($contact['avatar'])) { $url = $contact['avatar']; } $mimetext = ''; if (!empty($url)) { - $mime = ParseUrl::getContentType($url); + $mime = ParseUrl::getContentType($url, HttpClientAccept::IMAGE); if (!empty($mime)) { $mimetext = $mime[0] . '/' . $mime[1]; } else { - Logger::info('Invalid file', ['url' => $url]); + // Only update federated accounts that hadn't failed before and hadn't been updated recently + $update = in_array($contact['network'], Protocol::FEDERATED) && !$contact['failed'] + && ((time() - strtotime($contact['updated']) > 86400)); + if ($update) { + $curlResult = DI::httpClient()->head($url, [HttpClientOptions::ACCEPT_CONTENT => HttpClientAccept::IMAGE]); + $update = !$curlResult->isSuccess() && ($curlResult->getReturnCode() == 404); + Logger::debug('Got return code for avatar', ['return code' => $curlResult->getReturnCode(), 'cid' => $id, 'url' => $contact['url'], 'avatar' => $url]); + } + if ($update) { + Logger::info('Invalid file, contact update initiated', ['cid' => $id, 'url' => $contact['url'], 'avatar' => $url]); + Worker::add(PRIORITY_LOW, 'UpdateContact', $id); + } else { + Logger::info('Invalid file', ['cid' => $id, 'url' => $contact['url'], 'avatar' => $url]); + } } if (!empty($mimetext) && ($mime[0] != 'image') && ($mimetext != 'application/octet-stream')) { Logger::info('Unexpected Content-Type', ['mime' => $mimetext, 'url' => $url]); $mimetext = ''; + } if (!empty($mimetext)) { + Logger::debug('Expected Content-Type', ['mime' => $mimetext, 'url' => $url]); } } if (empty($mimetext)) { @@ -329,7 +360,7 @@ class Photo extends BaseModule } } return MPhoto::createPhotoForExternalResource($url, 0, $mimetext); - case "header": + case 'header': $fields = ['uid', 'url', 'header', 'network', 'gsid']; $contact = Contact::getById($id, $fields); if (empty($contact)) { @@ -344,37 +375,37 @@ class Photo extends BaseModule $url = Contact::getDefaultHeader($contact); } return MPhoto::createPhotoForExternalResource($url); - case "banner": - $photo = MPhoto::selectFirst([], ["scale" => 3, 'uid' => $id, 'photo-type' => MPhoto::USER_BANNER]); + case 'banner': + $photo = MPhoto::selectFirst([], ['scale' => 3, 'uid' => $id, 'photo-type' => MPhoto::USER_BANNER]); if (!empty($photo)) { return $photo; } return MPhoto::createPhotoForExternalResource(DI::baseUrl() . '/images/friendica-banner.jpg'); - case "profile": - case "custom": + case 'profile': + case 'custom': $scale = 4; break; - case "micro": + case 'micro': $scale = 6; break; - case "avatar": + case 'avatar': default: $scale = 5; } - $photo = MPhoto::selectFirst([], ["scale" => $scale, "uid" => $id, "profile" => 1]); + $photo = MPhoto::selectFirst([], ['scale' => $scale, 'uid' => $id, 'profile' => 1]); if (empty($photo)) { $contact = DBA::selectFirst('contact', [], ['uid' => $id, 'self' => true]) ?: []; switch($type) { - case "profile": - case "custom": + case 'profile': + case 'custom': $default = Contact::getDefaultAvatar($contact, Proxy::SIZE_SMALL); break; - case "micro": + case 'micro': $default = Contact::getDefaultAvatar($contact, Proxy::SIZE_MICRO); break; - case "avatar": + case 'avatar': default: $default = Contact::getDefaultAvatar($contact, Proxy::SIZE_THUMB); }