Completed
Push — master ( 8d91fd...0e0bf2 )
by Benjamin
11:32
created

MediaProvider::randomFile()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 16
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 16
rs 9.4285
cc 3
eloc 11
nc 3
nop 1
1
<?php
2
3
namespace Alpixel\Bundle\MediaBundle\DataFixtures\ORM;
4
5
use Alpixel\Bundle\MediaBundle\Services\MediaManager;
6
use Faker\Provider\Base as BaseProvider;
7
use Symfony\Component\Filesystem\Filesystem;
8
use Symfony\Component\Finder\Finder;
9
use Symfony\Component\HttpFoundation\File\File;
10
11
class MediaProvider extends BaseProvider
12
{
13
    protected $mediaManager;
14
15
    public function __construct(MediaManager $mediaManager)
16
    {
17
        $this->mediaManager = $mediaManager;
18
    }
19
20
    /** @deprecated */
21
    public function randomMedia($width = null, $height = null, $type = 'color')
22
    {
23
        return $this->randomImage($width, $height, $type);
24
    }
25
26
    public function randomImage($width = null, $height = null, $type = 'color')
27
    {
28
        do {
29
            $dimensions = $this->fetchDimensions($width, $height);
30
            $file = $this->fetchFromCache($dimensions['w'] . '-' . $dimensions['h']);
31
            if ($file === null) {
32
                $file = $this->downloadMedia($this->generateUrl($dimensions, $type), 'jpg');
33
                $this->storeInCache($dimensions['w'] . '-' . $dimensions['h'], $file);
34
            }
35
        } while (!preg_match('@^image/@', $file->getMimeType()));
36
37
        $media = $this->mediaManager->upload($file);
38
39
        return $media;
40
    }
41
42
    public function randomFile($fileType)
43
    {
44
        $file = $this->fetchFromCache("file-" . $fileType);
45
        if ($file === null) {
46
            switch ($fileType) {
47
                case "pdf":
48
                default:
49
                    $file = $this->downloadMedia("https://symfony.com/pdf/Symfony_book_master.pdf", $fileType);
50
                    break;
51
            }
52
        }
53
        $this->storeInCache("file-" . $fileType, $file);
54
        $media = $this->mediaManager->upload($file);
55
56
        return $media;
57
    }
58
59
    protected function fetchDimensions($width = null, $height = null)
60
    {
61
        if ($width === null && $height !== null) {
62
            $width = round($height * 4 / 3);
63
        } elseif ($width !== null && $height === null) {
64
            $height = round($width * 3 / 4);
65
        } else {
66
            $aWidth = [800, 1200, 1600];
67
            $width = array_rand($aWidth, 1);
68
            $width = $aWidth[$width];
69
            $height = round($width * 3 / 4);
70
        }
71
72
        return ['w' => $width, 'h' => $height];
73
    }
74
75
    protected function generateUrl($dimensions, $type = 'color')
76
    {
77
        $url = 'http://loremflickr.com/';
78
79
        if ($type !== 'color') {
80
            $url .= 'g/';
81
        }
82
83
        $url .= $dimensions['w'] . '/' . $dimensions['h'];
84
85
        $category = ['abstract', 'city', 'nature', 'moutains'];
86
        $url .= '/' . $category[array_rand($category, 1)] . '/';
87
88
        return $url;
89
    }
90
91
    protected function downloadMedia($url, $ext)
92
    {
93
        $filepath = sys_get_temp_dir() . '/' . uniqid() . '.' . $ext;
94
        $ch = curl_init($url);
95
        $fp = fopen($filepath, 'wb');
96
        curl_setopt($ch, CURLOPT_FILE, $fp);
97
        curl_setopt($ch, CURLOPT_HEADER, 0);
98
        curl_exec($ch);
99
        curl_close($ch);
100
        fclose($fp);
101
102
        return new File($filepath, 'random');
0 ignored issues
show
Documentation introduced by
'random' is of type string, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
103
    }
104
105
    protected function fetchFromCache($key)
0 ignored issues
show
Coding Style introduced by
fetchFromCache uses the super-global variable $_SERVER which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
106
    {
107
        $fs = new Filesystem();
108
        $cacheDir = $_SERVER['HOME'] . '/.symfony/media';
109
        if (!$fs->exists($cacheDir)) {
110
            $fs->mkdir($cacheDir, 0777);
111
        } else {
112
            $cacheDir .= '/' . $key;
113
            if (!$fs->exists($cacheDir)) {
114
                $fs->mkdir($cacheDir, 0777);
115
            } else {
116
                $finder = new Finder();
117
                $files = $finder->in($cacheDir . '/')->files();
118
                if (strrpos($key, "file-") !== false || $files->count() === 3) {
119
                    $iterator = $finder->getIterator();
120
                    $iterator->rewind();
121
                    for ($i = 0; $i < rand(0, 2); $i++) {
122
                        $iterator->next();
123
                    }
124
                    $file = new File($iterator->current());
125
                    $fs->copy($file->getRealPath(), sys_get_temp_dir() . '/' . $file->getFilename());
126
127
                    return new File(sys_get_temp_dir() . '/' . $file->getFilename());
128
                }
129
            }
130
        }
131
    }
132
133
    protected function storeInCache($key, File $file)
0 ignored issues
show
Coding Style introduced by
storeInCache uses the super-global variable $_SERVER which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
134
    {
135
        $fs = new Filesystem();
136
        $cacheDir = $_SERVER['HOME'] . '/.symfony/media/' . $key;
137
        if (!$fs->exists($cacheDir)) {
138
            $fs->mkdir($cacheDir, 0777);
139
        }
140
        $fs->copy($file->getRealPath(), $cacheDir . '/' . $file->getFilename());
141
    }
142
}
143