GlobalMedia.php 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. <?php
  2. /**
  3. * @package Grav.Common.Page
  4. *
  5. * @copyright Copyright (C) 2015 - 2018 Trilby Media, LLC. All rights reserved.
  6. * @license MIT License; see LICENSE file for details.
  7. */
  8. namespace Grav\Common\Page\Medium;
  9. use Grav\Common\Grav;
  10. use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator;
  11. class GlobalMedia extends AbstractMedia
  12. {
  13. /**
  14. * @param mixed $offset
  15. *
  16. * @return bool
  17. */
  18. public function offsetExists($offset)
  19. {
  20. return parent::offsetExists($offset) ?: !empty($this->resolveStream($offset));
  21. }
  22. /**
  23. * @param mixed $offset
  24. *
  25. * @return mixed
  26. */
  27. public function offsetGet($offset)
  28. {
  29. return parent::offsetGet($offset) ?: $this->addMedium($offset);
  30. }
  31. /**
  32. * @param string $filename
  33. * @return string|null
  34. */
  35. protected function resolveStream($filename)
  36. {
  37. /** @var UniformResourceLocator $locator */
  38. $locator = Grav::instance()['locator'];
  39. return $locator->isStream($filename) ? ($locator->findResource($filename) ?: null) : null;
  40. }
  41. /**
  42. * @param string $stream
  43. * @return Medium|null
  44. */
  45. protected function addMedium($stream)
  46. {
  47. $filename = $this->resolveStream($stream);
  48. if (!$filename) {
  49. return null;
  50. }
  51. $path = dirname($filename);
  52. list($basename, $ext,, $extra) = $this->getFileParts(basename($filename));
  53. $medium = MediumFactory::fromFile($filename);
  54. if (empty($medium)) {
  55. return null;
  56. }
  57. $medium->set('size', filesize($filename));
  58. $scale = (int) ($extra ?: 1);
  59. if ($scale !== 1) {
  60. $altMedium = $medium;
  61. // Create scaled down regular sized image.
  62. $medium = MediumFactory::scaledFromMedium($altMedium, $scale, 1)['file'];
  63. if (empty($medium)) {
  64. return null;
  65. }
  66. // Add original sized image as alternative.
  67. $medium->addAlternative($scale, $altMedium['file']);
  68. // Locate or generate smaller retina images.
  69. for ($i = $scale-1; $i > 1; $i--) {
  70. $altFilename = "{$path}/{$basename}@{$i}x.{$ext}";
  71. if (file_exists($altFilename)) {
  72. $scaled = MediumFactory::fromFile($altFilename);
  73. } else {
  74. $scaled = MediumFactory::scaledFromMedium($altMedium, $scale, $i)['file'];
  75. }
  76. if ($scaled) {
  77. $medium->addAlternative($i, $scaled);
  78. }
  79. }
  80. }
  81. $meta = "{$path}/{$basename}.{$ext}.yaml";
  82. if (file_exists($meta)) {
  83. $medium->addMetaFile($meta);
  84. }
  85. $meta = "{$path}/{$basename}.{$ext}.meta.yaml";
  86. if (file_exists($meta)) {
  87. $medium->addMetaFile($meta);
  88. }
  89. $thumb = "{$path}/{$basename}.thumb.{$ext}";
  90. if (file_exists($thumb)) {
  91. $medium->set('thumbnails.page', $thumb);
  92. }
  93. $this->add($stream, $medium);
  94. return $medium;
  95. }
  96. }