Skip to content
This repository has been archived by the owner on Dec 11, 2020. It is now read-only.

Lorempixel is down : impossible to use $faker->image (again) #1884

Open
dsampaolo opened this issue Jan 9, 2020 · 28 comments
Open

Lorempixel is down : impossible to use $faker->image (again) #1884

dsampaolo opened this issue Jan 9, 2020 · 28 comments

Comments

@dsampaolo
Copy link

Summary

LoremPixel.com is used by $faker->image to download files from the service.

The service is down, so we can't use $faker->image() at the moment.

We use it in the seeds of a Laravel application, which disables our preproduction environment.

A timeout detection MAY be enough for us, as it would allow the preproduction environment to run, even without images.

@DanielSalut
Copy link

Bonjour J'aurai juste aimé savoir quand sera réparer ( $ faker -> image )
Je vous remecie beaucoup !!!

@kvlknctk
Copy link

this service nonsence. 👎
please replace this service with another one.

@miroslav-demcak-cz
Copy link

This is temporary fix in my project. Feel free to use if the random image is sufficient for you with random color only:

    /**
     * Generates random image; temporary fix for current issue.
     * @link https://github.com/fzaninotto/Faker/issues/1884
     *
     * @param string $absolutePath
     * @param int $width
     * @param int $height
     * @return bool
     */
    protected function saveRandomImage(string $absolutePath, int $width = 640, int $height = 480): bool
    {
        // Create a blank image:
        $im = imagecreatetruecolor($width, $height);
        // Add light background color:
        $bgColor = imagecolorallocate($im, rand(100, 255), rand(100, 255), rand(100, 255));
        imagefill($im, 0, 0, $bgColor);

        // Save the image:
        $isGenerated = imagejpeg($im, $absolutePath);

        // Free up memory:
        imagedestroy($im);

        return $isGenerated;
    }

@jonathanbossenger
Copy link

Proposed PR replaces use of lorempixel.com service, which even while now live is very slow, with placeholder.com service.

@pimjansen
Copy link
Contributor

@jonathanbossenger we are completely removing the third party implementation in the faker core. See the announcement for 2.x so we are not going to patch this any time soon. Feel free to add a custom provider instead

@jonathanbossenger
Copy link

@pimjansen aha I see, ok no problem.

@jonathanbossenger
Copy link

BTW where would I see announcements :-)

@kvlknctk
Copy link

@jonathanbossenger we are completely removing the third party implementation in the faker core. See the announcement for 2.x so we are not going to patch this any time soon. Feel free to add a custom provider instead

why did you make such a decision? we have used this feature in every project and we will need it. It's a burden for us to put something else in place. how can you make such comfortable decisions about the project?

@jonathanbossenger
Copy link

jonathanbossenger commented Jan 16, 2020

If it's helpful to any one I created an Image Helper which will do the same thing as my initial PR


namespace App\Helpers;

class Image
{

    /**
     * Generate the URL that will return a random image
     *
     * Set randomize to false to remove the random GET parameter at the end of the url.
     *
     * @example 'https://via.placeholder.com/640x480/?12345'
     *
     * @param integer $width
     * @param integer $height
     * @param bool $randomize
     *
     * @return string
     */
    public static function imageUrl($width = 640, $height = 480, $randomize = true): string
    {
        $baseUrl = "https://via.placeholder.com/";
        $url = "{$width}x{$height}/";

        if ($randomize) {
            $url .= '?' . mt_rand();
        }

        return $baseUrl . $url;
    }

    /**
     * Download a remote random image to disk and return its location
     *
     * Requires curl, or allow_url_fopen to be on in php.ini.
     *
     * @param null $dir
     * @param int $width
     * @param int $height
     * @param bool $fullPath
     * @param bool $randomize
     * @return bool|\RuntimeException|string
     * @example '/path/to/dir/13b73edae8443990be1aa8f1a483bc27.jpg'
     */
    public static function image($dir = null, $width = 640, $height = 480, $fullPath = true, $randomize = true)
    {
        $dir = is_null($dir) ? sys_get_temp_dir() : $dir; // GNU/Linux / OS X / Windows compatible
        // Validate directory path
        if (!is_dir($dir) || !is_writable($dir)) {
            throw new \InvalidArgumentException(sprintf('Cannot write to directory "%s"', $dir));
        }

        // Generate a random filename. Use the server address so that a file
        // generated at the same time on a different server won't have a collision.
        $name = md5(uniqid(empty($_SERVER['SERVER_ADDR']) ? '' : $_SERVER['SERVER_ADDR'], true));
        $filename = $name .'.jpg';
        $filepath = $dir . DIRECTORY_SEPARATOR . $filename;

        $url = static::imageUrl($width, $height, $randomize);

        // save file
        if (function_exists('curl_exec')) {
            // use cURL
            $fp = fopen($filepath, 'w');
            $ch = curl_init($url);
            curl_setopt($ch, CURLOPT_FILE, $fp);
            $success = curl_exec($ch) && curl_getinfo($ch, CURLINFO_HTTP_CODE) === 200;
            fclose($fp);
            curl_close($ch);

            if (!$success) {
                unlink($filepath);

                // could not contact the distant URL or HTTP error - fail silently.
                return false;
            }
        } elseif (ini_get('allow_url_fopen')) {
            // use remote fopen() via copy()
            $success = copy($url, $filepath);
        } else {
            return new \RuntimeException('The image formatter downloads an image from a remote HTTP server. Therefore, it requires that PHP can request remote hosts, either via cURL or fopen()');
        }

        return $fullPath ? $filepath : $filename;
    }

}

