PluginProbe
Charitable – Donation & Fundraising Platform (Donation Forms, Recurring Donations & Fundraising Campaigns) / 1.8.13
Charitable – Donation & Fundraising Platform (Donation Forms, Recurring Donations & Fundraising Campaigns) v1.8.13
1.8.13 1.8.12.3 1.8.12.2 1.8.12.1 1.8.12 1.8.11.3 1.8.11.2 1.8.11.1 1.8.11 1.6.6 1.6.60 1.6.7 1.6.8 1.6.9 1.7.0 1.7.0.1 1.7.0.11 1.7.0.12 1.7.0.14 1.7.0.2 1.7.0.3 1.7.0.5 1.7.0.6 1.7.0.7 1.7.0.9 All 211 releases
charitable / vendor / stripe / stripe-php / lib / Collection.php

Collection.php in Charitable – Donation & Fundraising Platform (Donation Forms, Recurring Donations & Fundraising Campaigns) 1.8.13, at vendor/stripe/stripe-php/lib/Collection.php

316 lines 8.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Stripe;
4
5 /**
6 * Class Collection.
7 *
8 * @template TStripeObject of StripeObject
9 * @template-implements \IteratorAggregate<TStripeObject>
10 *
11 * @property string $object
12 * @property string $url
13 * @property bool $has_more
14 * @property TStripeObject[] $data
15 */
16 class Collection extends StripeObject implements \Countable, \IteratorAggregate
17 {
18 const OBJECT_NAME = 'list';
19
20 use ApiOperations\Request;
21
22 /** @var array */
23 protected $filters = [];
24
25 /**
26 * @return string the base URL for the given class
27 */
28 public static function baseUrl()
29 {
30 return Stripe::$apiBase;
31 }
32
33 /**
34 * Returns the filters.
35 *
36 * @return array the filters
37 */
38 public function getFilters()
39 {
40 return $this->filters;
41 }
42
43 /**
44 * Sets the filters, removing paging options.
45 *
46 * @param array $filters the filters
47 */
48 public function setFilters($filters)
49 {
50 $this->filters = $filters;
51 }
52
53 /**
54 * @return mixed
55 */
56 #[\ReturnTypeWillChange]
57 public function offsetGet($k)
58 {
59 if (\is_string($k)) {
60 return parent::offsetGet($k);
61 }
62 $msg = "You tried to access the {$k} index, but Collection " .
63 'types only support string keys. (HINT: List calls ' .
64 'return an object with a `data` (which is the data ' .
65 "array). You likely want to call ->data[{$k}])";
66
67 throw new Exception\InvalidArgumentException($msg);
68 }
69
70 /**
71 * @param null|array $params
72 * @param null|array|string $opts
73 *
74 * @throws Exception\ApiErrorException
75 *
76 * @return Collection<TStripeObject>
77 */
78 public function all($params = null, $opts = null)
79 {
80 self::_validateParams($params);
81 list($url, $params) = $this->extractPathAndUpdateParams($params);
82
83 list($response, $opts) = $this->_request('get', $url, $params, $opts);
84 $obj = Util\Util::convertToStripeObject($response, $opts);
85 if (!($obj instanceof \Stripe\Collection)) {
86 throw new \Stripe\Exception\UnexpectedValueException(
87 'Expected type ' . \Stripe\Collection::class . ', got "' . \get_class($obj) . '" instead.'
88 );
89 }
90 $obj->setFilters($params);
91
92 return $obj;
93 }
94
95 /**
96 * @param null|array $params
97 * @param null|array|string $opts
98 *
99 * @throws Exception\ApiErrorException
100 *
101 * @return TStripeObject
102 */
103 public function create($params = null, $opts = null)
104 {
105 self::_validateParams($params);
106 list($url, $params) = $this->extractPathAndUpdateParams($params);
107
108 list($response, $opts) = $this->_request('post', $url, $params, $opts);
109
110 return Util\Util::convertToStripeObject($response, $opts);
111 }
112
113 /**
114 * @param string $id
115 * @param null|array $params
116 * @param null|array|string $opts
117 *
118 * @throws Exception\ApiErrorException
119 *
120 * @return TStripeObject
121 */
122 public function retrieve($id, $params = null, $opts = null)
123 {
124 self::_validateParams($params);
125 list($url, $params) = $this->extractPathAndUpdateParams($params);
126
127 $id = Util\Util::utf8($id);
128 $extn = \urlencode($id);
129 list($response, $opts) = $this->_request(
130 'get',
131 "{$url}/{$extn}",
132 $params,
133 $opts
134 );
135
136 return Util\Util::convertToStripeObject($response, $opts);
137 }
138
139 /**
140 * @return int the number of objects in the current page
141 */
142 #[\ReturnTypeWillChange]
143 public function count()
144 {
145 return \count($this->data);
146 }
147
148 /**
149 * @return \ArrayIterator an iterator that can be used to iterate
150 * across objects in the current page
151 */
152 #[\ReturnTypeWillChange]
153 public function getIterator()
154 {
155 return new \ArrayIterator($this->data);
156 }
157
158 /**
159 * @return \ArrayIterator an iterator that can be used to iterate
160 * backwards across objects in the current page
161 */
162 public function getReverseIterator()
163 {
164 return new \ArrayIterator(\array_reverse($this->data));
165 }
166
167 /**
168 * @return \Generator|TStripeObject[] A generator that can be used to
169 * iterate across all objects across all pages. As page boundaries are
170 * encountered, the next page will be fetched automatically for
171 * continued iteration.
172 */
173 public function autoPagingIterator()
174 {
175 $page = $this;
176
177 while (true) {
178 $filters = $this->filters ?: [];
179 if (\array_key_exists('ending_before', $filters)
180 && !\array_key_exists('starting_after', $filters)) {
181 foreach ($page->getReverseIterator() as $item) {
182 yield $item;
183 }
184 $page = $page->previousPage();
185 } else {
186 foreach ($page as $item) {
187 yield $item;
188 }
189 $page = $page->nextPage();
190 }
191
192 if ($page->isEmpty()) {
193 break;
194 }
195 }
196 }
197
198 /**
199 * Returns an empty collection. This is returned from {@see nextPage()}
200 * when we know that there isn't a next page in order to replicate the
201 * behavior of the API when it attempts to return a page beyond the last.
202 *
203 * @param null|array|string $opts
204 *
205 * @return Collection
206 */
207 public static function emptyCollection($opts = null)
208 {
209 return Collection::constructFrom(['data' => []], $opts);
210 }
211
212 /**
213 * Returns true if the page object contains no element.
214 *
215 * @return bool
216 */
217 public function isEmpty()
218 {
219 return empty($this->data);
220 }
221
222 /**
223 * Fetches the next page in the resource list (if there is one).
224 *
225 * This method will try to respect the limit of the current page. If none
226 * was given, the default limit will be fetched again.
227 *
228 * @param null|array $params
229 * @param null|array|string $opts
230 *
231 * @return Collection<TStripeObject>
232 */
233 public function nextPage($params = null, $opts = null)
234 {
235 if (!$this->has_more) {
236 return static::emptyCollection($opts);
237 }
238
239 $lastId = \end($this->data)->id;
240
241 $params = \array_merge(
242 $this->filters ?: [],
243 ['starting_after' => $lastId],
244 $params ?: []
245 );
246
247 return $this->all($params, $opts);
248 }
249
250 /**
251 * Fetches the previous page in the resource list (if there is one).
252 *
253 * This method will try to respect the limit of the current page. If none
254 * was given, the default limit will be fetched again.
255 *
256 * @param null|array $params
257 * @param null|array|string $opts
258 *
259 * @return Collection<TStripeObject>
260 */
261 public function previousPage($params = null, $opts = null)
262 {
263 if (!$this->has_more) {
264 return static::emptyCollection($opts);
265 }
266
267 $firstId = $this->data[0]->id;
268
269 $params = \array_merge(
270 $this->filters ?: [],
271 ['ending_before' => $firstId],
272 $params ?: []
273 );
274
275 return $this->all($params, $opts);
276 }
277
278 /**
279 * Gets the first item from the current page. Returns `null` if the current page is empty.
280 *
281 * @return null|TStripeObject
282 */
283 public function first()
284 {
285 return \count($this->data) > 0 ? $this->data[0] : null;
286 }
287
288 /**
289 * Gets the last item from the current page. Returns `null` if the current page is empty.
290 *
291 * @return null|TStripeObject
292 */
293 public function last()
294 {
295 return \count($this->data) > 0 ? $this->data[\count($this->data) - 1] : null;
296 }
297
298 private function extractPathAndUpdateParams($params)
299 {
300 $url = \parse_url($this->url);
301 if (!isset($url['path'])) {
302 throw new Exception\UnexpectedValueException("Could not parse list url into parts: {$url}");
303 }
304
305 if (isset($url['query'])) {
306 // If the URL contains a query param, parse it out into $params so they
307 // don't interact weirdly with each other.
308 $query = [];
309 \parse_str($url['query'], $query);
310 $params = \array_merge($params ?: [], $query);
311 }
312
313 return [$url['path'], $params];
314 }
315 }
316