ManagesStacks.php 4.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. <?php
  2. namespace Illuminate\View\Concerns;
  3. use InvalidArgumentException;
  4. trait ManagesStacks
  5. {
  6. /**
  7. * All of the finished, captured push sections.
  8. *
  9. * @var array
  10. */
  11. protected $pushes = [];
  12. /**
  13. * All of the finished, captured prepend sections.
  14. *
  15. * @var array
  16. */
  17. protected $prepends = [];
  18. /**
  19. * The stack of in-progress push sections.
  20. *
  21. * @var array
  22. */
  23. protected $pushStack = [];
  24. /**
  25. * Start injecting content into a push section.
  26. *
  27. * @param string $section
  28. * @param string $content
  29. * @return void
  30. */
  31. public function startPush($section, $content = '')
  32. {
  33. if ($content === '') {
  34. if (ob_start()) {
  35. $this->pushStack[] = $section;
  36. }
  37. } else {
  38. $this->extendPush($section, $content);
  39. }
  40. }
  41. /**
  42. * Stop injecting content into a push section.
  43. *
  44. * @return string
  45. * @throws \InvalidArgumentException
  46. */
  47. public function stopPush()
  48. {
  49. if (empty($this->pushStack)) {
  50. throw new InvalidArgumentException('Cannot end a push stack without first starting one.');
  51. }
  52. return tap(array_pop($this->pushStack), function ($last) {
  53. $this->extendPush($last, ob_get_clean());
  54. });
  55. }
  56. /**
  57. * Append content to a given push section.
  58. *
  59. * @param string $section
  60. * @param string $content
  61. * @return void
  62. */
  63. protected function extendPush($section, $content)
  64. {
  65. if (! isset($this->pushes[$section])) {
  66. $this->pushes[$section] = [];
  67. }
  68. if (! isset($this->pushes[$section][$this->renderCount])) {
  69. $this->pushes[$section][$this->renderCount] = $content;
  70. } else {
  71. $this->pushes[$section][$this->renderCount] .= $content;
  72. }
  73. }
  74. /**
  75. * Start prepending content into a push section.
  76. *
  77. * @param string $section
  78. * @param string $content
  79. * @return void
  80. */
  81. public function startPrepend($section, $content = '')
  82. {
  83. if ($content === '') {
  84. if (ob_start()) {
  85. $this->pushStack[] = $section;
  86. }
  87. } else {
  88. $this->extendPrepend($section, $content);
  89. }
  90. }
  91. /**
  92. * Stop prepending content into a push section.
  93. *
  94. * @return string
  95. * @throws \InvalidArgumentException
  96. */
  97. public function stopPrepend()
  98. {
  99. if (empty($this->pushStack)) {
  100. throw new InvalidArgumentException('Cannot end a prepend operation without first starting one.');
  101. }
  102. return tap(array_pop($this->pushStack), function ($last) {
  103. $this->extendPrepend($last, ob_get_clean());
  104. });
  105. }
  106. /**
  107. * Prepend content to a given stack.
  108. *
  109. * @param string $section
  110. * @param string $content
  111. * @return void
  112. */
  113. protected function extendPrepend($section, $content)
  114. {
  115. if (! isset($this->prepends[$section])) {
  116. $this->prepends[$section] = [];
  117. }
  118. if (! isset($this->prepends[$section][$this->renderCount])) {
  119. $this->prepends[$section][$this->renderCount] = $content;
  120. } else {
  121. $this->prepends[$section][$this->renderCount] = $content.$this->prepends[$section][$this->renderCount];
  122. }
  123. }
  124. /**
  125. * Get the string contents of a push section.
  126. *
  127. * @param string $section
  128. * @param string $default
  129. * @return string
  130. */
  131. public function yieldPushContent($section, $default = '')
  132. {
  133. if (! isset($this->pushes[$section]) && ! isset($this->prepends[$section])) {
  134. return $default;
  135. }
  136. $output = '';
  137. if (isset($this->prepends[$section])) {
  138. $output .= implode(array_reverse($this->prepends[$section]));
  139. }
  140. if (isset($this->pushes[$section])) {
  141. $output .= implode($this->pushes[$section]);
  142. }
  143. return $output;
  144. }
  145. /**
  146. * Flush all of the stacks.
  147. *
  148. * @return void
  149. */
  150. public function flushStacks()
  151. {
  152. $this->pushes = [];
  153. $this->prepends = [];
  154. $this->pushStack = [];
  155. }
  156. }