1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace App\Services\Snippets; |
4
|
|
|
|
5
|
|
|
/* |
6
|
|
|
This class show an alignable and zoomable image to place in the posts. |
7
|
|
|
|
8
|
|
|
Example of snippet: |
9
|
|
|
{# image id=[1] alignment=[left] width=[300] show_caption=[true] zoom=[true] #} |
10
|
|
|
*/ |
11
|
|
|
|
12
|
|
|
use App\Helpers\Helper; |
13
|
|
|
use App\Models\Post; |
14
|
|
|
use Spatie\MediaLibrary\MediaCollections\Models\Media; |
15
|
|
|
|
16
|
|
|
class ImageService |
17
|
|
|
{ |
18
|
|
|
private int $count = 1; |
|
|
|
|
19
|
|
|
|
20
|
|
|
/** |
21
|
|
|
* Substitute accordion snippets with the related HTML |
22
|
|
|
* |
23
|
|
|
* @param string $postBody |
24
|
|
|
* |
25
|
|
|
* @return string |
26
|
|
|
*/ |
27
|
|
|
public function snippetsToHTML(string $postBody): string |
28
|
|
|
{ |
29
|
|
|
// Find snippet occurrences |
30
|
|
|
//$ptn = '/{# +gallery +(name|width)=\[(.*)\] +(name|width)=\[(.*)\] +(name|width)=\[(.*)\] +#}/'; |
31
|
|
|
$ptn = '/{# +image +(id|alignment|width|show_caption|zoom)=\[(.*)\] +(id|alignment|width|show_caption|zoom)=\[(.*)\] +(id|alignment|width|show_caption|zoom)=\[(.*)\] +(id|alignment|width|show_caption|zoom)=\[(.*)\] +(id|alignment|width|show_caption|zoom)=\[(.*)\] +#}/'; |
32
|
|
|
|
33
|
|
|
if (preg_match_all($ptn, $postBody, $matches)) { |
34
|
|
|
// Transform the matches array in a way that can be used |
35
|
|
|
$matches = Helper::turnArray($matches); |
36
|
|
|
|
37
|
|
|
foreach ($matches as $key => $singleImageMatches) { |
38
|
|
|
$parameters = $this->getParameters($singleImageMatches); |
39
|
|
|
|
40
|
|
|
$image = Media::find($parameters['image_id']); |
41
|
|
|
$imageHtml = self::prepareImageHtml($image, $parameters); |
|
|
|
|
42
|
|
|
|
43
|
|
|
// Replace the TOKEN found in the article with the generatd gallery HTML |
44
|
|
|
$postBody = str_replace($parameters['token'], $imageHtml, $postBody); |
45
|
|
|
} |
46
|
|
|
} else { |
47
|
|
|
$postBody = $postBody; |
48
|
|
|
} |
49
|
|
|
|
50
|
|
|
return $postBody; |
51
|
|
|
} |
52
|
|
|
|
53
|
|
|
/** |
54
|
|
|
* Returns the plugin parameters. |
55
|
|
|
* |
56
|
|
|
* @param array $matches |
57
|
|
|
* |
58
|
|
|
* @return array $ret |
59
|
|
|
*/ |
60
|
|
|
public function getParameters(array $matches): array |
61
|
|
|
{ |
62
|
|
|
$ret = []; |
63
|
|
|
//ray($matches); |
64
|
|
|
|
65
|
|
|
// Get activation string parameters (from article) |
66
|
|
|
$ret['token'] = $matches[0]; |
67
|
|
|
|
68
|
|
|
$ret['image_id'] = $matches[2]; |
69
|
|
|
$ret['alignment'] = $matches[4]; |
70
|
|
|
$ret['width'] = $matches[6]; |
71
|
|
|
$ret['show_caption'] = filter_var($matches[8], FILTER_VALIDATE_BOOLEAN); |
72
|
|
|
$ret['zoom'] = filter_var($matches[10], FILTER_VALIDATE_BOOLEAN); |
73
|
|
|
|
74
|
|
|
//ray($ret); |
75
|
|
|
return $ret; |
76
|
|
|
} |
77
|
|
|
|
78
|
|
|
/** |
79
|
|
|
* Returns HTML with the image, caption, zoom functionality, etc. |
80
|
|
|
* |
81
|
|
|
* @param \Spatie\MediaLibrary\MediaCollections\Models\Media|null $image |
82
|
|
|
* @param array $parameters |
83
|
|
|
* |
84
|
|
|
* @return string $ret |
85
|
|
|
*/ |
86
|
|
|
public function prepareImageHtml(?Media $image, array $parameters): string |
87
|
|
|
{ |
88
|
|
|
if (is_null($image)) { |
89
|
|
|
return "<div class='p-4 bg-yellow-200'>A image with this id has not been found.</div>"; |
90
|
|
|
} |
91
|
|
|
|
92
|
|
|
$alt = $image->getCustomProperty('image_description'); |
93
|
|
|
//ray(empty($alt)); |
94
|
|
|
$caption = $image->getCustomProperty('image_caption'); |
95
|
|
|
|
96
|
|
|
$width = "w-full sm:" . $parameters['width']; // 100% width mobile, then for bigger devices the one specified |
97
|
|
|
$margin = "mb-6 sm:mb-0 "; |
98
|
|
|
|
99
|
|
|
$imagePath = $image->getUrl(); |
100
|
|
|
$thumbnailPath = $image->getUrl('thumb'); |
101
|
|
|
$videoUrl = $image->getCustomProperty('image_video_url'); |
102
|
|
|
|
103
|
|
|
$imageLink = ($videoUrl == null) ? $imagePath : $videoUrl; |
104
|
|
|
//$videoPlayIcon = ($videoUrl == null) ? '' : "<i class='far fa-play-circle absolute text-6xl text-white inset-center opacity-80'></i>"; |
105
|
|
|
//$videoPlayIcon = ($videoUrl == null) ? '' : "<svg class='absolute w-14 fill-current text-white inset-center opacity-80' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'><path d='M371.7 238l-176-107c-15.8-8.8-35.7 2.5-35.7 21v208c0 18.4 19.8 29.8 35.7 21l176-101c16.4-9.1 16.4-32.8 0-42zM504 256C504 119 393 8 256 8S8 119 8 256s111 248 248 248 248-111 248-248zm-448 0c0-110.5 89.5-200 200-200s200 89.5 200 200-89.5 200-200 200S56 366.5 56 256z'/></svg>"; |
106
|
|
|
$videoPlayIcon = ($videoUrl == null) ? '' : "<svg class='absolute h-14 w-14 fill-current inset-center text-primary-500' fill='currentColor' viewBox='0 0 84 84'><circle opacity='0.9' cx='42' cy='42' r='42' fill='white' /><path d='M55.5039 40.3359L37.1094 28.0729C35.7803 27.1869 34 28.1396 34 29.737V54.263C34 55.8604 35.7803 56.8131 37.1094 55.9271L55.5038 43.6641C56.6913 42.8725 56.6913 41.1275 55.5039 40.3359Z' /></svg>"; |
107
|
|
|
|
108
|
|
|
switch ($parameters['alignment']) { |
109
|
|
|
case 'right': |
110
|
|
|
$alignment = "float-right"; |
111
|
|
|
$margin .= 'ml-0 sm:ml-3'; |
112
|
|
|
break; |
113
|
|
|
|
114
|
|
|
default: |
115
|
|
|
$alignment = "float-left"; |
116
|
|
|
$margin .= 'mr-0 sm:mr-3'; |
117
|
|
|
break; |
118
|
|
|
} |
119
|
|
|
|
120
|
|
|
$imageHtml = ""; |
121
|
|
|
$imageHtml .= "<div class='imageSnippet {$width} {$margin} {$alignment} text-center'>"; |
122
|
|
|
$imageHtml .= "<div class='relative inline-block'>"; |
123
|
|
|
$imageHtml .= "<a href='" . $imageLink . "' data-fancybox='images' data-caption='" . $caption . "' alt='" . $alt . "'>"; |
124
|
|
|
$imageHtml .= "<img class='my-0' src='" . $thumbnailPath . "' />"; |
125
|
|
|
$imageHtml .= $videoPlayIcon; |
126
|
|
|
$imageHtml .= "</a>"; |
127
|
|
|
if (is_null($videoUrl)) { |
128
|
|
|
$imageHtml .= "<div class='absolute bottom-0 right-0 p-2 bg-gray-100 opacity-80'>"; |
129
|
|
|
$imageHtml .= "<svg class='w-6 h-6' fill='none' stroke='currentColor' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'><path stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0zM10 7v3m0 0v3m0-3h3m-3 0H7'></path></svg>"; |
130
|
|
|
$imageHtml .= "</div>"; |
131
|
|
|
} |
132
|
|
|
$imageHtml .= "</div>"; |
133
|
|
|
if (!empty($alt)) { |
134
|
|
|
$imageHtml .= "<div class='text-xs p-2 font-semibold sm:text-left'>"; /*bg-gray-200*/ |
135
|
|
|
$imageHtml .= $alt; |
136
|
|
|
$imageHtml .= "</div>"; |
137
|
|
|
} |
138
|
|
|
$imageHtml .= "</div>"; |
139
|
|
|
|
140
|
|
|
return $imageHtml; |
141
|
|
|
} |
142
|
|
|
} |
143
|
|
|
|
144
|
|
|
|