55use Illuminate \Contracts \Support \Htmlable ;
66use Illuminate \Support \Collection ;
77use Illuminate \Support \HtmlString ;
8+ use SolutionForest \InspireCms \InspireCmsConfig ;
89use SolutionForest \InspireCms \Support \Base \Dtos \BaseDto ;
10+ use SolutionForest \InspireCms \Support \Dtos \MediaAssetDto ;
911
1012class SeoDto extends BaseDto
1113{
@@ -72,83 +74,13 @@ class SeoDto extends BaseDto
7274 */
7375 public $ siteName ;
7476
75- /**
76- * The locale of the content.
77- *
78- * @var string
79- */
80- public $ locale ;
81-
82- /**
83- * The published time of the content.
84- *
85- * @var string
86- */
87- public $ publishedTime ;
88-
89- /**
90- * The last modified time of the content.
91- *
92- * @var string
93- */
94- public $ modifiedTime ;
95-
96- /**
97- * The author of the content.
98- *
99- * @var string
100- */
101- public $ author ;
102-
103- /**
104- * The section of the site where the content is located.
105- *
106- * @var string
107- */
108- public $ section ;
109-
110- /**
111- * The tag associated with the content.
112- *
113- * @var string
114- */
115- public $ tag ;
116-
117- /**
118- * The category of the content.
119- *
120- * @var string
121- */
122- public $ category ;
123-
12477 /**
12578 * The canonical URL of the content.
12679 *
12780 * @var string
12881 */
12982 public $ canonical ;
13083
131- /**
132- * The alternate URL of the content.
133- *
134- * @var string
135- */
136- public $ alternate ;
137-
138- /**
139- * The AMP HTML version of the content.
140- *
141- * @var string
142- */
143- public $ ampHtml ;
144-
145- /**
146- * The AMP version of the content.
147- *
148- * @var string
149- */
150- public $ amp ;
151-
15284 /**
15385 * Indicates whether the content should not be indexed by search engines.
15486 *
@@ -163,55 +95,6 @@ class SeoDto extends BaseDto
16395 */
16496 public $ noFollow ;
16597
166- /**
167- * Indicates whether the content should not be archived by search engines.
168- *
169- * @var string
170- */
171- public $ noArchive ;
172-
173- /**
174- * Indicates whether search engines should not show a snippet of the content.
175- *
176- * @var string
177- */
178- public $ noSnippet ;
179-
180- /**
181- * Indicates whether the content should not be included in the Open Directory Project.
182- *
183- * @var string
184- */
185- public $ noOdp ;
186-
187- /**
188- * Indicates whether the content should not be included in Yahoo Directory.
189- *
190- * @var string
191- */
192- public $ noYdir ;
193-
194- /**
195- * Indicates whether images on the content should not be indexed by search engines.
196- *
197- * @var string
198- */
199- public $ noImageIndex ;
200-
201- /**
202- * Indicates whether the content should not be translated by search engines.
203- *
204- * @var string
205- */
206- public $ noTranslate ;
207-
208- /**
209- * Indicates whether the content should not be cached by search engines.
210- *
211- * @var string
212- */
213- public $ noCache ;
214-
21598 /**
21699 * @var Collection<self>|null
217100 */
@@ -228,10 +111,6 @@ public static function fromArray(array $parameters)
228111 'og_image ' => 'ogImage ' ,
229112 'noindex ' => 'noIndex ' ,
230113 'nofollow ' => 'noFollow ' ,
231- 'noarchive ' => 'noArchive ' ,
232- 'nosnippet ' => 'noSnippet ' ,
233- 'noodp ' => 'noOdp ' ,
234- 'noydir ' => 'noYdir ' ,
235114 ];
236115
237116 foreach ($ parameters as $ key => $ value ) {
@@ -259,11 +138,34 @@ public static function fromArray(array $parameters)
259138
260139 $ dto = parent ::fromArray ($ parameters );
261140
141+ $ fallbackSeo = InspireCmsConfig::get ('frontend.fallback_seo ' , []);
142+ $ fallbackExtraMapper = [
143+ 'title ' => ['ogTitle ' ],
144+ 'description ' => ['ogDescription ' ],
145+ 'image ' => ['ogImage ' ],
146+ ];
147+ if (is_array ($ fallbackSeo ) && ! empty ($ fallbackSeo )) {
148+ foreach ($ fallbackSeo as $ key => $ value ) {
149+ $ keysToMap = array_unique (array_merge (
150+ [$ key ],
151+ $ fallbackExtraMapper [$ key ] ?? []
152+ ));
153+ foreach ($ keysToMap ?? [] as $ mappedKey ) {
154+ if (! property_exists ($ dto , $ mappedKey )) {
155+ continue ;
156+ }
157+ if (! isset ($ dto ->{$ mappedKey }) || empty ($ dto ->{$ mappedKey })) {
158+ $ dto ->{$ mappedKey } = $ value ;
159+ }
160+ }
161+ }
162+ }
163+
262164 return $ dto ;
263165 }
264166
265167 /**
266- * @param self[]|Collection<slef >|null $ancestors
168+ * @param self[]|Collection<self >|null $ancestors
267169 * @return self
268170 */
269171 public function setAncestors ($ ancestors )
@@ -317,8 +219,8 @@ public function __toString(): string
317219 $ html .= "<meta property= \"og:description \" content= \"{$ ogDescription }\"> \n" ;
318220 }
319221
320- if ($ this -> ogImage && ( $ mediaAssetUrl = inspirecms_asset ()-> findByKeys ($ this ->ogImage )-> first ()?->getUrl() )) {
321- $ html .= "<meta property= \"og:image \" content= \"{$ mediaAssetUrl }\"> \n" ;
222+ if ($ odImageUrl = $ this -> transformImage ($ this ->ogImage )) {
223+ $ html .= "<meta property= \"og:image \" content= \"{$ odImageUrl }\"> \n" ;
322224 }
323225
324226 if ($ this ->url ) {
@@ -333,86 +235,66 @@ public function __toString(): string
333235 $ html .= "<meta property= \"og:site_name \" content= \"{$ this ->siteName }\"> \n" ;
334236 }
335237
336- if ($ this ->locale ) {
337- $ html .= "<meta property= \"og:locale \" content= \"{$ this ->locale }\"> \n" ;
338- }
339-
340- if ($ this ->publishedTime ) {
341- $ html .= "<meta property= \"article:published_time \" content= \"{$ this ->publishedTime }\"> \n" ;
342- }
343-
344- if ($ this ->modifiedTime ) {
345- $ html .= "<meta property= \"article:modified_time \" content= \"{$ this ->modifiedTime }\"> \n" ;
346- }
347-
348- if ($ this ->author ) {
349- $ html .= "<meta property= \"article:author \" content= \"{$ this ->author }\"> \n" ;
350- }
351-
352- if ($ this ->section ) {
353- $ html .= "<meta property= \"article:section \" content= \"{$ this ->section }\"> \n" ;
354- }
355-
356- if ($ this ->tag ) {
357- $ html .= "<meta property= \"article:tag \" content= \"{$ this ->tag }\"> \n" ;
358- }
359-
360- if ($ this ->category ) {
361- $ html .= "<meta property= \"article:category \" content= \"{$ this ->category }\"> \n" ;
362- }
363-
364238 if ($ this ->canonical ) {
365239 $ html .= "<link rel= \"canonical \" href= \"{$ this ->canonical }\"> \n" ;
366240 }
367241
368- if ($ this ->alternate ) {
369- $ html .= "<link rel= \"alternate \" href= \"{$ this ->alternate }\"> \n" ;
242+ $ robotsContent = [];
243+ if ($ this ->noIndex ) {
244+ $ robotsContent [] = 'noindex ' ;
370245 }
371-
372- if ($ this ->ampHtml ) {
373- $ html .= "<link rel= \"amphtml \" href= \"{$ this ->ampHtml }\"> \n" ;
246+ if ($ this ->noFollow ) {
247+ $ robotsContent [] = 'nofollow ' ;
374248 }
375-
376- if ($ this ->amp ) {
377- $ html .= "<link rel= \"amp \" href= \"{$ this ->amp }\"> \n" ;
249+ if (! empty ($ robotsContent )) {
250+ $ html .= '<meta name="robots" content=" ' . implode (', ' , $ robotsContent ) . "\"> \n" ;
378251 }
379252
380- if ($ this ->noIndex ) {
381- $ html .= "<meta name= \"robots \" content= \"noindex \"> \n" ;
382- }
253+ return $ html ;
254+ }
383255
384- if ($ this ->noFollow ) {
385- $ html .= "<meta name= \"robots \" content= \"nofollow \"> \n" ;
256+ protected function transformImage ($ value )
257+ {
258+ // If the value is empty or null, return null
259+ if (empty ($ value )) {
260+ return null ;
386261 }
387262
388- if ($ this ->noArchive ) {
389- $ html .= "<meta name= \"robots \" content= \"noarchive \"> \n" ;
390- }
263+ // If the value is a string, check if it is a valid URL
264+ if (is_string ($ value )) {
391265
392- if ($ this -> noSnippet ) {
393- $ html .= " <meta name= \" robots \" content= \" nosnippet \" > \n" ;
394- }
266+ if (filter_var ( $ value , FILTER_VALIDATE_URL ) ) {
267+ return $ value ;
268+ }
395269
396- if ($ this ->noOdp ) {
397- $ html .= "<meta name= \"robots \" content= \"noodp \"> \n" ;
398- }
270+ // If not, check if it is a relative URL (e.g., "/storage/images/example.jpg")
271+ if (str_starts_with ($ value , '/ ' )) {
272+ // Assuming the base URL is defined in your configuration
273+ $ baseUrl = config ('app.url ' , 'http://localhost ' );
399274
400- if ($ this ->noYdir ) {
401- $ html .= "<meta name= \"robots \" content= \"noydir \"> \n" ;
402- }
275+ return rtrim ($ baseUrl , '/ ' ) . $ value ;
276+ }
403277
404- if ($ this ->noImageIndex ) {
405- $ html .= "<meta name= \"robots \" content= \"noimageindex \"> \n" ;
278+ return null ;
406279 }
407280
408- if ($ this ->noTranslate ) {
409- $ html .= "<meta name= \"robots \" content= \"notranslate \"> \n" ;
410- }
281+ // If the value is an array (from MediaPicker)
282+ if (is_array ($ value )) {
283+
284+ try {
285+ $ dto = MediaAssetDto::fromArray ($ value );
286+ // Handle the case where the src is a string
287+ if (filled ($ dto ->src )) {
288+ return $ this ->transformImage ($ dto ->src );
289+ }
290+ } catch (\Throwable $ th ) {
291+ //
292+ }
411293
412- if ($ this ->noCache ) {
413- $ html .= "<meta name= \"robots \" content= \"nocache \"> \n" ;
294+ return null ;
414295 }
415296
416- return $ html ;
297+ // If the value is not a string or an array, return null
298+ return null ;
417299 }
418300}
0 commit comments