/system/src/Grav/Common/Page/Media.php

https://gitlab.com/asun89/socianovation-web · PHP · 258 lines · 161 code · 38 blank · 59 comment · 31 complexity · aa8edc151f33c7b320846e96375a968a MD5 · raw file

  1. <?php
  2. namespace Grav\Common\Page;
  3. use Grav\Common\Getters;
  4. use Grav\Common\GravTrait;
  5. use Grav\Common\Page\Medium\Medium;
  6. use Grav\Common\Page\Medium\MediumFactory;
  7. /**
  8. * Media is a holder object that contains references to the media of page. This object is created and
  9. * populated during the getMedia() method in the Pages object
  10. *
  11. * @author RocketTheme
  12. * @license MIT
  13. */
  14. class Media extends Getters
  15. {
  16. use GravTrait;
  17. protected $gettersVariable = 'instances';
  18. protected $path;
  19. protected $instances = [];
  20. protected $images = [];
  21. protected $videos = [];
  22. protected $audios = [];
  23. protected $files = [];
  24. /**
  25. * @param $path
  26. */
  27. public function __construct($path)
  28. {
  29. // Handle special cases where page doesn't exist in filesystem.
  30. if (!is_dir($path)) {
  31. return;
  32. }
  33. $this->path = $path;
  34. $iterator = new \FilesystemIterator($path, \FilesystemIterator::UNIX_PATHS | \FilesystemIterator::SKIP_DOTS);
  35. $media = [];
  36. /** @var \DirectoryIterator $info */
  37. foreach ($iterator as $path => $info) {
  38. // Ignore folders and Markdown files.
  39. if (!$info->isFile() || $info->getExtension() == 'md' || $info->getBasename() === '.DS_Store') {
  40. continue;
  41. }
  42. // Find out what type we're dealing with
  43. list($basename, $ext, $type, $extra) = $this->getFileParts($info->getFilename());
  44. $media["{$basename}.{$ext}"] = isset($media["{$basename}.{$ext}"]) ? $media["{$basename}.{$ext}"] : [];
  45. if ($type === 'alternative') {
  46. $media["{$basename}.{$ext}"][$type] = isset($media["{$basename}.{$ext}"][$type]) ? $media["{$basename}.{$ext}"][$type] : [];
  47. $media["{$basename}.{$ext}"][$type][$extra] = [ 'file' => $path, 'size' => $info->getSize() ];
  48. } else {
  49. $media["{$basename}.{$ext}"][$type] = [ 'file' => $path, 'size' => $info->getSize() ];
  50. }
  51. }
  52. foreach ($media as $name => $types) {
  53. // First prepare the alternatives in case there is no base medium
  54. if (!empty($types['alternative'])) {
  55. foreach ($types['alternative'] as $ratio => &$alt) {
  56. $alt['file'] = MediumFactory::fromFile($alt['file']);
  57. if (!$alt['file']) {
  58. unset($types['alternative'][$ratio]);
  59. } else {
  60. $alt['file']->set('size', $alt['size']);
  61. }
  62. }
  63. }
  64. // Create the base medium
  65. if (!empty($types['base'])) {
  66. $medium = MediumFactory::fromFile($types['base']['file']);
  67. $medium && $medium->set('size', $types['base']['size']);
  68. } else if (!empty($types['alternative'])) {
  69. $altMedium = reset($types['alternative']);
  70. $ratio = key($types['alternative']);
  71. $altMedium = $altMedium['file'];
  72. $medium = MediumFactory::scaledFromMedium($altMedium, $ratio, 1)['file'];
  73. }
  74. if (!$medium) {
  75. continue;
  76. }
  77. if (!empty($types['meta'])) {
  78. $medium->addMetaFile($types['meta']['file']);
  79. }
  80. if (!empty($types['thumb'])) {
  81. // We will not turn it into medium yet because user might never request the thumbnail
  82. // not wasting any resources on that, maybe we should do this for medium in general?
  83. $medium->set('thumbnails.page', $types['thumb']['file']);
  84. }
  85. // Build missing alternatives
  86. if (!empty($types['alternative'])) {
  87. $alternatives = $types['alternative'];
  88. $max = max(array_keys($alternatives));
  89. for ($i=2; $i < $max; $i++) {
  90. if (isset($alternatives[$i])) {
  91. continue;
  92. }
  93. $types['alternative'][$i] = MediumFactory::scaledFromMedium($alternatives[$max]['file'], $max, $i);
  94. }
  95. foreach ($types['alternative'] as $ratio => $altMedium) {
  96. $medium->addAlternative($ratio, $altMedium['file']);
  97. }
  98. }
  99. $this->add($name, $medium);
  100. }
  101. }
  102. /**
  103. * Get medium by filename.
  104. *
  105. * @param string $filename
  106. * @return Medium|null
  107. */
  108. public function get($filename)
  109. {
  110. return isset($this->instances[$filename]) ? $this->instances[$filename] : null;
  111. }
  112. /**
  113. * Get a list of all media.
  114. *
  115. * @return array|Medium[]
  116. */
  117. public function all()
  118. {
  119. ksort($this->instances, SORT_NATURAL | SORT_FLAG_CASE);
  120. return $this->instances;
  121. }
  122. /**
  123. * Get a list of all image media.
  124. *
  125. * @return array|Medium[]
  126. */
  127. public function images()
  128. {
  129. ksort($this->images, SORT_NATURAL | SORT_FLAG_CASE);
  130. return $this->images;
  131. }
  132. /**
  133. * Get a list of all video media.
  134. *
  135. * @return array|Medium[]
  136. */
  137. public function videos()
  138. {
  139. ksort($this->videos, SORT_NATURAL | SORT_FLAG_CASE);
  140. return $this->videos;
  141. }
  142. /**
  143. * Get a list of all audio media.
  144. *
  145. * @return array|Medium[]
  146. */
  147. public function audios()
  148. {
  149. ksort($this->audios, SORT_NATURAL | SORT_FLAG_CASE);
  150. return $this->audios;
  151. }
  152. /**
  153. * Get a list of all file media.
  154. *
  155. * @return array|Medium[]
  156. */
  157. public function files()
  158. {
  159. ksort($this->files, SORT_NATURAL | SORT_FLAG_CASE);
  160. return $this->files;
  161. }
  162. /**
  163. * @internal
  164. */
  165. protected function add($name, $file)
  166. {
  167. $this->instances[$name] = $file;
  168. switch ($file->type) {
  169. case 'image':
  170. $this->images[$name] = $file;
  171. break;
  172. case 'video':
  173. $this->videos[$name] = $file;
  174. break;
  175. case 'audio':
  176. $this->audios[$name] = $file;
  177. break;
  178. default:
  179. $this->files[$name] = $file;
  180. }
  181. }
  182. /**
  183. * Get filename, extension and meta part.
  184. *
  185. * @param string $filename
  186. * @return array
  187. */
  188. protected function getFileParts($filename)
  189. {
  190. $fileParts = explode('.', $filename);
  191. $name = array_shift($fileParts);
  192. $type = 'base';
  193. $extra = null;
  194. if (preg_match('/(.*)@(\d+)x\.(.*)$/', $filename, $matches)) {
  195. $name = $matches[1];
  196. $extension = $matches[3];
  197. $extra = (int) $matches[2];
  198. $type = 'alternative';
  199. if ($extra === 1) {
  200. $type = 'base';
  201. $extra = null;
  202. }
  203. } else {
  204. $extension = null;
  205. while (($part = array_shift($fileParts)) !== null) {
  206. if ($part != 'meta' && $part != 'thumb') {
  207. if (isset($extension)) {
  208. $name .= '.' . $extension;
  209. }
  210. $extension = $part;
  211. } else {
  212. $type = $part;
  213. $extra = '.' . $part . '.' . implode('.', $fileParts);
  214. break;
  215. }
  216. }
  217. }
  218. return array($name, $extension, $type, $extra);
  219. }
  220. }