@pimjansen
Copy link
Contributor

BTW where would I see announcements :-)

We flagged them under the issues. See #1851

why did you make such a decision? we have used this feature in every project and we will need it. It's a burden for us to put something else in place. how can you make such comfortable decisions about the project?

More info can be found at #1807. In general to summarize it is that we want to bring Faker back to its basics. There are way too many external dependencies at this point. Maintaining all locales is work for someone who understands the locale and not the Faker core itself. Same goes with the images.
To help you guys, it will be very easy extendable so probably you just install a custom faker provider that can generate images for you (whatever service it would be).

@kvlknctk
Copy link

I think it's not a problem to remain an optional option.

@PWalkow
Copy link

PWalkow commented Jan 23, 2020

Maybe a solution for the image problem would be to use different provider (maybe even confiurable in the 'image' method) like
https://picsum.photos/
or
https://loremflickr.com/
?

similiar packages in js have moved away from lorempixel due to downtime issues.

@phenix-factory
Copy link

I found this plugin and use it instead of the Core function. Work well with not too much work : https://packagist.org/packages/bheller/images-generator

morawskim added a commit to morawskim/faker-images that referenced this issue Feb 3, 2020
Faker include support for Lorempixel, but currently this service is down
(fzaninotto/Faker#1884).
We can't use $faker->image due to timeouts.
I created a new provider (picsum) to fetch or generate url to random images.
@morawskim
Copy link

If someone want fetch images from picsum may use may library: https://github.com/morawskim/faker-images

Due to #1899 I don't created pull request.

@Lafoiss
Copy link

Lafoiss commented Feb 4, 2020

If someone want fetch images from picsum may use may library: https://github.com/morawskim/faker-images

Due to #1899 I don't created pull request.

Thanks a lot @morawskim , great job

morawskim added a commit to stasiu20/ssorder that referenced this issue Feb 5, 2020
Po załadowaniu restauracji korzystamy z faker to pobrania losowych zdjec dla restauracji.
Pobrane zdjecia nastepnie wrzucamy na minio.
Dzieki temu na naszej stronie glownej pojawia sie loga restauracji.
Obecnie faker korzysta tylko z lorempixel, ktore nie dziala (fzaninotto/Faker#1884)
Korzystamy wiec tymczasowo z forka, ktory dodaje usluge https://picsum.photos/
@simonemarino
Copy link

I solved it this way. I have modified the method imageUrl of the ".../Faker/Provider/Image" class.

  public static function imageUrl($width = 640, $height = 480, $id = null, $randomize = true, $word = null, $gray = false)
    {
        // Example : "https://i.picsum.photos/id/10/200/300.jpg";

        $baseUrl = "https://picsum.photos/";

        // ID Random image
        $url = "id/".$id."/";
        $url .= "{$width}/{$height}/";

        return $baseUrl . $url;
    }

$id will have to be passed as $faker->numberBetween($min = 10, $max = 200);

@edgarsn
Copy link

edgarsn commented Apr 15, 2020

Thanks everyone for temporary workarounds.

Imo, this should be fixed in 1.0 anyways. I think no one doesn't care what's coming up in 2.0 since it's a future version, not a version coming in a week or so. Also, it's not that hard to just swap providers to fix annoying bug.

I can offer to create a PR, but only if it will not be declined because of "we've plans for 2.0 blah blah blah".

@jonathanbossenger
Copy link

@edgarsn I'm afraid I don't agree with your statement that this should be fixed in 1.0. This is an open source project, and we can't expect open source maintainers to do anything, especially on a project that they maintain in their free time, and for no remuneration.

There are enough work arounds in this issue to provide solutions to folks, or you can fork the software and roll your own solution, but comments like but only if it will not be declined because of "we've plans for 2.0 blah blah blah" are neither helpful or constructive.

@edgarsn
Copy link

edgarsn commented Apr 15, 2020

@edgarsn I'm afraid I don't agree with your statement that this should be fixed in 1.0. This is an open source project, and we can't expect open source maintainers to do anything, especially on a project that they maintain in their free time, and for no remuneration.

There are enough work arounds in this issue to provide solutions to folks, or you can fork the software and roll your own solution, but comments like but only if it will not be declined because of "we've plans for 2.0 blah blah blah" are neither helpful or constructive.

Then Image class and docs should be removed, don't you think? Imagine if Laravel documentation would describe how to use Request object but in fact it's not working and Taylor would not want to fix it until he releases next major version. Sounds dumb, isn't?

As I said, I can offer a PR, but if the maintainers have a "vision" not to fix this, then at least remove it completetely.

@PWalkow
Copy link

PWalkow commented Apr 18, 2020

I guess this issue can be closed already as it seems like lorempixel works already without downtime issues. Would be great to change the provider on the fly just by the configuration in the future...

@poldixd
Copy link

poldixd commented Apr 30, 2020

I guess this issue can be closed already as it seems like lorempixel works already without downtime issues. Would be great to change the provider on the fly just by the configuration in the future...

But lorempixel is really slow...

@Dinver
Copy link

Dinver commented May 11, 2020

In Russia Lorempixel not working...

@xorinzor
Copy link

I don't understand why they won't just accept a PR to fix this. It's such an easy fix and people are willing to fix it in this version. Right now it's already been another 5 months with this issue going on and lorempixel still working barely (if at all).

Especially given the fact that the devs are deciding to only fix this in 2.0 should be enough reason to at least accept a PR fix for this version too. Any major version upgrade always entails breaking stuff (which is why for certain operating systems LTS versions exist).

@xwiz
Copy link

xwiz commented Jul 17, 2020

For Laravel, you can replace faker image with UploadedFile::fake()->create('random.extension');.

@pnoeric
Copy link

pnoeric commented Aug 18, 2020

For those just joining this thread... I ended up using this excellent drop-in library:

https://github.com/salopot/image-generator

@reduardo7
Copy link

reduardo7 commented Oct 16, 2020

Helper

namespace App\Helpers;

/**
 * @see https://github.com/fzaninotto/Faker/issues/1884
 */
class FakerHelper
{
  /**
   * Generate the URL that will return a random image
   *
   * Set randomize to false to remove the random GET parameter at the end of the url.
   *
   * @example 'https://picsum.photos/id/237/200/300'
   *
   * @param integer $width
   * @param integer $height
   * @param string|null $_category NOT USED
   * @param bool $randomize
   * @param string|null $_word NOT USED
   * @param bool $gray
   *
   * @return string
   * @see vendor/fzaninotto/faker/src/Faker/Provider/Image.php > imageUrl
   */
  public static function getImageUrl($width = 640, $height = 480, $_category = null, $randomize = true, $_word = null, $gray = false)
  {
    $baseUrl = 'https://picsum.photos/';
    $url = '';

    if (!$randomize) {
      $url .= 'id/' . rand(1, 1000) . '/';
    }

    $url .= "$width/$height/";

    if ($gray) {
      $url .= '?grayscale';
    }

    if ($randomize) {
      $url .= str_contains($url, '?') ? '&' : '?';
      $url .= 'random=' . rand(1, 1000);
    }

    return $baseUrl . $url;
  }

  public function imageUrl($width = 640, $height = 480, $_category = null, $randomize = true, $_word = null, $gray = false)
  {
    return self::getImageUrl($width, $height, $_category, $randomize, $_word, $gray);
  }

  public static function changeUrl($original_url)
  {
    if (str_starts_with($original_url, 'https://lorempixel.com/')) {
      $o = str_replace('https://lorempixel.com/', '', $original_url);

      $parts = explode('/', $o);
      $width = $parts[0];
      $height = $parts[1];
      $gray = str_contains($original_url, '/gray/');
      $randomize = str_contains($original_url, '?');

      return self::getImageUrl($width, $height, null, $randomize, null, $gray);
    }

    return $original_url;
  }
}

Faker

/** @var \Illuminate\Database\Eloquent\Factory $factory */

use App\Helpers\FakerHelper;

$factory->define('Foo', function () {
  $f = new FakerHelper();
  $height = rand(600, 900);
  $width = intval($height * 2 / 3);

  return [
    // 'logo' => $faker->imageUrl($width, $height, 'NOT USED', false), // Old implementation
    'logo' => $f->imageUrl($width, $height, 'NOT USED', false),
  ];
});

Update

If you want to update your current fake data, you can add a new Migration with following:

$data = MyModel::where([])->get();

foreach ($data as $record) {
  $record->logo = FakerHelper::changeUrl($record->logo);
  $record->save();
}

@stesvis
Copy link

stesvis commented Oct 22, 2020

lorempixel.com is down again, please use something else that is more reliable

@mdutt247
Copy link

lorempixel.com is down.
Replaced following line in \vendor\fzaninotto\faker\src\Faker\Provider\Image.php
//$baseUrl = "https://lorempixel.com/";
with
$baseUrl = "https://picsum.photos/";

and it is working.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.