AbstractMedia.php 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  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\Getters;
  10. use Grav\Common\Grav;
  11. use Grav\Common\Media\Interfaces\MediaCollectionInterface;
  12. use Grav\Common\Media\Interfaces\MediaObjectInterface;
  13. use Grav\Common\Utils;
  14. abstract class AbstractMedia extends Getters implements MediaCollectionInterface
  15. {
  16. protected $gettersVariable = 'instances';
  17. protected $instances = [];
  18. protected $images = [];
  19. protected $videos = [];
  20. protected $audios = [];
  21. protected $files = [];
  22. protected $media_order;
  23. /**
  24. * Get medium by filename.
  25. *
  26. * @param string $filename
  27. * @return Medium|null
  28. */
  29. public function get($filename)
  30. {
  31. return $this->offsetGet($filename);
  32. }
  33. /**
  34. * Call object as function to get medium by filename.
  35. *
  36. * @param string $filename
  37. * @return mixed
  38. */
  39. public function __invoke($filename)
  40. {
  41. return $this->offsetGet($filename);
  42. }
  43. /**
  44. * @param mixed $offset
  45. *
  46. * @return mixed
  47. */
  48. public function offsetGet($offset)
  49. {
  50. $object = parent::offsetGet($offset);
  51. // It would be nice if previous image modification would not affect the later ones.
  52. //$object = $object ? clone($object) : null;
  53. return $object;
  54. }
  55. /**
  56. * Get a list of all media.
  57. *
  58. * @return array|MediaObjectInterface[]
  59. */
  60. public function all()
  61. {
  62. $this->instances = $this->orderMedia($this->instances);
  63. return $this->instances;
  64. }
  65. /**
  66. * Get a list of all image media.
  67. *
  68. * @return array|MediaObjectInterface[]
  69. */
  70. public function images()
  71. {
  72. $this->images = $this->orderMedia($this->images);
  73. return $this->images;
  74. }
  75. /**
  76. * Get a list of all video media.
  77. *
  78. * @return array|MediaObjectInterface[]
  79. */
  80. public function videos()
  81. {
  82. $this->videos = $this->orderMedia($this->videos);
  83. return $this->videos;
  84. }
  85. /**
  86. * Get a list of all audio media.
  87. *
  88. * @return array|MediaObjectInterface[]
  89. */
  90. public function audios()
  91. {
  92. $this->audios = $this->orderMedia($this->audios);
  93. return $this->audios;
  94. }
  95. /**
  96. * Get a list of all file media.
  97. *
  98. * @return array|MediaObjectInterface[]
  99. */
  100. public function files()
  101. {
  102. $this->files = $this->orderMedia($this->files);
  103. return $this->files;
  104. }
  105. /**
  106. * @param string $name
  107. * @param MediaObjectInterface $file
  108. */
  109. protected function add($name, $file)
  110. {
  111. $this->instances[$name] = $file;
  112. switch ($file->type) {
  113. case 'image':
  114. $this->images[$name] = $file;
  115. break;
  116. case 'video':
  117. $this->videos[$name] = $file;
  118. break;
  119. case 'audio':
  120. $this->audios[$name] = $file;
  121. break;
  122. default:
  123. $this->files[$name] = $file;
  124. }
  125. }
  126. /**
  127. * Order the media based on the page's media_order
  128. *
  129. * @param $media
  130. * @return array
  131. */
  132. protected function orderMedia($media)
  133. {
  134. if (null === $this->media_order) {
  135. $page = Grav::instance()['pages']->get($this->path);
  136. if ($page && isset($page->header()->media_order)) {
  137. $this->media_order = array_map('trim', explode(',', $page->header()->media_order));
  138. }
  139. }
  140. if (!empty($this->media_order) && is_array($this->media_order)) {
  141. $media = Utils::sortArrayByArray($media, $this->media_order);
  142. } else {
  143. ksort($media, SORT_NATURAL | SORT_FLAG_CASE);
  144. }
  145. return $media;
  146. }
  147. /**
  148. * Get filename, extension and meta part.
  149. *
  150. * @param string $filename
  151. * @return array
  152. */
  153. protected function getFileParts($filename)
  154. {
  155. if (preg_match('/(.*)@(\d+)x\.(.*)$/', $filename, $matches)) {
  156. $name = $matches[1];
  157. $extension = $matches[3];
  158. $extra = (int) $matches[2];
  159. $type = 'alternative';
  160. if ($extra === 1) {
  161. $type = 'base';
  162. $extra = null;
  163. }
  164. } else {
  165. $fileParts = explode('.', $filename);
  166. $name = array_shift($fileParts);
  167. $extension = null;
  168. $extra = null;
  169. $type = 'base';
  170. while (($part = array_shift($fileParts)) !== null) {
  171. if ($part !== 'meta' && $part !== 'thumb') {
  172. if (null !== $extension) {
  173. $name .= '.' . $extension;
  174. }
  175. $extension = $part;
  176. } else {
  177. $type = $part;
  178. $extra = '.' . $part . '.' . implode('.', $fileParts);
  179. break;
  180. }
  181. }
  182. }
  183. return array($name, $extension, $type, $extra);
  184. }
  185. }