use Friendica\Database\DBStructure;
use Friendica\DI;
use Friendica\Model\Storage\ExternalResource;
+use Friendica\Model\Storage\InvalidClassStorageException;
+use Friendica\Model\Storage\ReferenceStorageException;
+use Friendica\Model\Storage\StorageException;
use Friendica\Model\Storage\SystemResource;
use Friendica\Object\Image;
use Friendica\Util\DateTimeFormat;
* @param array $photo Photo data. Needs at least 'id', 'type', 'backend-class', 'backend-ref'
*
* @return \Friendica\Object\Image
- * @throws \Friendica\Network\HTTPException\InternalServerErrorException
- * @throws \ImagickException
*/
public static function getImageDataForPhoto(array $photo)
{
return $photo['data'];
}
- $backendClass = DI::storageManager()->getByName($photo['backend-class'] ?? '');
- if (empty($backendClass)) {
- // legacy data storage in "data" column
- $i = self::selectFirst(['data'], ['id' => $photo['id']]);
- if ($i === false) {
- return null;
+ try {
+ $backendClass = DI::storageManager()->getByName($photo['backend-class'] ?? '');
+ /// @todo refactoring this returning, because the storage returns a "string" which is casted in different ways - a check "instanceof Image" will fail!
+ return $backendClass->get($photo['backend-ref'] ?? '');
+ } catch (InvalidClassStorageException $storageException) {
+ try {
+ // legacy data storage in "data" column
+ $i = self::selectFirst(['data'], ['id' => $photo['id']]);
+ if ($i !== false) {
+ return $i['data'];
+ } else {
+ DI::logger()->info('Stored legacy data is empty', ['photo' => $photo]);
+ }
+ } catch (\Exception $exception) {
+ DI::logger()->info('Unexpected database exception', ['photo' => $photo, 'exception' => $exception]);
}
- $data = $i['data'];
- } else {
- $backendRef = $photo['backend-ref'] ?? '';
- $data = $backendClass->get($backendRef);
+ } catch (ReferenceStorageException $referenceStorageException) {
+ DI::logger()->debug('Invalid reference for photo', ['photo' => $photo, 'exception' => $referenceStorageException]);
+ } catch (StorageException $storageException) {
+ DI::logger()->info('Unexpected storage exception', ['photo' => $photo, 'exception' => $storageException]);
+ } catch (\ImagickException $imagickException) {
+ DI::logger()->info('Unexpected imagick exception', ['photo' => $photo, 'exception' => $imagickException]);
}
- return $data;
+
+ return null;
}
/**
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
* @throws \ImagickException
*/
- public static function getImageForPhoto(array $photo)
+ public static function getImageForPhoto(array $photo): Image
{
- $data = self::getImageDataForPhoto($photo);
- if (empty($data)) {
- return null;
- }
-
- return new Image($data, $photo['type']);
+ return new Image(self::getImageDataForPhoto($photo), $photo['type']);
}
/**
// Get defined storage backend.
// if no storage backend, we use old "data" column in photo table.
// if is an existing photo, reuse same backend
- $data = "";
+ $data = "";
$backend_ref = "";
+ $storage = "";
- if (DBA::isResult($existing_photo)) {
- $backend_ref = (string)$existing_photo["backend-ref"];
- $storage = DI::storageManager()->getByName($existing_photo["backend-class"] ?? '');
- } else {
- $storage = DI::storage();
- }
-
- if (empty($storage)) {
- $data = $Image->asString();
- } else {
+ try {
+ if (DBA::isResult($existing_photo)) {
+ $backend_ref = (string)$existing_photo["backend-ref"];
+ $storage = DI::storageManager()->getWritableStorageByName($existing_photo["backend-class"] ?? '');
+ } else {
+ $storage = DI::storage();
+ }
$backend_ref = $storage->put($Image->asString(), $backend_ref);
+ } catch (InvalidClassStorageException $storageException) {
+ $data = $Image->asString();
}
$fields = [
$photos = DBA::select('photo', ['id', 'backend-class', 'backend-ref'], $conditions);
while ($photo = DBA::fetch($photos)) {
- $backend_class = DI::storageManager()->getByName($photo['backend-class'] ?? '');
- if (!empty($backend_class)) {
- if ($backend_class->delete($photo["backend-ref"] ?? '')) {
- // Delete the photos after they had been deleted successfully
- DBA::delete("photo", ['id' => $photo['id']]);
- }
+ try {
+ $backend_class = DI::storageManager()->getWritableStorageByName($photo['backend-class'] ?? '');
+ $backend_class->delete($photo['backend-ref'] ?? '');
+ // Delete the photos after they had been deleted successfully
+ DBA::delete("photo", ['id' => $photo['id']]);
+ } catch (InvalidClassStorageException $storageException) {
+ DI::logger()->debug('Storage class not found.', ['conditions' => $conditions, 'exception' => $storageException]);
+ } catch (ReferenceStorageException $referenceStorageException) {
+ DI::logger()->debug('Photo doesn\'t exist.', ['conditions' => $conditions, 'exception' => $referenceStorageException]);
}
}
$photos = self::selectToArray(['backend-class', 'backend-ref'], $conditions);
foreach($photos as $photo) {
- $backend_class = DI::storageManager()->getByName($photo['backend-class'] ?? '');
- if (!empty($backend_class)) {
+ try {
+ $backend_class = DI::storageManager()->getWritableStorageByName($photo['backend-class'] ?? '');
$fields["backend-ref"] = $backend_class->put($img->asString(), $photo['backend-ref']);
- } else {
+ } catch (InvalidClassStorageException $storageException) {
$fields["data"] = $img->asString();
}
}
$filename = basename($image_url);
if (!empty($image_url)) {
- $ret = DI::httpRequest()->get($image_url);
+ $ret = DI::httpClient()->get($image_url);
$img_str = $ret->getBody();
$type = $ret->getContentType();
} else {
$img_str = '';
+ $type = '';
}
if ($quit_on_error && ($img_str == "")) {
Photo::update($fields, $condition);
}
- /**
- * Strips known picture extensions from picture links
- *
- * @param string $name Picture link
- * @return string stripped picture link
- * @throws \Exception
- */
- public static function stripExtension($name)
- {
- $name = str_replace([".jpg", ".png", ".gif"], ["", "", ""], $name);
- foreach (Images::supportedTypes() as $m => $e) {
- $name = str_replace("." . $e, "", $name);
- }
- return $name;
- }
-
/**
* Fetch the guid and scale from picture links
*
return [];
}
- $guid = self::stripExtension($guid);
+ $guid = pathinfo($guid, PATHINFO_FILENAME);
if (substr($guid, -2, 1) != "-") {
return [];
}
* @throws \Exception
*/
public static function isLocal($name)
+ {
+ return (bool)self::getIdForName($name);
+ }
+
+ /**
+ * Return the id of a local photo
+ *
+ * @param string $name Picture link
+ * @return int
+ */
+ public static function getIdForName($name)
{
$data = self::getResourceData($name);
if (empty($data)) {
- return false;
+ return 0;
}
- return DBA::exists('photo', ['resource-id' => $data['guid'], 'scale' => $data['scale']]);
+ $photo = DBA::selectFirst('photo', ['id'], ['resource-id' => $data['guid'], 'scale' => $data['scale']]);
+ if (!empty($photo['id'])) {
+ return $photo['id'];
+ }
+ return 0;
}
/**