elements
+ $complexSelectors['+'] = function (array $parts, \DOMNode $context, callable $add = null) use (&$getMatchingElements, &$isMatchingElement) {
+ $elements = null;
+ foreach ($parts as $part) {
+ if ($elements === null) {
+ $elements = $getMatchingElements($context, $part);
+ } else {
+ $temp = [];
+ foreach ($elements as $element) {
+ if ($element->nextSibling !== null && $isMatchingElement($element->nextSibling, $part)) {
+ $temp[] = $element->nextSibling;
+ }
+ }
+ $elements = $temp;
+ }
+ }
+ foreach ($elements as $element) {
+ $add($element);
+ }
+ };
+
+ // p ~ ul - all
elements that are preceded by a element
+ $complexSelectors['~'] = function (array $parts, \DOMNode $context, callable $add = null) use (&$getMatchingElements, &$isMatchingElement) {
+ $elements = null;
+ foreach ($parts as $part) {
+ if ($elements === null) {
+ $elements = $getMatchingElements($context, $part);
+ } else {
+ $temp = [];
+ foreach ($elements as $element) {
+ $nextSibling = $element->nextSibling;
+ while ($nextSibling !== null) {
+ if ($isMatchingElement($nextSibling, $part)) {
+ $temp[] = $nextSibling;
+ }
+ $nextSibling = $nextSibling->nextSibling;
+ }
+ }
+ $elements = $temp;
+ }
+ }
+ foreach ($elements as $element) {
+ $add($element);
+ }
+ };
+
+ $result = $getMatchingElements($this, $selector, $preferredLimit);
+ if ($result === false) {
+ throw new \InvalidArgumentException('Unsupported selector (' . $selector . ')');
+ }
+ return new \IvoPetkov\HTML5DOMNodeList($result);
+ }
+}
diff --git a/web/app/vendor/ivopetkov/html5-dom-document-php/src/HTML5DOMElement.php b/web/app/vendor/ivopetkov/html5-dom-document-php/src/HTML5DOMElement.php
new file mode 100644
index 0000000..6647c8c
--- /dev/null
+++ b/web/app/vendor/ivopetkov/html5-dom-document-php/src/HTML5DOMElement.php
@@ -0,0 +1,240 @@
+firstChild === null) {
+ return '';
+ }
+ $html = $this->ownerDocument->saveHTML($this);
+ $nodeName = $this->nodeName;
+ return preg_replace('@^<' . $nodeName . '[^>]*>|' . $nodeName . '>$@', '', $html);
+ } elseif ($name === 'outerHTML') {
+ if ($this->firstChild === null) {
+ $nodeName = $this->nodeName;
+ $attributes = $this->getAttributes();
+ $result = '<' . $nodeName . '';
+ foreach ($attributes as $name => $value) {
+ $result .= ' ' . $name . '="' . htmlentities($value) . '"';
+ }
+ if (array_search($nodeName, ['area', 'base', 'br', 'col', 'command', 'embed', 'hr', 'img', 'input', 'keygen', 'link', 'meta', 'param', 'source', 'track', 'wbr']) === false) {
+ $result .= '>' . $nodeName . '>';
+ } else {
+ $result .= '/>';
+ }
+ return $result;
+ }
+ return $this->ownerDocument->saveHTML($this);
+ } elseif ($name === 'classList') {
+ if ($this->classList === null) {
+ $this->classList = new HTML5DOMTokenList($this, 'class');
+ }
+ return $this->classList;
+ }
+ throw new \Exception('Undefined property: HTML5DOMElement::$' . $name);
+ }
+
+ /**
+ * Sets the value for the property specified.
+ *
+ * @param string $name
+ * @param string $value
+ * @throws \Exception
+ */
+ public function __set(string $name, $value)
+ {
+ if ($name === 'innerHTML') {
+ while ($this->hasChildNodes()) {
+ $this->removeChild($this->firstChild);
+ }
+ if (!isset(self::$newObjectsCache['html5domdocument'])) {
+ self::$newObjectsCache['html5domdocument'] = new \IvoPetkov\HTML5DOMDocument();
+ }
+ $tmpDoc = clone (self::$newObjectsCache['html5domdocument']);
+ $tmpDoc->loadHTML('
' . $value . '', HTML5DOMDocument::ALLOW_DUPLICATE_IDS);
+ foreach ($tmpDoc->getElementsByTagName('body')->item(0)->childNodes as $node) {
+ $node = $this->ownerDocument->importNode($node, true);
+ $this->appendChild($node);
+ }
+ return;
+ } elseif ($name === 'outerHTML') {
+ if (!isset(self::$newObjectsCache['html5domdocument'])) {
+ self::$newObjectsCache['html5domdocument'] = new \IvoPetkov\HTML5DOMDocument();
+ }
+ $tmpDoc = clone (self::$newObjectsCache['html5domdocument']);
+ $tmpDoc->loadHTML('' . $value . '', HTML5DOMDocument::ALLOW_DUPLICATE_IDS);
+ foreach ($tmpDoc->getElementsByTagName('body')->item(0)->childNodes as $node) {
+ $node = $this->ownerDocument->importNode($node, true);
+ $this->parentNode->insertBefore($node, $this);
+ }
+ $this->parentNode->removeChild($this);
+ return;
+ } elseif ($name === 'classList') {
+ $this->setAttribute('class', $value);
+ return;
+ }
+ throw new \Exception('Undefined property: HTML5DOMElement::$' . $name);
+ }
+
+ /**
+ * Updates the result value before returning it.
+ *
+ * @param string $value
+ * @return string The updated value
+ */
+ private function updateResult(string $value): string
+ {
+ $value = str_replace(self::$foundEntitiesCache[0], self::$foundEntitiesCache[1], $value);
+ if (strstr($value, 'html5-dom-document-internal-entity') !== false) {
+ $search = [];
+ $replace = [];
+ $matches = [];
+ preg_match_all('/html5-dom-document-internal-entity([12])-(.*?)-end/', $value, $matches);
+ $matches[0] = array_unique($matches[0]);
+ foreach ($matches[0] as $i => $match) {
+ $search[] = $match;
+ $replace[] = html_entity_decode(($matches[1][$i] === '1' ? '&' : '') . $matches[2][$i] . ';');
+ }
+ $value = str_replace($search, $replace, $value);
+ self::$foundEntitiesCache[0] = array_merge(self::$foundEntitiesCache[0], $search);
+ self::$foundEntitiesCache[1] = array_merge(self::$foundEntitiesCache[1], $replace);
+ unset($search);
+ unset($replace);
+ unset($matches);
+ }
+ return $value;
+ }
+
+ /**
+ * Returns the updated nodeValue Property
+ *
+ * @return string The updated $nodeValue
+ */
+ public function getNodeValue(): string
+ {
+ return $this->updateResult($this->nodeValue);
+ }
+
+ /**
+ * Returns the updated $textContent Property
+ *
+ * @return string The updated $textContent
+ */
+ public function getTextContent(): string
+ {
+ return $this->updateResult($this->textContent);
+ }
+
+ /**
+ * Returns the value for the attribute name specified.
+ *
+ * @param string $name The attribute name.
+ * @return string The attribute value.
+ * @throws \InvalidArgumentException
+ */
+ public function getAttribute($name): string
+ {
+ if ($this->attributes->length === 0) { // Performance optimization
+ return '';
+ }
+ $value = parent::getAttribute($name);
+ return $value !== '' ? (strstr($value, 'html5-dom-document-internal-entity') !== false ? $this->updateResult($value) : $value) : '';
+ }
+
+ /**
+ * Returns an array containing all attributes.
+ *
+ * @return array An associative array containing all attributes.
+ */
+ public function getAttributes(): array
+ {
+ $attributes = [];
+ foreach ($this->attributes as $attributeName => $attribute) {
+ $value = $attribute->value;
+ $attributes[$attributeName] = $value !== '' ? (strstr($value, 'html5-dom-document-internal-entity') !== false ? $this->updateResult($value) : $value) : '';
+ }
+ return $attributes;
+ }
+
+ /**
+ * Returns the element outerHTML.
+ *
+ * @return string The element outerHTML.
+ */
+ public function __toString(): string
+ {
+ return $this->outerHTML;
+ }
+
+ /**
+ * Returns the first child element matching the selector.
+ *
+ * @param string $selector A CSS query selector. Available values: *, tagname, tagname#id, #id, tagname.classname, .classname, tagname.classname.classname2, .classname.classname2, tagname[attribute-selector], [attribute-selector], "div, p", div p, div > p, div + p and p ~ ul.
+ * @return HTML5DOMElement|null The result DOMElement or null if not found.
+ * @throws \InvalidArgumentException
+ */
+ public function querySelector(string $selector)
+ {
+ return $this->internalQuerySelector($selector);
+ }
+
+ /**
+ * Returns a list of children elements matching the selector.
+ *
+ * @param string $selector A CSS query selector. Available values: *, tagname, tagname#id, #id, tagname.classname, .classname, tagname.classname.classname2, .classname.classname2, tagname[attribute-selector], [attribute-selector], "div, p", div p, div > p, div + p and p ~ ul.
+ * @return HTML5DOMNodeList Returns a list of DOMElements matching the criteria.
+ * @throws \InvalidArgumentException
+ */
+ public function querySelectorAll(string $selector)
+ {
+ return $this->internalQuerySelectorAll($selector);
+ }
+}
diff --git a/web/app/vendor/ivopetkov/html5-dom-document-php/src/HTML5DOMNodeList.php b/web/app/vendor/ivopetkov/html5-dom-document-php/src/HTML5DOMNodeList.php
new file mode 100644
index 0000000..dc07236
--- /dev/null
+++ b/web/app/vendor/ivopetkov/html5-dom-document-php/src/HTML5DOMNodeList.php
@@ -0,0 +1,45 @@
+offsetExists($index) ? $this->offsetGet($index) : null;
+ }
+
+ /**
+ * Returns the value for the property specified.
+ *
+ * @param string $name The name of the property.
+ * @return mixed
+ * @throws \Exception
+ */
+ public function __get(string $name)
+ {
+ if ($name === 'length') {
+ return sizeof($this);
+ }
+ throw new \Exception('Undefined property: \IvoPetkov\HTML5DOMNodeList::$' . $name);
+ }
+}
diff --git a/web/app/vendor/ivopetkov/html5-dom-document-php/src/HTML5DOMTokenList.php b/web/app/vendor/ivopetkov/html5-dom-document-php/src/HTML5DOMTokenList.php
new file mode 100644
index 0000000..e917ab4
--- /dev/null
+++ b/web/app/vendor/ivopetkov/html5-dom-document-php/src/HTML5DOMTokenList.php
@@ -0,0 +1,266 @@
+element = $element;
+ $this->attributeName = $attributeName;
+ $this->previousValue = null;
+ $this->tokenize();
+ }
+
+ /**
+ * Adds the given tokens to the list.
+ *
+ * @param string[] $tokens The tokens you want to add to the list.
+ * @return void
+ */
+ public function add(string ...$tokens)
+ {
+ if (count($tokens) === 0) {
+ return;
+ }
+ foreach ($tokens as $t) {
+ if (in_array($t, $this->tokens)) {
+ continue;
+ }
+ $this->tokens[] = $t;
+ }
+ $this->setAttributeValue();
+ }
+
+ /**
+ * Removes the specified tokens from the list. If the string does not exist in the list, no error is thrown.
+ *
+ * @param string[] $tokens The token you want to remove from the list.
+ * @return void
+ */
+ public function remove(string ...$tokens)
+ {
+ if (count($tokens) === 0) {
+ return;
+ }
+ if (count($this->tokens) === 0) {
+ return;
+ }
+ foreach ($tokens as $t) {
+ $i = array_search($t, $this->tokens);
+ if ($i === false) {
+ continue;
+ }
+ array_splice($this->tokens, $i, 1);
+ }
+ $this->setAttributeValue();
+ }
+
+ /**
+ * Returns an item in the list by its index (returns null if the number is greater than or equal to the length of the list).
+ *
+ * @param int $index The zero-based index of the item you want to return.
+ * @return null|string
+ */
+ public function item(int $index)
+ {
+ $this->tokenize();
+ if ($index >= count($this->tokens)) {
+ return null;
+ }
+ return $this->tokens[$index];
+ }
+
+ /**
+ * Removes a given token from the list and returns false. If token doesn't exist it's added and the function returns true.
+ *
+ * @param string $token The token you want to toggle.
+ * @param bool $force A Boolean that, if included, turns the toggle into a one way-only operation. If set to false, the token will only be removed but not added again. If set to true, the token will only be added but not removed again.
+ * @return bool false if the token is not in the list after the call, or true if the token is in the list after the call.
+ */
+ public function toggle(string $token, bool $force = null): bool
+ {
+ $this->tokenize();
+ $isThereAfter = false;
+ $i = array_search($token, $this->tokens);
+ if (is_null($force)) {
+ if ($i === false) {
+ $this->tokens[] = $token;
+ $isThereAfter = true;
+ } else {
+ array_splice($this->tokens, $i, 1);
+ }
+ } else {
+ if ($force) {
+ if ($i === false) {
+ $this->tokens[] = $token;
+ }
+ $isThereAfter = true;
+ } else {
+ if ($i !== false) {
+ array_splice($this->tokens, $i, 1);
+ }
+ }
+ }
+ $this->setAttributeValue();
+ return $isThereAfter;
+ }
+
+ /**
+ * Returns true if the list contains the given token, otherwise false.
+ *
+ * @param string $token The token you want to check for the existence of in the list.
+ * @return bool true if the list contains the given token, otherwise false.
+ */
+ public function contains(string $token): bool
+ {
+ $this->tokenize();
+ return in_array($token, $this->tokens);
+ }
+
+ /**
+ * Replaces an existing token with a new token.
+ *
+ * @param string $old The token you want to replace.
+ * @param string $new The token you want to replace $old with.
+ * @return void
+ */
+ public function replace(string $old, string $new)
+ {
+ if ($old === $new) {
+ return;
+ }
+ $this->tokenize();
+ $i = array_search($old, $this->tokens);
+ if ($i !== false) {
+ $j = array_search($new, $this->tokens);
+ if ($j === false) {
+ $this->tokens[$i] = $new;
+ } else {
+ array_splice($this->tokens, $i, 1);
+ }
+ $this->setAttributeValue();
+ }
+ }
+
+ /**
+ *
+ * @return string
+ */
+ public function __toString(): string
+ {
+ $this->tokenize();
+ return implode(' ', $this->tokens);
+ }
+
+ /**
+ * Returns an iterator allowing you to go through all tokens contained in the list.
+ *
+ * @return ArrayIterator
+ */
+ public function entries(): ArrayIterator
+ {
+ $this->tokenize();
+ return new ArrayIterator($this->tokens);
+ }
+
+ /**
+ * Returns the value for the property specified
+ *
+ * @param string $name The name of the property
+ * @return string The value of the property specified
+ * @throws \Exception
+ */
+ public function __get(string $name)
+ {
+ if ($name === 'length') {
+ $this->tokenize();
+ return count($this->tokens);
+ } elseif ($name === 'value') {
+ return $this->__toString();
+ }
+ throw new \Exception('Undefined property: HTML5DOMTokenList::$' . $name);
+ }
+
+ /**
+ *
+ * @return void
+ */
+ private function tokenize()
+ {
+ $current = $this->element->getAttribute($this->attributeName);
+ if ($this->previousValue === $current) {
+ return;
+ }
+ $this->previousValue = $current;
+ $tokens = explode(' ', $current);
+ $finals = [];
+ foreach ($tokens as $token) {
+ if ($token === '') {
+ continue;
+ }
+ if (in_array($token, $finals)) {
+ continue;
+ }
+ $finals[] = $token;
+ }
+ $this->tokens = $finals;
+ }
+
+ /**
+ *
+ * @return void
+ */
+ private function setAttributeValue()
+ {
+ $value = implode(' ', $this->tokens);
+ if ($this->previousValue === $value) {
+ return;
+ }
+ $this->previousValue = $value;
+ $this->element->setAttribute($this->attributeName, $value);
+ }
+}
diff --git a/web/app/vendor/php-curl-class/php-curl-class/.gitignore b/web/app/vendor/php-curl-class/php-curl-class/.gitignore
new file mode 100644
index 0000000..d1502b0
--- /dev/null
+++ b/web/app/vendor/php-curl-class/php-curl-class/.gitignore
@@ -0,0 +1,2 @@
+vendor/
+composer.lock
diff --git a/web/app/vendor/php-curl-class/php-curl-class/.travis.yml b/web/app/vendor/php-curl-class/php-curl-class/.travis.yml
new file mode 100644
index 0000000..a915771
--- /dev/null
+++ b/web/app/vendor/php-curl-class/php-curl-class/.travis.yml
@@ -0,0 +1,19 @@
+language: php
+php:
+ - 5.3
+ - 5.4
+ - 5.5
+ - 5.6
+ - hhvm
+matrix:
+ allow_failures:
+ - php: 5.6
+ - php: hhvm
+before_script:
+ - if [[ "$TRAVIS_PHP_VERSION" == "5.4" ]]; then sh -c "php -S 127.0.0.1:8000 -t tests/PHPCurlClass/ &"; fi
+ - if [[ "$TRAVIS_PHP_VERSION" == "5.5" ]]; then sh -c "php -S 127.0.0.1:8000 -t tests/PHPCurlClass/ &"; fi
+ - if [[ "$TRAVIS_PHP_VERSION" == "5.6" ]]; then sh -c "php -S 127.0.0.1:8000 -t tests/PHPCurlClass/ &"; fi
+ - if [[ "$TRAVIS_PHP_VERSION" == "hhvm" ]]; then sh -c "cd tests && hhvm --mode server --port 8000 --config PHPCurlClass/server.hdf &"; fi
+script:
+ - php -l src/*
+ - if [[ "$TRAVIS_PHP_VERSION" != "5.3" ]]; then sh -c "cd tests && phpunit --configuration phpunit.xml"; fi
diff --git a/web/app/vendor/php-curl-class/php-curl-class/LICENSE b/web/app/vendor/php-curl-class/php-curl-class/LICENSE
new file mode 100644
index 0000000..68a49da
--- /dev/null
+++ b/web/app/vendor/php-curl-class/php-curl-class/LICENSE
@@ -0,0 +1,24 @@
+This is free and unencumbered software released into the public domain.
+
+Anyone is free to copy, modify, publish, use, compile, sell, or
+distribute this software, either in source code form or as a compiled
+binary, for any purpose, commercial or non-commercial, and by any
+means.
+
+In jurisdictions that recognize copyright laws, the author or authors
+of this software dedicate any and all copyright interest in the
+software to the public domain. We make this dedication for the benefit
+of the public at large and to the detriment of our heirs and
+successors. We intend this dedication to be an overt act of
+relinquishment in perpetuity of all present and future rights to this
+software under copyright law.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+For more information, please refer to
diff --git a/web/app/vendor/php-curl-class/php-curl-class/README.md b/web/app/vendor/php-curl-class/php-curl-class/README.md
new file mode 100644
index 0000000..5934471
--- /dev/null
+++ b/web/app/vendor/php-curl-class/php-curl-class/README.md
@@ -0,0 +1,136 @@
+# php-curl-class
+
+[![Build Status](https://travis-ci.org/php-curl-class/php-curl-class.png?branch=master)](https://travis-ci.org/php-curl-class/php-curl-class)
+
+PHP Curl Class is an object-oriented wrapper of the PHP cURL extension.
+
+### Composer
+
+ $ composer require php-curl-class/php-curl-class
+
+### Quick Start and Examples
+
+```php
+require 'Curl.class.php';
+
+$curl = new Curl();
+$curl->get('http://www.example.com/');
+```
+
+```php
+$curl = new Curl();
+$curl->get('http://www.example.com/search', array(
+ 'q' => 'keyword',
+));
+```
+
+```php
+$curl = new Curl();
+$curl->post('http://www.example.com/login/', array(
+ 'username' => 'myusername',
+ 'password' => 'mypassword',
+));
+```
+
+```php
+$curl = new Curl();
+$curl->setBasicAuthentication('username', 'password');
+$curl->setUserAgent('');
+$curl->setReferrer('');
+$curl->setHeader('X-Requested-With', 'XMLHttpRequest');
+$curl->setCookie('key', 'value');
+$curl->get('http://www.example.com/');
+
+if ($curl->error) {
+ echo $curl->error_code;
+}
+else {
+ echo $curl->response;
+}
+
+var_dump($curl->request_headers);
+var_dump($curl->response_headers);
+```
+
+```php
+$curl = new Curl();
+$curl->setOpt(CURLOPT_SSL_VERIFYPEER, false);
+$curl->get('https://encrypted.example.com/');
+```
+
+```php
+$curl = new Curl();
+$curl->put('http://api.example.com/user/', array(
+ 'first_name' => 'Zach',
+ 'last_name' => 'Borboa',
+));
+```
+
+```php
+$curl = new Curl();
+$curl->patch('http://api.example.com/profile/', array(
+ 'image' => '@path/to/file.jpg',
+));
+```
+
+```php
+$curl = new Curl();
+$curl->delete('http://api.example.com/user/', array(
+ 'id' => '1234',
+));
+```
+
+```php
+// Enable gzip compression.
+$curl = new Curl();
+$curl->setOpt(CURLOPT_ENCODING , 'gzip');
+$curl->get('https://www.example.com/image.png');
+```
+
+```php
+// Case-insensitive access to headers.
+$curl = new Curl();
+$curl->get('https://www.example.com/image.png');
+echo $curl->response_headers['Content-Type'] . "\n"; // image/png
+echo $curl->response_headers['CoNTeNT-TyPE'] . "\n"; // image/png
+```
+
+```php
+$curl->close();
+```
+
+```php
+// Example access to curl object.
+curl_set_opt($curl->curl, CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1');
+curl_close($curl->curl);
+```
+
+```php
+// Requests in parallel with callback functions.
+$curl = new Curl();
+$curl->setOpt(CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1');
+
+$curl->success(function($instance) {
+ echo 'call was successful. response was' . "\n";
+ echo $instance->response . "\n";
+});
+$curl->error(function($instance) {
+ echo 'call was unsuccessful.' . "\n";
+ echo 'error code:' . $instance->error_code . "\n";
+ echo 'error message:' . $instance->error_message . "\n";
+});
+$curl->complete(function($instance) {
+ echo 'call completed' . "\n";
+});
+
+$curl->get(array(
+ 'https://duckduckgo.com/',
+ 'https://search.yahoo.com/search',
+ 'https://www.bing.com/search',
+ 'http://www.dogpile.com/search/web',
+ 'https://www.google.com/search',
+ 'https://www.wolframalpha.com/input/',
+), array(
+ 'q' => 'hello world',
+));
+```
diff --git a/web/app/vendor/php-curl-class/php-curl-class/composer.json b/web/app/vendor/php-curl-class/php-curl-class/composer.json
new file mode 100644
index 0000000..007da18
--- /dev/null
+++ b/web/app/vendor/php-curl-class/php-curl-class/composer.json
@@ -0,0 +1,7 @@
+{
+ "name": "php-curl-class/php-curl-class",
+ "description": "PHP Curl Class is an object-oriented wrapper of the PHP cURL extension.",
+ "autoload": {
+ "classmap": ["src/"]
+ }
+}
diff --git a/web/app/vendor/php-curl-class/php-curl-class/examples/coinbase_account_balance.php b/web/app/vendor/php-curl-class/php-curl-class/examples/coinbase_account_balance.php
new file mode 100644
index 0000000..b45add8
--- /dev/null
+++ b/web/app/vendor/php-curl-class/php-curl-class/examples/coinbase_account_balance.php
@@ -0,0 +1,22 @@
+setHeader('ACCESS_KEY', API_KEY);
+$curl->setHeader('ACCESS_SIGNATURE', $signature);
+$curl->setHeader('ACCESS_NONCE', $nonce);
+$curl->get($url);
+
+echo
+ 'My current account balance at Coinbase is ' .
+ $curl->response->amount . ' ' . $curl->response->currency . '.' . "\n";
diff --git a/web/app/vendor/php-curl-class/php-curl-class/examples/coinbase_spot_rate.php b/web/app/vendor/php-curl-class/php-curl-class/examples/coinbase_spot_rate.php
new file mode 100644
index 0000000..f84e450
--- /dev/null
+++ b/web/app/vendor/php-curl-class/php-curl-class/examples/coinbase_spot_rate.php
@@ -0,0 +1,10 @@
+get('https://coinbase.com/api/v1/prices/spot_rate');
+
+echo
+ 'The current price of bitcoin at Coinbase is ' .
+ '$' . $curl->response->amount . ' ' . $curl->response->currency . '.' . "\n";
diff --git a/web/app/vendor/php-curl-class/php-curl-class/examples/instagram_search_photos.php b/web/app/vendor/php-curl-class/php-curl-class/examples/instagram_search_photos.php
new file mode 100644
index 0000000..dad8d96
--- /dev/null
+++ b/web/app/vendor/php-curl-class/php-curl-class/examples/instagram_search_photos.php
@@ -0,0 +1,17 @@
+get('https://api.instagram.com/v1/media/search', array(
+ 'client_id' => INSTAGRAM_CLIENT_ID,
+ 'lat' => '37.8296',
+ 'lng' => '-122.4832',
+));
+
+foreach ($curl->response->data as $media) {
+ $image = $media->images->low_resolution;
+ echo '';
+}
diff --git a/web/app/vendor/php-curl-class/php-curl-class/examples/put.php b/web/app/vendor/php-curl-class/php-curl-class/examples/put.php
new file mode 100644
index 0000000..f06e14c
--- /dev/null
+++ b/web/app/vendor/php-curl-class/php-curl-class/examples/put.php
@@ -0,0 +1,14 @@
+put('http://httpbin.org/put', array(
+ 'id' => 1,
+ 'first_name' => 'Zach',
+ 'last_name' => 'Borboa',
+));
+
+echo 'Data server received via PUT:' . "\n";
+var_dump($curl->response->form);
diff --git a/web/app/vendor/php-curl-class/php-curl-class/examples/twitter_post_tweet.php b/web/app/vendor/php-curl-class/php-curl-class/examples/twitter_post_tweet.php
new file mode 100644
index 0000000..18b7671
--- /dev/null
+++ b/web/app/vendor/php-curl-class/php-curl-class/examples/twitter_post_tweet.php
@@ -0,0 +1,35 @@
+ API_KEY,
+ 'oauth_nonce' => md5(microtime() . mt_rand()),
+ 'oauth_signature_method' => 'HMAC-SHA1',
+ 'oauth_timestamp' => time(),
+ 'oauth_token' => OAUTH_ACCESS_TOKEN,
+ 'oauth_version' => '1.0',
+ 'status' => $status,
+);
+
+$url = 'https://api.twitter.com/1.1/statuses/update.json';
+$request = implode('&', array(
+ 'POST',
+ rawurlencode($url),
+ rawurlencode(http_build_query($oauth_data, '', '&', PHP_QUERY_RFC3986)),
+));
+$key = implode('&', array(API_SECRET, OAUTH_TOKEN_SECRET));
+$oauth_data['oauth_signature'] = base64_encode(hash_hmac('sha1', $request, $key, true));
+$data = http_build_query($oauth_data, '', '&');
+
+$curl = new Curl();
+$curl->post($url, $data);
+
+echo 'Posted "' . $curl->response->text . '" at ' . $curl->response->created_at . '.' . "\n";
diff --git a/web/app/vendor/php-curl-class/php-curl-class/src/Curl.class.php b/web/app/vendor/php-curl-class/php-curl-class/src/Curl.class.php
new file mode 100644
index 0000000..26209ba
--- /dev/null
+++ b/web/app/vendor/php-curl-class/php-curl-class/src/Curl.class.php
@@ -0,0 +1,496 @@
+curl = curl_init();
+ $this->setUserAgent(self::USER_AGENT);
+ $this->setOpt(CURLINFO_HEADER_OUT, true);
+ $this->setOpt(CURLOPT_HEADER, true);
+ $this->setOpt(CURLOPT_RETURNTRANSFER, true);
+ }
+
+ public function get($url_mixed, $data = array())
+ {
+ if (is_array($url_mixed)) {
+ $curl_multi = curl_multi_init();
+ $this->multi_parent = true;
+
+ $this->curls = array();
+
+ foreach ($url_mixed as $url) {
+ $curl = new Curl();
+ $curl->multi_child = true;
+ $curl->setOpt(CURLOPT_URL, $this->buildURL($url, $data), $curl->curl);
+ $curl->setOpt(CURLOPT_CUSTOMREQUEST, 'GET');
+ $curl->setOpt(CURLOPT_HTTPGET, true);
+ $this->call($this->before_send_function, $curl);
+ $this->curls[] = $curl;
+
+ $curlm_error_code = curl_multi_add_handle($curl_multi, $curl->curl);
+ if (!($curlm_error_code === CURLM_OK)) {
+ throw new \ErrorException('cURL multi add handle error: ' . curl_multi_strerror($curlm_error_code));
+ }
+ }
+
+ foreach ($this->curls as $ch) {
+ foreach ($this->options as $key => $value) {
+ $ch->setOpt($key, $value);
+ }
+ }
+
+ do {
+ $status = curl_multi_exec($curl_multi, $active);
+ } while ($status === CURLM_CALL_MULTI_PERFORM || $active);
+
+ foreach ($this->curls as $ch) {
+ $this->exec($ch);
+ }
+ } else {
+ $this->setopt(CURLOPT_URL, $this->buildURL($url_mixed, $data));
+ $this->setOpt(CURLOPT_CUSTOMREQUEST, 'GET');
+ $this->setopt(CURLOPT_HTTPGET, true);
+ return $this->exec();
+ }
+ }
+
+ public function post($url, $data = array())
+ {
+ if (is_array($data) && empty($data)) {
+ $this->setHeader('Content-Length');
+ }
+
+ $this->setOpt(CURLOPT_URL, $this->buildURL($url));
+ $this->setOpt(CURLOPT_CUSTOMREQUEST, 'POST');
+ $this->setOpt(CURLOPT_POST, true);
+ $this->setOpt(CURLOPT_POSTFIELDS, $this->postfields($data));
+ return $this->exec();
+ }
+
+ public function put($url, $data = array())
+ {
+ $this->setOpt(CURLOPT_URL, $url);
+ $this->setOpt(CURLOPT_CUSTOMREQUEST, 'PUT');
+ $put_data = http_build_query($data);
+ if (empty($this->options[CURLOPT_INFILE]) && empty($this->options[CURLOPT_INFILESIZE])) {
+ $this->setHeader('Content-Length', strlen($put_data));
+ }
+ $this->setOpt(CURLOPT_POSTFIELDS, $put_data);
+ return $this->exec();
+ }
+
+ public function patch($url, $data = array())
+ {
+ $this->setHeader('Content-Length');
+ $this->setOpt(CURLOPT_URL, $this->buildURL($url));
+ $this->setOpt(CURLOPT_CUSTOMREQUEST, 'PATCH');
+ $this->setOpt(CURLOPT_POSTFIELDS, $data);
+ return $this->exec();
+ }
+
+ public function delete($url, $data = array())
+ {
+ $this->setHeader('Content-Length');
+ $this->setOpt(CURLOPT_URL, $this->buildURL($url, $data));
+ $this->setOpt(CURLOPT_CUSTOMREQUEST, 'DELETE');
+ return $this->exec();
+ }
+
+ public function head($url, $data = array())
+ {
+ $this->setOpt(CURLOPT_URL, $this->buildURL($url, $data));
+ $this->setOpt(CURLOPT_CUSTOMREQUEST, 'HEAD');
+ $this->setOpt(CURLOPT_NOBODY, true);
+ return $this->exec();
+ }
+
+ public function options($url, $data = array())
+ {
+ $this->setHeader('Content-Length');
+ $this->setOpt(CURLOPT_URL, $this->buildURL($url, $data));
+ $this->setOpt(CURLOPT_CUSTOMREQUEST, 'OPTIONS');
+ return $this->exec();
+ }
+
+ public function setBasicAuthentication($username, $password)
+ {
+ $this->setOpt(CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
+ $this->setOpt(CURLOPT_USERPWD, $username . ':' . $password);
+ }
+
+ public function setHeader($key, $value = '')
+ {
+ $this->headers[$key] = $key . ': ' . $value;
+ $this->setOpt(CURLOPT_HTTPHEADER, array_values($this->headers));
+ }
+
+ public function setUserAgent($user_agent)
+ {
+ $this->setOpt(CURLOPT_USERAGENT, $user_agent);
+ }
+
+ public function setReferrer($referrer)
+ {
+ $this->setOpt(CURLOPT_REFERER, $referrer);
+ }
+
+ public function setCookie($key, $value)
+ {
+ $this->cookies[$key] = $value;
+ $this->setOpt(CURLOPT_COOKIE, http_build_query($this->cookies, '', '; '));
+ }
+
+ public function setCookieFile($cookie_file)
+ {
+ $this->setOpt(CURLOPT_COOKIEFILE, $cookie_file);
+ }
+
+ public function setCookieJar($cookie_jar)
+ {
+ $this->setOpt(CURLOPT_COOKIEJAR, $cookie_jar);
+ }
+
+ public function setOpt($option, $value, $_ch = null)
+ {
+ $ch = is_null($_ch) ? $this->curl : $_ch;
+
+ $required_options = array(
+ CURLINFO_HEADER_OUT => 'CURLINFO_HEADER_OUT',
+ CURLOPT_HEADER => 'CURLOPT_HEADER',
+ CURLOPT_RETURNTRANSFER => 'CURLOPT_RETURNTRANSFER',
+ );
+
+ if (in_array($option, array_keys($required_options), true) && !($value === true)) {
+ trigger_error($required_options[$option] . ' is a required option', E_USER_WARNING);
+ }
+
+ $this->options[$option] = $value;
+ return curl_setopt($ch, $option, $value);
+ }
+
+ public function verbose($on = true)
+ {
+ $this->setOpt(CURLOPT_VERBOSE, $on);
+ }
+
+ public function close()
+ {
+ if ($this->multi_parent) {
+ foreach ($this->curls as $curl) {
+ $curl->close();
+ }
+ }
+
+ if (is_resource($this->curl)) {
+ curl_close($this->curl);
+ }
+ }
+
+ public function beforeSend($function)
+ {
+ $this->before_send_function = $function;
+ }
+
+ public function success($callback)
+ {
+ $this->success_function = $callback;
+ }
+
+ public function error($callback)
+ {
+ $this->error_function = $callback;
+ }
+
+ public function complete($callback)
+ {
+ $this->complete_function = $callback;
+ }
+
+ private function buildURL($url, $data = array())
+ {
+ return $url . (empty($data) ? '' : '?' . http_build_query($data));
+ }
+
+ private function parseHeaders($raw_headers)
+ {
+ $raw_headers = preg_split('/\r\n/', $raw_headers, null, PREG_SPLIT_NO_EMPTY);
+ $http_headers = new CaseInsensitiveArray();
+
+ for ($i = 1; $i < count($raw_headers); $i++) {
+ list($key, $value) = explode(':', $raw_headers[$i], 2);
+ $key = trim($key);
+ $value = trim($value);
+ // Use isset() as array_key_exists() and ArrayAccess are not compatible.
+ if (isset($http_headers[$key])) {
+ $http_headers[$key] .= ',' . $value;
+ } else {
+ $http_headers[$key] = $value;
+ }
+ }
+
+ return array(isset($raw_headers['0']) ? $raw_headers['0'] : '', $http_headers);
+ }
+
+ private function parseRequestHeaders($raw_headers)
+ {
+ $request_headers = new CaseInsensitiveArray();
+ list($first_line, $headers) = $this->parseHeaders($raw_headers);
+ $request_headers['Request-Line'] = $first_line;
+ foreach ($headers as $key => $value) {
+ $request_headers[$key] = $value;
+ }
+ return $request_headers;
+ }
+
+ private function parseResponseHeaders($raw_headers)
+ {
+ $response_headers = new CaseInsensitiveArray();
+ list($first_line, $headers) = $this->parseHeaders($raw_headers);
+ $response_headers['Status-Line'] = $first_line;
+ foreach ($headers as $key => $value) {
+ $response_headers[$key] = $value;
+ }
+ return $response_headers;
+ }
+
+ private function postfields($data)
+ {
+ if (is_array($data)) {
+ if (is_array_multidim($data)) {
+ $data = http_build_multi_query($data);
+ } else {
+ foreach ($data as $key => $value) {
+ // Fix "Notice: Array to string conversion" when $value in
+ // curl_setopt($ch, CURLOPT_POSTFIELDS, $value) is an array
+ // that contains an empty array.
+ if (is_array($value) && empty($value)) {
+ $data[$key] = '';
+ // Fix "curl_setopt(): The usage of the @filename API for
+ // file uploading is deprecated. Please use the CURLFile
+ // class instead".
+ } elseif (is_string($value) && strpos($value, '@') === 0) {
+ if (class_exists('CURLFile')) {
+ $data[$key] = new CURLFile(substr($value, 1));
+ }
+ }
+ }
+ }
+ }
+
+ return $data;
+ }
+
+ protected function exec($_ch = null)
+ {
+ $ch = is_null($_ch) ? $this : $_ch;
+
+ if ($ch->multi_child) {
+ $ch->response = curl_multi_getcontent($ch->curl);
+ } else {
+ $ch->response = curl_exec($ch->curl);
+ }
+
+ $ch->curl_error_code = curl_errno($ch->curl);
+ $ch->curl_error_message = curl_error($ch->curl);
+ $ch->curl_error = !($ch->curl_error_code === 0);
+ $ch->http_status_code = curl_getinfo($ch->curl, CURLINFO_HTTP_CODE);
+ $ch->http_error = in_array(floor($ch->http_status_code / 100), array(4, 5));
+ $ch->error = $ch->curl_error || $ch->http_error;
+ $ch->error_code = $ch->error ? ($ch->curl_error ? $ch->curl_error_code : $ch->http_status_code) : 0;
+
+ $ch->request_headers = $this->parseRequestHeaders(curl_getinfo($ch->curl, CURLINFO_HEADER_OUT));
+ $ch->response_headers = '';
+ if (!(strpos($ch->response, "\r\n\r\n") === false)) {
+ list($response_header, $ch->response) = explode("\r\n\r\n", $ch->response, 2);
+ if ($response_header === 'HTTP/1.1 100 Continue') {
+ list($response_header, $ch->response) = explode("\r\n\r\n", $ch->response, 2);
+ }
+ $ch->response_headers = $this->parseResponseHeaders($response_header);
+
+ if (isset($ch->response_headers['Content-Type'])) {
+ if (preg_match('/^application\/json/i', $ch->response_headers['Content-Type'])) {
+ $json_obj = json_decode($ch->response, false);
+ if (!is_null($json_obj)) {
+ $ch->response = $json_obj;
+ }
+ }
+ }
+ }
+
+ $ch->http_error_message = '';
+ if ($ch->error) {
+ if (isset($ch->response_headers['Status-Line'])) {
+ $ch->http_error_message = $ch->response_headers['Status-Line'];
+ }
+ }
+ $ch->error_message = $ch->curl_error ? $ch->curl_error_message : $ch->http_error_message;
+
+ if (!$ch->error) {
+ $ch->call($this->success_function, $ch);
+ } else {
+ $ch->call($this->error_function, $ch);
+ }
+
+ $ch->call($this->complete_function, $ch);
+
+ return $ch->error_code;
+ }
+
+ private function call($function)
+ {
+ if (is_callable($function)) {
+ $args = func_get_args();
+ array_shift($args);
+ call_user_func_array($function, $args);
+ }
+ }
+
+ public function __destruct()
+ {
+ $this->close();
+ }
+}
+
+class CaseInsensitiveArray implements ArrayAccess, Countable, Iterator
+{
+ private $container = array();
+
+ public function offsetSet($offset, $value)
+ {
+ if (is_null($offset)) {
+ $this->container[] = $value;
+ } else {
+ $index = array_search(strtolower($offset), array_keys(array_change_key_case($this->container, CASE_LOWER)));
+ if (!($index === false)) {
+ $keys = array_keys($this->container);
+ unset($this->container[$keys[$index]]);
+ }
+ $this->container[$offset] = $value;
+ }
+ }
+
+ public function offsetExists($offset)
+ {
+ return array_key_exists(strtolower($offset), array_change_key_case($this->container, CASE_LOWER));
+ }
+
+ public function offsetUnset($offset)
+ {
+ unset($this->container[$offset]);
+ }
+
+ public function offsetGet($offset)
+ {
+ $index = array_search(strtolower($offset), array_keys(array_change_key_case($this->container, CASE_LOWER)));
+ if ($index === false) {
+ return null;
+ }
+
+ $values = array_values($this->container);
+ return $values[$index];
+ }
+
+ public function count()
+ {
+ return count($this->container);
+ }
+
+ public function current()
+ {
+ return current($this->container);
+ }
+
+ public function next()
+ {
+ return next($this->container);
+ }
+
+ public function key()
+ {
+ return key($this->container);
+ }
+
+ public function valid()
+ {
+ return !($this->current() === false);
+ }
+
+ public function rewind()
+ {
+ reset($this->container);
+ }
+}
+
+function is_array_assoc($array)
+{
+ return (bool)count(array_filter(array_keys($array), 'is_string'));
+}
+
+function is_array_multidim($array)
+{
+ if (!is_array($array)) {
+ return false;
+ }
+
+ return !(count($array) === count($array, COUNT_RECURSIVE));
+}
+
+function http_build_multi_query($data, $key = null)
+{
+ $query = array();
+
+ if (empty($data)) {
+ return $key . '=';
+ }
+
+ $is_array_assoc = is_array_assoc($data);
+
+ foreach ($data as $k => $value) {
+ if (is_string($value) || is_numeric($value)) {
+ $brackets = $is_array_assoc ? '[' . $k . ']' : '[]';
+ $query[] = urlencode(is_null($key) ? $k : $key . $brackets) . '=' . rawurlencode($value);
+ } elseif (is_array($value)) {
+ $nested = is_null($key) ? $k : $key . '[' . $k . ']';
+ $query[] = http_build_multi_query($value, $nested);
+ }
+ }
+
+ return implode('&', $query);
+}
diff --git a/web/app/vendor/php-curl-class/php-curl-class/tests/PHPCurlClass/PHPCurlClassTest.php b/web/app/vendor/php-curl-class/php-curl-class/tests/PHPCurlClass/PHPCurlClassTest.php
new file mode 100644
index 0000000..c42bea0
--- /dev/null
+++ b/web/app/vendor/php-curl-class/php-curl-class/tests/PHPCurlClass/PHPCurlClassTest.php
@@ -0,0 +1,740 @@
+assertTrue(extension_loaded('curl'));
+ }
+
+ public function testArrayAssociative() {
+ $this->assertTrue(is_array_assoc(array(
+ 'foo' => 'wibble',
+ 'bar' => 'wubble',
+ 'baz' => 'wobble',
+ )));
+ }
+
+ public function testArrayIndexed() {
+ $this->assertFalse(is_array_assoc(array(
+ 'wibble',
+ 'wubble',
+ 'wobble',
+ )));
+ }
+
+ public function testCaseInsensitiveArrayGet() {
+ $array = new CaseInsensitiveArray();
+ $this->assertTrue(is_object($array));
+ $this->assertCount(0, $array);
+ $this->assertNull($array[(string)rand()]);
+
+ $array['foo'] = 'bar';
+ $this->assertNotEmpty($array);
+ $this->assertCount(1, $array);
+ }
+
+ public function testCaseInsensitiveArraySet() {
+ function assertions($array, $count=1) {
+ PHPUnit_Framework_Assert::assertCount($count, $array);
+ PHPUnit_Framework_Assert::assertTrue($array['foo'] === 'bar');
+ PHPUnit_Framework_Assert::assertTrue($array['Foo'] === 'bar');
+ PHPUnit_Framework_Assert::assertTrue($array['FOo'] === 'bar');
+ PHPUnit_Framework_Assert::assertTrue($array['FOO'] === 'bar');
+ }
+
+ $array = new CaseInsensitiveArray();
+ $array['foo'] = 'bar';
+ assertions($array);
+
+ $array['Foo'] = 'bar';
+ assertions($array);
+
+ $array['FOo'] = 'bar';
+ assertions($array);
+
+ $array['FOO'] = 'bar';
+ assertions($array);
+
+ $array['baz'] = 'qux';
+ assertions($array, 2);
+ }
+
+ public function testUserAgent() {
+ $test = new Test();
+ $test->curl->setUserAgent(Curl::USER_AGENT);
+ $this->assertTrue($test->server('server', 'GET', array(
+ 'key' => 'HTTP_USER_AGENT',
+ )) === Curl::USER_AGENT);
+ }
+
+ public function testGet() {
+ $test = new Test();
+ $this->assertTrue($test->server('server', 'GET', array(
+ 'key' => 'REQUEST_METHOD',
+ )) === 'GET');
+ }
+
+ public function testPostRequestMethod() {
+ $test = new Test();
+ $this->assertTrue($test->server('server', 'POST', array(
+ 'key' => 'REQUEST_METHOD',
+ )) === 'POST');
+ }
+
+ public function testPostData() {
+ $test = new Test();
+ $this->assertTrue($test->server('post', 'POST', array(
+ 'key' => 'value',
+ )) === 'key=value');
+ }
+
+ public function testPostAssociativeArrayData() {
+ $test = new Test();
+ $this->assertTrue($test->server('post_multidimensional', 'POST', array(
+ 'username' => 'myusername',
+ 'password' => 'mypassword',
+ 'more_data' => array(
+ 'param1' => 'something',
+ 'param2' => 'other thing',
+ 'param3' => 123,
+ 'param4' => 3.14,
+ ),
+ )) === 'username=myusername&password=mypassword&more_data%5Bparam1%5D=something&more_data%5Bparam2%5D=other%20thing&more_data%5Bparam3%5D=123&more_data%5Bparam4%5D=3.14');
+ }
+
+ public function testPostMultidimensionalData() {
+ $test = new Test();
+ $this->assertTrue($test->server('post_multidimensional', 'POST', array(
+ 'key' => 'file',
+ 'file' => array(
+ 'wibble',
+ 'wubble',
+ 'wobble',
+ ),
+ )) === 'key=file&file%5B%5D=wibble&file%5B%5D=wubble&file%5B%5D=wobble');
+ }
+
+ public function testPostFilePathUpload() {
+ $file_path = get_png();
+
+ $test = new Test();
+ $this->assertTrue($test->server('post_file_path_upload', 'POST', array(
+ 'key' => 'image',
+ 'image' => '@' . $file_path,
+ )) === 'image/png');
+
+ unlink($file_path);
+ $this->assertFalse(file_exists($file_path));
+ }
+
+ public function testPostCurlFileUpload() {
+ if (class_exists('CURLFile')) {
+ $file_path = get_png();
+
+ $test = new Test();
+ $this->assertTrue($test->server('post_file_path_upload', 'POST', array(
+ 'key' => 'image',
+ 'image' => new CURLFile($file_path),
+ )) === 'image/png');
+
+ unlink($file_path);
+ $this->assertFalse(file_exists($file_path));
+ }
+ }
+
+ public function testPutRequestMethod() {
+ $test = new Test();
+ $this->assertTrue($test->server('request_method', 'PUT') === 'PUT');
+ }
+
+ public function testPutData() {
+ $test = new Test();
+ $this->assertTrue($test->server('put', 'PUT', array(
+ 'key' => 'value',
+ )) === 'key=value');
+ }
+
+ public function testPutFileHandle() {
+ $png = create_png();
+ $tmp_file = create_tmp_file($png);
+
+ $test = new Test();
+ $test->curl->setHeader('X-DEBUG-TEST', 'put_file_handle');
+ $test->curl->setOpt(CURLOPT_PUT, true);
+ $test->curl->setOpt(CURLOPT_INFILE, $tmp_file);
+ $test->curl->setOpt(CURLOPT_INFILESIZE, strlen($png));
+ $test->curl->put(Test::TEST_URL);
+
+ fclose($tmp_file);
+
+ $this->assertTrue($test->curl->response === 'image/png');
+ }
+
+ public function testPatchRequestMethod() {
+ $test = new Test();
+ $this->assertTrue($test->server('request_method', 'PATCH') === 'PATCH');
+ }
+
+ public function testDelete() {
+ $test = new Test();
+ $this->assertTrue($test->server('server', 'DELETE', array(
+ 'key' => 'REQUEST_METHOD',
+ )) === 'DELETE');
+
+ $test = new Test();
+ $this->assertTrue($test->server('delete', 'DELETE', array(
+ 'test' => 'delete',
+ 'key' => 'test',
+ )) === 'delete');
+ }
+
+ public function testHeadRequestMethod() {
+ $test = new Test();
+ $test->server('request_method', 'HEAD', array(
+ 'key' => 'REQUEST_METHOD',
+ ));
+ $this->assertEquals($test->curl->response_headers['X-REQUEST-METHOD'], 'HEAD');
+ $this->assertEmpty($test->curl->response);
+ }
+
+ public function testOptionsRequestMethod() {
+ $test = new Test();
+ $test->server('request_method', 'OPTIONS', array(
+ 'key' => 'REQUEST_METHOD',
+ ));
+ $this->assertEquals($test->curl->response_headers['X-REQUEST-METHOD'], 'OPTIONS');
+ }
+
+ public function testBasicHttpAuth401Unauthorized() {
+ $test = new Test();
+ $this->assertTrue($test->server('http_basic_auth', 'GET') === 'canceled');
+ }
+
+ public function testBasicHttpAuthSuccess() {
+ $username = 'myusername';
+ $password = 'mypassword';
+ $test = new Test();
+ $test->curl->setBasicAuthentication($username, $password);
+ $test->server('http_basic_auth', 'GET');
+ $json = $test->curl->response;
+ $this->assertTrue($json->username === $username);
+ $this->assertTrue($json->password === $password);
+ }
+
+ public function testReferrer() {
+ $test = new Test();
+ $test->curl->setReferrer('myreferrer');
+ $this->assertTrue($test->server('server', 'GET', array(
+ 'key' => 'HTTP_REFERER',
+ )) === 'myreferrer');
+ }
+
+ public function testCookies() {
+ $test = new Test();
+ $test->curl->setCookie('mycookie', 'yum');
+ $this->assertTrue($test->server('cookie', 'GET', array(
+ 'key' => 'mycookie',
+ )) === 'yum');
+ }
+
+ public function testCookieFile() {
+ $cookie_file = dirname(__FILE__) . '/cookies.txt';
+ $cookie_data = implode("\t", array(
+ '127.0.0.1', // domain
+ 'FALSE', // tailmatch
+ '/', // path
+ 'FALSE', // secure
+ '0', // expires
+ 'mycookie', // name
+ 'yum', // value
+ ));
+ file_put_contents($cookie_file, $cookie_data);
+
+ $test = new Test();
+ $test->curl->setCookieFile($cookie_file);
+ $this->assertTrue($test->server('cookie', 'GET', array(
+ 'key' => 'mycookie',
+ )) === 'yum');
+
+ unlink($cookie_file);
+ $this->assertFalse(file_exists($cookie_file));
+ }
+
+ public function testCookieJar() {
+ $cookie_file = dirname(__FILE__) . '/cookies.txt';
+
+ $test = new Test();
+ $test->curl->setCookieJar($cookie_file);
+ $test->server('cookiejar', 'GET');
+ $test->curl->close();
+
+ $this->assertTrue(!(strpos(file_get_contents($cookie_file), "\t" . 'mycookie' . "\t" . 'yum') === false));
+ unlink($cookie_file);
+ $this->assertFalse(file_exists($cookie_file));
+ }
+
+ public function testMultipleCookieResponse() {
+ $expected_response = 'cookie1=scrumptious,cookie2=mouthwatering';
+
+ // github.com/facebook/hhvm/issues/2345
+ if (defined('HHVM_VERSION')) {
+ $expected_response = 'cookie2=mouthwatering,cookie1=scrumptious';
+ }
+
+ $test = new Test();
+ $test->server('multiple_cookie', 'GET');
+ $this->assertEquals($test->curl->response_headers['Set-Cookie'], $expected_response);
+ }
+
+ public function testError() {
+ $test = new Test();
+ $test->curl->setOpt(CURLOPT_CONNECTTIMEOUT_MS, 4000);
+ $test->curl->get(Test::ERROR_URL);
+ $this->assertTrue($test->curl->error);
+ $this->assertTrue($test->curl->curl_error);
+ $this->assertTrue($test->curl->curl_error_code === CURLE_OPERATION_TIMEOUTED);
+ }
+
+ public function testErrorMessage() {
+ $test = new Test();
+ $test->server('error_message', 'GET');
+
+ $expected_response = 'HTTP/1.1 401 Unauthorized';
+ if (defined('HHVM_VERSION')) {
+ $expected_response = 'HTTP/1.1 401';
+ }
+
+ $this->assertEquals($test->curl->error_message, $expected_response);
+ }
+
+ public function testHeaders() {
+ $test = new Test();
+ $test->curl->setHeader('Content-Type', 'application/json');
+ $test->curl->setHeader('X-Requested-With', 'XMLHttpRequest');
+ $test->curl->setHeader('Accept', 'application/json');
+ $this->assertTrue($test->server('server', 'GET', array(
+ 'key' => 'HTTP_CONTENT_TYPE', // OR "CONTENT_TYPE".
+ )) === 'application/json');
+ $this->assertTrue($test->server('server', 'GET', array(
+ 'key' => 'HTTP_X_REQUESTED_WITH',
+ )) === 'XMLHttpRequest');
+ $this->assertTrue($test->server('server', 'GET', array(
+ 'key' => 'HTTP_ACCEPT',
+ )) === 'application/json');
+ }
+
+ public function testHeaderCaseSensitivity() {
+ $content_type = 'application/json';
+ $test = new Test();
+ $test->curl->setHeader('Content-Type', $content_type);
+ $test->server('response_header', 'GET');
+
+ $request_headers = $test->curl->request_headers;
+ $response_headers = $test->curl->response_headers;
+
+ $this->assertEquals($request_headers['Content-Type'], $content_type);
+ $this->assertEquals($request_headers['content-type'], $content_type);
+ $this->assertEquals($request_headers['CONTENT-TYPE'], $content_type);
+ $this->assertEquals($request_headers['cOnTeNt-TyPe'], $content_type);
+
+ $etag = $response_headers['ETag'];
+ $this->assertEquals($response_headers['ETAG'], $etag);
+ $this->assertEquals($response_headers['etag'], $etag);
+ $this->assertEquals($response_headers['eTAG'], $etag);
+ $this->assertEquals($response_headers['eTaG'], $etag);
+ }
+
+ public function testRequestURL() {
+ $test = new Test();
+ $this->assertFalse(substr($test->server('request_uri', 'GET'), -1) === '?');
+ $test = new Test();
+ $this->assertFalse(substr($test->server('request_uri', 'POST'), -1) === '?');
+ $test = new Test();
+ $this->assertFalse(substr($test->server('request_uri', 'PUT'), -1) === '?');
+ $test = new Test();
+ $this->assertFalse(substr($test->server('request_uri', 'PATCH'), -1) === '?');
+ $test = new Test();
+ $this->assertFalse(substr($test->server('request_uri', 'DELETE'), -1) === '?');
+ }
+
+ public function testNestedData() {
+ $test = new Test();
+ $data = array(
+ 'username' => 'myusername',
+ 'password' => 'mypassword',
+ 'more_data' => array(
+ 'param1' => 'something',
+ 'param2' => 'other thing',
+ 'another' => array(
+ 'extra' => 'level',
+ 'because' => 'I need it',
+ ),
+ ),
+ );
+ $this->assertTrue(
+ $test->server('post', 'POST', $data) === http_build_query($data)
+ );
+ }
+
+ public function testPostContentTypes() {
+ $test = new Test();
+ $test->server('server', 'POST', 'foo=bar');
+ $this->assertEquals($test->curl->request_headers['Content-Type'], 'application/x-www-form-urlencoded');
+
+ $test = new Test();
+ $test->server('server', 'POST', array(
+ 'foo' => 'bar',
+ ));
+ $this->assertEquals($test->curl->request_headers['Expect'], '100-continue');
+ preg_match('/^multipart\/form-data; boundary=/', $test->curl->request_headers['Content-Type'], $content_type);
+ $this->assertTrue(!empty($content_type));
+ }
+
+ public function testJSONResponse() {
+ function assertion($key, $value) {
+ $test = new Test();
+ $test->server('json_response', 'POST', array(
+ 'key' => $key,
+ 'value' => $value,
+ ));
+
+ $response = $test->curl->response;
+ PHPUnit_Framework_Assert::assertNotNull($response);
+ PHPUnit_Framework_Assert::assertNull($response->null);
+ PHPUnit_Framework_Assert::assertTrue($response->true);
+ PHPUnit_Framework_Assert::assertFalse($response->false);
+ PHPUnit_Framework_Assert::assertTrue(is_int($response->integer));
+ PHPUnit_Framework_Assert::assertTrue(is_float($response->float));
+ PHPUnit_Framework_Assert::assertEmpty($response->empty);
+ PHPUnit_Framework_Assert::assertTrue(is_string($response->string));
+ }
+
+ assertion('Content-Type', 'application/json; charset=utf-8');
+ assertion('content-type', 'application/json; charset=utf-8');
+ assertion('Content-Type', 'application/json');
+ assertion('content-type', 'application/json');
+ assertion('CONTENT-TYPE', 'application/json');
+ assertion('CONTENT-TYPE', 'APPLICATION/JSON');
+ }
+
+ public function testArrayToStringConversion() {
+ $test = new Test();
+ $test->server('post', 'POST', array(
+ 'foo' => 'bar',
+ 'baz' => array(
+ ),
+ ));
+ $this->assertTrue($test->curl->response === 'foo=bar&baz=');
+
+ $test = new Test();
+ $test->server('post', 'POST', array(
+ 'foo' => 'bar',
+ 'baz' => array(
+ 'qux' => array(
+ ),
+ ),
+ ));
+ $this->assertTrue(urldecode($test->curl->response) ===
+ 'foo=bar&baz[qux]='
+ );
+
+ $test = new Test();
+ $test->server('post', 'POST', array(
+ 'foo' => 'bar',
+ 'baz' => array(
+ 'qux' => array(
+ ),
+ 'wibble' => 'wobble',
+ ),
+ ));
+ $this->assertTrue(urldecode($test->curl->response) ===
+ 'foo=bar&baz[qux]=&baz[wibble]=wobble'
+ );
+ }
+
+ public function testParallelRequests() {
+ $test = new Test();
+ $curl = $test->curl;
+ $curl->beforeSend(function($instance) {
+ $instance->setHeader('X-DEBUG-TEST', 'request_uri');
+ });
+ $curl->get(array(
+ Test::TEST_URL . 'a/',
+ Test::TEST_URL . 'b/',
+ Test::TEST_URL . 'c/',
+ ), array(
+ 'foo' => 'bar',
+ ));
+
+ $len = strlen('/a/?foo=bar');
+ $this->assertTrue(substr($curl->curls['0']->response, - $len) === '/a/?foo=bar');
+ $this->assertTrue(substr($curl->curls['1']->response, - $len) === '/b/?foo=bar');
+ $this->assertTrue(substr($curl->curls['2']->response, - $len) === '/c/?foo=bar');
+ }
+
+ public function testParallelSetOptions() {
+ $test = new Test();
+ $curl = $test->curl;
+ $curl->setHeader('X-DEBUG-TEST', 'server');
+ $curl->setOpt(CURLOPT_USERAGENT, 'useragent');
+ $curl->complete(function($instance) {
+ PHPUnit_Framework_Assert::assertTrue($instance->response === 'useragent');
+ });
+ $curl->get(array(
+ Test::TEST_URL,
+ ), array(
+ 'key' => 'HTTP_USER_AGENT',
+ ));
+ }
+
+ public function testSuccessCallback() {
+ $success_called = false;
+ $error_called = false;
+ $complete_called = false;
+
+ $test = new Test();
+ $curl = $test->curl;
+ $curl->setHeader('X-DEBUG-TEST', 'get');
+
+ $curl->success(function($instance) use (&$success_called, &$error_called, &$complete_called) {
+ PHPUnit_Framework_Assert::assertInstanceOf('Curl', $instance);
+ PHPUnit_Framework_Assert::assertFalse($success_called);
+ PHPUnit_Framework_Assert::assertFalse($error_called);
+ PHPUnit_Framework_Assert::assertFalse($complete_called);
+ $success_called = true;
+ });
+ $curl->error(function($instance) use (&$success_called, &$error_called, &$complete_called, &$curl) {
+ PHPUnit_Framework_Assert::assertInstanceOf('Curl', $instance);
+ PHPUnit_Framework_Assert::assertFalse($success_called);
+ PHPUnit_Framework_Assert::assertFalse($error_called);
+ PHPUnit_Framework_Assert::assertFalse($complete_called);
+ $error_called = true;
+ });
+ $curl->complete(function($instance) use (&$success_called, &$error_called, &$complete_called) {
+ PHPUnit_Framework_Assert::assertInstanceOf('Curl', $instance);
+ PHPUnit_Framework_Assert::assertTrue($success_called);
+ PHPUnit_Framework_Assert::assertFalse($error_called);
+ PHPUnit_Framework_Assert::assertFalse($complete_called);
+ $complete_called = true;
+ });
+
+ $curl->get(Test::TEST_URL);
+
+ $this->assertTrue($success_called);
+ $this->assertFalse($error_called);
+ $this->assertTrue($complete_called);
+ }
+
+ public function testParallelSuccessCallback() {
+ $success_called = false;
+ $error_called = false;
+ $complete_called = false;
+
+ $success_called_once = false;
+ $error_called_once = false;
+ $complete_called_once = false;
+
+ $test = new Test();
+ $curl = $test->curl;
+ $curl->setHeader('X-DEBUG-TEST', 'get');
+
+ $curl->success(function($instance) use (&$success_called,
+ &$error_called,
+ &$complete_called,
+ &$success_called_once) {
+ PHPUnit_Framework_Assert::assertInstanceOf('Curl', $instance);
+ PHPUnit_Framework_Assert::assertFalse($success_called);
+ PHPUnit_Framework_Assert::assertFalse($error_called);
+ PHPUnit_Framework_Assert::assertFalse($complete_called);
+ $success_called = true;
+ $success_called_once = true;
+ });
+ $curl->error(function($instance) use (&$success_called,
+ &$error_called,
+ &$complete_called,
+ &$curl,
+ &$error_called_once) {
+ PHPUnit_Framework_Assert::assertInstanceOf('Curl', $instance);
+ PHPUnit_Framework_Assert::assertFalse($success_called);
+ PHPUnit_Framework_Assert::assertFalse($error_called);
+ PHPUnit_Framework_Assert::assertFalse($complete_called);
+ $error_called = true;
+ $error_called_once = true;
+ });
+ $curl->complete(function($instance) use (&$success_called,
+ &$error_called,
+ &$complete_called,
+ &$complete_called_once) {
+ PHPUnit_Framework_Assert::assertInstanceOf('Curl', $instance);
+ PHPUnit_Framework_Assert::assertTrue($success_called);
+ PHPUnit_Framework_Assert::assertFalse($error_called);
+ PHPUnit_Framework_Assert::assertFalse($complete_called);
+ $complete_called = true;
+ $complete_called_once = true;
+
+ PHPUnit_Framework_Assert::assertTrue($success_called);
+ PHPUnit_Framework_Assert::assertFalse($error_called);
+ PHPUnit_Framework_Assert::assertTrue($complete_called);
+
+ $success_called = false;
+ $error_called = false;
+ $complete_called = false;
+ });
+
+ $curl->get(array(
+ Test::TEST_URL . 'a/',
+ Test::TEST_URL . 'b/',
+ Test::TEST_URL . 'c/',
+ ));
+
+ PHPUnit_Framework_Assert::assertTrue($success_called_once || $error_called_once);
+ PHPUnit_Framework_Assert::assertTrue($complete_called_once);
+ }
+
+ public function testErrorCallback() {
+ $success_called = false;
+ $error_called = false;
+ $complete_called = false;
+
+ $test = new Test();
+ $curl = $test->curl;
+ $curl->setHeader('X-DEBUG-TEST', 'get');
+ $curl->setOpt(CURLOPT_CONNECTTIMEOUT_MS, 2000);
+
+ $curl->success(function($instance) use (&$success_called, &$error_called, &$complete_called) {
+ PHPUnit_Framework_Assert::assertInstanceOf('Curl', $instance);
+ PHPUnit_Framework_Assert::assertFalse($success_called);
+ PHPUnit_Framework_Assert::assertFalse($error_called);
+ PHPUnit_Framework_Assert::assertFalse($complete_called);
+ $success_called = true;
+ });
+ $curl->error(function($instance) use (&$success_called, &$error_called, &$complete_called, &$curl) {
+ PHPUnit_Framework_Assert::assertInstanceOf('Curl', $instance);
+ PHPUnit_Framework_Assert::assertFalse($success_called);
+ PHPUnit_Framework_Assert::assertFalse($error_called);
+ PHPUnit_Framework_Assert::assertFalse($complete_called);
+ $error_called = true;
+ });
+ $curl->complete(function($instance) use (&$success_called, &$error_called, &$complete_called) {
+ PHPUnit_Framework_Assert::assertInstanceOf('Curl', $instance);
+ PHPUnit_Framework_Assert::assertFalse($success_called);
+ PHPUnit_Framework_Assert::assertTrue($error_called);
+ PHPUnit_Framework_Assert::assertFalse($complete_called);
+ $complete_called = true;
+ });
+
+ $curl->get(Test::ERROR_URL);
+
+ $this->assertFalse($success_called);
+ $this->assertTrue($error_called);
+ $this->assertTrue($complete_called);
+ }
+
+ public function testClose() {
+ $test = new Test();
+ $curl = $test->curl;
+ $curl->setHeader('X-DEBUG-TEST', 'post');
+ $curl->post(Test::TEST_URL);
+ $this->assertTrue(is_resource($curl->curl));
+ $curl->close();
+ $this->assertFalse(is_resource($curl->curl));
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error_Warning
+ */
+ public function testRequiredOptionCurlInfoHeaderOutEmitsWarning() {
+ $curl = new Curl();
+ $curl->setOpt(CURLINFO_HEADER_OUT, false);
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error_Warning
+ */
+ public function testRequiredOptionCurlOptHeaderEmitsWarning() {
+ $curl = new Curl();
+ $curl->setOpt(CURLOPT_HEADER, false);
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error_Warning
+ */
+ public function testRequiredOptionCurlOptReturnTransferEmitsWarning() {
+ $curl = new Curl();
+ $curl->setOpt(CURLOPT_RETURNTRANSFER, false);
+ }
+
+ public function testRequestMethodSuccessiveGetRequests() {
+ $test = new Test();
+ test($test, 'GET', 'POST');
+ test($test, 'GET', 'PUT');
+ test($test, 'GET', 'PATCH');
+ test($test, 'GET', 'DELETE');
+ test($test, 'GET', 'HEAD');
+ test($test, 'GET', 'OPTIONS');
+ }
+
+ public function testRequestMethodSuccessivePostRequests() {
+ $test = new Test();
+ test($test, 'POST', 'GET');
+ test($test, 'POST', 'PUT');
+ test($test, 'POST', 'PATCH');
+ test($test, 'POST', 'DELETE');
+ test($test, 'POST', 'HEAD');
+ test($test, 'POST', 'OPTIONS');
+ }
+
+ public function testRequestMethodSuccessivePutRequests() {
+ $test = new Test();
+ test($test, 'PUT', 'GET');
+ test($test, 'PUT', 'POST');
+ test($test, 'PUT', 'PATCH');
+ test($test, 'PUT', 'DELETE');
+ test($test, 'PUT', 'HEAD');
+ test($test, 'PUT', 'OPTIONS');
+ }
+
+ public function testRequestMethodSuccessivePatchRequests() {
+ $test = new Test();
+ test($test, 'PATCH', 'GET');
+ test($test, 'PATCH', 'POST');
+ test($test, 'PATCH', 'PUT');
+ test($test, 'PATCH', 'DELETE');
+ test($test, 'PATCH', 'HEAD');
+ test($test, 'PATCH', 'OPTIONS');
+ }
+
+ public function testRequestMethodSuccessiveDeleteRequests() {
+ $test = new Test();
+ test($test, 'DELETE', 'GET');
+ test($test, 'DELETE', 'POST');
+ test($test, 'DELETE', 'PUT');
+ test($test, 'DELETE', 'PATCH');
+ test($test, 'DELETE', 'HEAD');
+ test($test, 'DELETE', 'OPTIONS');
+ }
+
+ public function testRequestMethodSuccessiveHeadRequests() {
+ $test = new Test();
+ test($test, 'HEAD', 'GET');
+ test($test, 'HEAD', 'POST');
+ test($test, 'HEAD', 'PUT');
+ test($test, 'HEAD', 'PATCH');
+ test($test, 'HEAD', 'DELETE');
+ test($test, 'HEAD', 'OPTIONS');
+ }
+
+ public function testRequestMethodSuccessiveOptionsRequests() {
+ $test = new Test();
+ test($test, 'OPTIONS', 'GET');
+ test($test, 'OPTIONS', 'POST');
+ test($test, 'OPTIONS', 'PUT');
+ test($test, 'OPTIONS', 'PATCH');
+ test($test, 'OPTIONS', 'DELETE');
+ test($test, 'OPTIONS', 'HEAD');
+ }
+}
diff --git a/web/app/vendor/php-curl-class/php-curl-class/tests/PHPCurlClass/helper.inc.php b/web/app/vendor/php-curl-class/php-curl-class/tests/PHPCurlClass/helper.inc.php
new file mode 100644
index 0000000..406a8e1
--- /dev/null
+++ b/web/app/vendor/php-curl-class/php-curl-class/tests/PHPCurlClass/helper.inc.php
@@ -0,0 +1,47 @@
+curl = new Curl();
+ $this->curl->setOpt(CURLOPT_SSL_VERIFYPEER, false);
+ $this->curl->setOpt(CURLOPT_SSL_VERIFYHOST, false);
+ }
+
+ function server($test, $request_method, $data=array()) {
+ $this->curl->setHeader('X-DEBUG-TEST', $test);
+ $request_method = strtolower($request_method);
+ $this->curl->$request_method(self::TEST_URL, $data);
+ return $this->curl->response;
+ }
+}
+
+function test($instance, $before, $after) {
+ $instance->server('request_method', $before);
+ PHPUnit_Framework_Assert::assertEquals($instance->curl->response_headers['X-REQUEST-METHOD'], $before);
+ $instance->server('request_method', $after);
+ PHPUnit_Framework_Assert::assertEquals($instance->curl->response_headers['X-REQUEST-METHOD'], $after);
+}
+
+function create_png() {
+ // PNG image data, 1 x 1, 1-bit colormap, non-interlaced
+ ob_start();
+ imagepng(imagecreatefromstring(base64_decode('R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7')));
+ $raw_image = ob_get_contents();
+ ob_end_clean();
+ return $raw_image;
+}
+
+function create_tmp_file($data) {
+ $tmp_file = tmpfile();
+ fwrite($tmp_file, $data);
+ rewind($tmp_file);
+ return $tmp_file;
+}
+
+function get_png() {
+ $tmp_filename = tempnam('/tmp', 'php-curl-class.');
+ file_put_contents($tmp_filename, create_png());
+ return $tmp_filename;
+}
diff --git a/web/app/vendor/php-curl-class/php-curl-class/tests/PHPCurlClass/index.php b/web/app/vendor/php-curl-class/php-curl-class/tests/PHPCurlClass/index.php
new file mode 120000
index 0000000..21a87f6
--- /dev/null
+++ b/web/app/vendor/php-curl-class/php-curl-class/tests/PHPCurlClass/index.php
@@ -0,0 +1 @@
+server.php
\ No newline at end of file
diff --git a/web/app/vendor/php-curl-class/php-curl-class/tests/PHPCurlClass/server.hdf b/web/app/vendor/php-curl-class/php-curl-class/tests/PHPCurlClass/server.hdf
new file mode 100644
index 0000000..8e49d88
--- /dev/null
+++ b/web/app/vendor/php-curl-class/php-curl-class/tests/PHPCurlClass/server.hdf
@@ -0,0 +1,7 @@
+Log {
+ Level = Verbose
+}
+
+Server {
+ DefaultDocument = index.php
+}
diff --git a/web/app/vendor/php-curl-class/php-curl-class/tests/PHPCurlClass/server.php b/web/app/vendor/php-curl-class/php-curl-class/tests/PHPCurlClass/server.php
new file mode 100644
index 0000000..96e835b
--- /dev/null
+++ b/web/app/vendor/php-curl-class/php-curl-class/tests/PHPCurlClass/server.php
@@ -0,0 +1,132 @@
+ $_SERVER['PHP_AUTH_USER'],
+ 'password' => $_SERVER['PHP_AUTH_PW'],
+ ));
+ exit;
+}
+else if ($test === 'get') {
+ echo http_build_query($_GET);
+ exit;
+}
+else if ($test === 'post') {
+ echo http_build_query($_POST);
+ exit;
+}
+else if ($test === 'put') {
+ echo $http_raw_post_data;
+ exit;
+}
+else if ($test === 'post_multidimensional') {
+ echo $http_raw_post_data;
+ exit;
+}
+else if ($test === 'post_file_path_upload') {
+ echo mime_content_type($_FILES[$key]['tmp_name']);
+ exit;
+}
+else if ($test === 'put_file_handle') {
+ $tmp_filename = tempnam('/tmp', 'php-curl-class.');
+ file_put_contents($tmp_filename, $http_raw_post_data);
+ echo mime_content_type($tmp_filename);
+ unlink($tmp_filename);
+ exit;
+}
+else if ($test === 'request_method') {
+ header('X-REQUEST-METHOD: ' . $request_method);
+ echo $request_method;
+ exit;
+}
+else if ($test === 'request_uri') {
+ echo $_SERVER['REQUEST_URI'];
+ exit;
+}
+else if ($test === 'cookiejar') {
+ setcookie('mycookie', 'yum');
+ exit;
+}
+else if ($test === 'multiple_cookie') {
+ setcookie('cookie1', 'scrumptious');
+ setcookie('cookie2', 'mouthwatering');
+ exit;
+}
+else if ($test === 'response_header') {
+ header('Content-Type: application/json');
+ header('ETag: ' . md5('worldpeace'));
+ exit;
+}
+else if ($test === 'json_response') {
+ $key = $_POST['key'];
+ $value = $_POST['value'];
+ header($key . ': ' . $value);
+ echo json_encode(array(
+ 'null' => null,
+ 'true' => true,
+ 'false' => false,
+ 'integer' => 1,
+ 'float' => 3.14,
+ 'empty' => '',
+ 'string' => 'string',
+ ));
+ exit;
+}
+else if ($test === 'error_message') {
+ if (function_exists('http_response_code')) {
+ http_response_code(401);
+ }
+ else {
+ header('HTTP/1.1 401 Unauthorized');
+ }
+ exit;
+}
+
+header('Content-Type: text/plain');
+
+$data_mapping = array(
+ 'cookie' => '_COOKIE',
+ 'delete' => '_GET',
+ 'get' => '_GET',
+ 'patch' => '_PATCH',
+ 'post' => '_POST',
+ 'put' => '_PUT',
+ 'server' => '_SERVER',
+);
+
+$data = $$data_mapping[$test];
+$value = isset($data[$key]) ? $data[$key] : '';
+echo $value;
diff --git a/web/app/vendor/php-curl-class/php-curl-class/tests/phpunit.xml b/web/app/vendor/php-curl-class/php-curl-class/tests/phpunit.xml
new file mode 100644
index 0000000..8eccd99
--- /dev/null
+++ b/web/app/vendor/php-curl-class/php-curl-class/tests/phpunit.xml
@@ -0,0 +1,8 @@
+
+
+ .
+
+
+
+
+
diff --git a/web/app/vendor/php-curl-class/php-curl-class/tests/run.sh b/web/app/vendor/php-curl-class/php-curl-class/tests/run.sh
new file mode 100644
index 0000000..54330ba
--- /dev/null
+++ b/web/app/vendor/php-curl-class/php-curl-class/tests/run.sh
@@ -0,0 +1,4 @@
+php -S 127.0.0.1:8000 -t PHPCurlClass/ &
+pid=$!
+phpunit --configuration phpunit.xml
+kill $pid
diff --git a/web/app/vendor/php-curl-class/php-curl-class/tests/syntax.sh b/web/app/vendor/php-curl-class/php-curl-class/tests/syntax.sh
new file mode 100644
index 0000000..a5a32f1
--- /dev/null
+++ b/web/app/vendor/php-curl-class/php-curl-class/tests/syntax.sh
@@ -0,0 +1 @@
+phpcs --standard=PSR2 ../src/Curl.class.php
diff --git a/web/app/vendor/symfony/deprecation-contracts/.gitignore b/web/app/vendor/symfony/deprecation-contracts/.gitignore
new file mode 100644
index 0000000..c49a5d8
--- /dev/null
+++ b/web/app/vendor/symfony/deprecation-contracts/.gitignore
@@ -0,0 +1,3 @@
+vendor/
+composer.lock
+phpunit.xml
diff --git a/web/app/vendor/symfony/deprecation-contracts/CHANGELOG.md b/web/app/vendor/symfony/deprecation-contracts/CHANGELOG.md
new file mode 100644
index 0000000..7932e26
--- /dev/null
+++ b/web/app/vendor/symfony/deprecation-contracts/CHANGELOG.md
@@ -0,0 +1,5 @@
+CHANGELOG
+=========
+
+The changelog is maintained for all Symfony contracts at the following URL:
+https://github.com/symfony/contracts/blob/main/CHANGELOG.md
diff --git a/web/app/vendor/symfony/deprecation-contracts/LICENSE b/web/app/vendor/symfony/deprecation-contracts/LICENSE
new file mode 100644
index 0000000..406242f
--- /dev/null
+++ b/web/app/vendor/symfony/deprecation-contracts/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2020-2022 Fabien Potencier
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/web/app/vendor/symfony/deprecation-contracts/README.md b/web/app/vendor/symfony/deprecation-contracts/README.md
new file mode 100644
index 0000000..4957933
--- /dev/null
+++ b/web/app/vendor/symfony/deprecation-contracts/README.md
@@ -0,0 +1,26 @@
+Symfony Deprecation Contracts
+=============================
+
+A generic function and convention to trigger deprecation notices.
+
+This package provides a single global function named `trigger_deprecation()` that triggers silenced deprecation notices.
+
+By using a custom PHP error handler such as the one provided by the Symfony ErrorHandler component,
+the triggered deprecations can be caught and logged for later discovery, both on dev and prod environments.
+
+The function requires at least 3 arguments:
+ - the name of the Composer package that is triggering the deprecation
+ - the version of the package that introduced the deprecation
+ - the message of the deprecation
+ - more arguments can be provided: they will be inserted in the message using `printf()` formatting
+
+Example:
+```php
+trigger_deprecation('symfony/blockchain', '8.9', 'Using "%s" is deprecated, use "%s" instead.', 'bitcoin', 'fabcoin');
+```
+
+This will generate the following message:
+`Since symfony/blockchain 8.9: Using "bitcoin" is deprecated, use "fabcoin" instead.`
+
+While not necessarily recommended, the deprecation notices can be completely ignored by declaring an empty
+`function trigger_deprecation() {}` in your application.
diff --git a/web/app/vendor/symfony/deprecation-contracts/composer.json b/web/app/vendor/symfony/deprecation-contracts/composer.json
new file mode 100644
index 0000000..cc7cc12
--- /dev/null
+++ b/web/app/vendor/symfony/deprecation-contracts/composer.json
@@ -0,0 +1,35 @@
+{
+ "name": "symfony/deprecation-contracts",
+ "type": "library",
+ "description": "A generic function and convention to trigger deprecation notices",
+ "homepage": "https://symfony.com",
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "require": {
+ "php": ">=7.1"
+ },
+ "autoload": {
+ "files": [
+ "function.php"
+ ]
+ },
+ "minimum-stability": "dev",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "2.5-dev"
+ },
+ "thanks": {
+ "name": "symfony/contracts",
+ "url": "https://github.com/symfony/contracts"
+ }
+ }
+}
diff --git a/web/app/vendor/symfony/deprecation-contracts/function.php b/web/app/vendor/symfony/deprecation-contracts/function.php
new file mode 100644
index 0000000..d437150
--- /dev/null
+++ b/web/app/vendor/symfony/deprecation-contracts/function.php
@@ -0,0 +1,27 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+if (!function_exists('trigger_deprecation')) {
+ /**
+ * Triggers a silenced deprecation notice.
+ *
+ * @param string $package The name of the Composer package that is triggering the deprecation
+ * @param string $version The version of the package that introduced the deprecation
+ * @param string $message The message of the deprecation
+ * @param mixed ...$args Values to insert in the message using printf() formatting
+ *
+ * @author Nicolas Grekas
+ */
+ function trigger_deprecation(string $package, string $version, string $message, ...$args): void
+ {
+ @trigger_error(($package || $version ? "Since $package $version: " : '').($args ? vsprintf($message, $args) : $message), \E_USER_DEPRECATED);
+ }
+}
diff --git a/web/app/vendor/symfony/finder/CHANGELOG.md b/web/app/vendor/symfony/finder/CHANGELOG.md
index 9e2fc5a..6a44e87 100644
--- a/web/app/vendor/symfony/finder/CHANGELOG.md
+++ b/web/app/vendor/symfony/finder/CHANGELOG.md
@@ -1,11 +1,6 @@
CHANGELOG
=========
-6.0
----
-
- * Remove `Comparator::setTarget()` and `Comparator::setOperator()`
-
5.4.0
-----
diff --git a/web/app/vendor/symfony/finder/Comparator/Comparator.php b/web/app/vendor/symfony/finder/Comparator/Comparator.php
index bd68583..3af551f 100644
--- a/web/app/vendor/symfony/finder/Comparator/Comparator.php
+++ b/web/app/vendor/symfony/finder/Comparator/Comparator.php
@@ -16,47 +16,102 @@ namespace Symfony\Component\Finder\Comparator;
*/
class Comparator
{
- private string $target;
- private string $operator;
+ private $target;
+ private $operator = '==';
- public function __construct(string $target, string $operator = '==')
+ public function __construct(string $target = null, string $operator = '==')
{
- if (!\in_array($operator, ['>', '<', '>=', '<=', '==', '!='])) {
- throw new \InvalidArgumentException(sprintf('Invalid operator "%s".', $operator));
+ if (null === $target) {
+ trigger_deprecation('symfony/finder', '5.4', 'Constructing a "%s" without setting "$target" is deprecated.', __CLASS__);
}
$this->target = $target;
- $this->operator = $operator;
+ $this->doSetOperator($operator);
}
/**
* Gets the target value.
+ *
+ * @return string
*/
- public function getTarget(): string
+ public function getTarget()
{
+ if (null === $this->target) {
+ trigger_deprecation('symfony/finder', '5.4', 'Calling "%s" without initializing the target is deprecated.', __METHOD__);
+ }
+
return $this->target;
}
/**
- * Gets the comparison operator.
+ * @deprecated set the target via the constructor instead
*/
- public function getOperator(): string
+ public function setTarget(string $target)
+ {
+ trigger_deprecation('symfony/finder', '5.4', '"%s" is deprecated. Set the target via the constructor instead.', __METHOD__);
+
+ $this->target = $target;
+ }
+
+ /**
+ * Gets the comparison operator.
+ *
+ * @return string
+ */
+ public function getOperator()
{
return $this->operator;
}
/**
- * Tests against the target.
+ * Sets the comparison operator.
+ *
+ * @throws \InvalidArgumentException
+ *
+ * @deprecated set the operator via the constructor instead
*/
- public function test(mixed $test): bool
+ public function setOperator(string $operator)
{
- return match ($this->operator) {
- '>' => $test > $this->target,
- '>=' => $test >= $this->target,
- '<' => $test < $this->target,
- '<=' => $test <= $this->target,
- '!=' => $test != $this->target,
- default => $test == $this->target,
- };
+ trigger_deprecation('symfony/finder', '5.4', '"%s" is deprecated. Set the operator via the constructor instead.', __METHOD__);
+
+ $this->doSetOperator('' === $operator ? '==' : $operator);
+ }
+
+ /**
+ * Tests against the target.
+ *
+ * @param mixed $test A test value
+ *
+ * @return bool
+ */
+ public function test($test)
+ {
+ if (null === $this->target) {
+ trigger_deprecation('symfony/finder', '5.4', 'Calling "%s" without initializing the target is deprecated.', __METHOD__);
+ }
+
+ switch ($this->operator) {
+ case '>':
+ return $test > $this->target;
+ case '>=':
+ return $test >= $this->target;
+ case '<':
+ return $test < $this->target;
+ case '<=':
+ return $test <= $this->target;
+ case '!=':
+ return $test != $this->target;
+ }
+
+ return $test == $this->target;
+ }
+
+ private function doSetOperator(string $operator): void
+ {
+ if (!\in_array($operator, ['>', '<', '>=', '<=', '==', '!='])) {
+ throw new \InvalidArgumentException(sprintf('Invalid operator "%s".', $operator));
+ }
+
+ $this->operator = $operator;
}
}
diff --git a/web/app/vendor/symfony/finder/Comparator/DateComparator.php b/web/app/vendor/symfony/finder/Comparator/DateComparator.php
index 159964d..8f651e1 100644
--- a/web/app/vendor/symfony/finder/Comparator/DateComparator.php
+++ b/web/app/vendor/symfony/finder/Comparator/DateComparator.php
@@ -32,7 +32,7 @@ class DateComparator extends Comparator
try {
$date = new \DateTime($matches[2]);
$target = $date->format('U');
- } catch (\Exception) {
+ } catch (\Exception $e) {
throw new \InvalidArgumentException(sprintf('"%s" is not a valid date.', $matches[2]));
}
diff --git a/web/app/vendor/symfony/finder/Finder.php b/web/app/vendor/symfony/finder/Finder.php
index 4636f05..8cc564c 100644
--- a/web/app/vendor/symfony/finder/Finder.php
+++ b/web/app/vendor/symfony/finder/Finder.php
@@ -45,27 +45,27 @@ class Finder implements \IteratorAggregate, \Countable
public const IGNORE_DOT_FILES = 2;
public const IGNORE_VCS_IGNORED_FILES = 4;
- private int $mode = 0;
- private array $names = [];
- private array $notNames = [];
- private array $exclude = [];
- private array $filters = [];
- private array $depths = [];
- private array $sizes = [];
- private bool $followLinks = false;
- private bool $reverseSorting = false;
- private \Closure|int|false $sort = false;
- private int $ignore = 0;
- private array $dirs = [];
- private array $dates = [];
- private array $iterators = [];
- private array $contains = [];
- private array $notContains = [];
- private array $paths = [];
- private array $notPaths = [];
- private bool $ignoreUnreadableDirs = false;
+ private $mode = 0;
+ private $names = [];
+ private $notNames = [];
+ private $exclude = [];
+ private $filters = [];
+ private $depths = [];
+ private $sizes = [];
+ private $followLinks = false;
+ private $reverseSorting = false;
+ private $sort = false;
+ private $ignore = 0;
+ private $dirs = [];
+ private $dates = [];
+ private $iterators = [];
+ private $contains = [];
+ private $notContains = [];
+ private $paths = [];
+ private $notPaths = [];
+ private $ignoreUnreadableDirs = false;
- private static array $vcsPatterns = ['.svn', '_svn', 'CVS', '_darcs', '.arch-params', '.monotone', '.bzr', '.git', '.hg'];
+ private static $vcsPatterns = ['.svn', '_svn', 'CVS', '_darcs', '.arch-params', '.monotone', '.bzr', '.git', '.hg'];
public function __construct()
{
@@ -74,8 +74,10 @@ class Finder implements \IteratorAggregate, \Countable
/**
* Creates a new Finder.
+ *
+ * @return static
*/
- public static function create(): static
+ public static function create()
{
return new static();
}
@@ -85,7 +87,7 @@ class Finder implements \IteratorAggregate, \Countable
*
* @return $this
*/
- public function directories(): static
+ public function directories()
{
$this->mode = Iterator\FileTypeFilterIterator::ONLY_DIRECTORIES;
@@ -97,7 +99,7 @@ class Finder implements \IteratorAggregate, \Countable
*
* @return $this
*/
- public function files(): static
+ public function files()
{
$this->mode = Iterator\FileTypeFilterIterator::ONLY_FILES;
@@ -120,7 +122,7 @@ class Finder implements \IteratorAggregate, \Countable
* @see DepthRangeFilterIterator
* @see NumberComparator
*/
- public function depth(string|int|array $levels): static
+ public function depth($levels)
{
foreach ((array) $levels as $level) {
$this->depths[] = new Comparator\NumberComparator($level);
@@ -148,7 +150,7 @@ class Finder implements \IteratorAggregate, \Countable
* @see DateRangeFilterIterator
* @see DateComparator
*/
- public function date(string|array $dates): static
+ public function date($dates)
{
foreach ((array) $dates as $date) {
$this->dates[] = new Comparator\DateComparator($date);
@@ -173,7 +175,7 @@ class Finder implements \IteratorAggregate, \Countable
*
* @see FilenameFilterIterator
*/
- public function name(string|array $patterns): static
+ public function name($patterns)
{
$this->names = array_merge($this->names, (array) $patterns);
@@ -189,7 +191,7 @@ class Finder implements \IteratorAggregate, \Countable
*
* @see FilenameFilterIterator
*/
- public function notName(string|array $patterns): static
+ public function notName($patterns)
{
$this->notNames = array_merge($this->notNames, (array) $patterns);
@@ -211,7 +213,7 @@ class Finder implements \IteratorAggregate, \Countable
*
* @see FilecontentFilterIterator
*/
- public function contains(string|array $patterns): static
+ public function contains($patterns)
{
$this->contains = array_merge($this->contains, (array) $patterns);
@@ -233,7 +235,7 @@ class Finder implements \IteratorAggregate, \Countable
*
* @see FilecontentFilterIterator
*/
- public function notContains(string|array $patterns): static
+ public function notContains($patterns)
{
$this->notContains = array_merge($this->notContains, (array) $patterns);
@@ -257,7 +259,7 @@ class Finder implements \IteratorAggregate, \Countable
*
* @see FilenameFilterIterator
*/
- public function path(string|array $patterns): static
+ public function path($patterns)
{
$this->paths = array_merge($this->paths, (array) $patterns);
@@ -281,7 +283,7 @@ class Finder implements \IteratorAggregate, \Countable
*
* @see FilenameFilterIterator
*/
- public function notPath(string|array $patterns): static
+ public function notPath($patterns)
{
$this->notPaths = array_merge($this->notPaths, (array) $patterns);
@@ -303,7 +305,7 @@ class Finder implements \IteratorAggregate, \Countable
* @see SizeRangeFilterIterator
* @see NumberComparator
*/
- public function size(string|int|array $sizes): static
+ public function size($sizes)
{
foreach ((array) $sizes as $size) {
$this->sizes[] = new Comparator\NumberComparator($size);
@@ -325,7 +327,7 @@ class Finder implements \IteratorAggregate, \Countable
*
* @see ExcludeDirectoryFilterIterator
*/
- public function exclude(string|array $dirs): static
+ public function exclude($dirs)
{
$this->exclude = array_merge($this->exclude, (array) $dirs);
@@ -341,7 +343,7 @@ class Finder implements \IteratorAggregate, \Countable
*
* @see ExcludeDirectoryFilterIterator
*/
- public function ignoreDotFiles(bool $ignoreDotFiles): static
+ public function ignoreDotFiles(bool $ignoreDotFiles)
{
if ($ignoreDotFiles) {
$this->ignore |= static::IGNORE_DOT_FILES;
@@ -361,7 +363,7 @@ class Finder implements \IteratorAggregate, \Countable
*
* @see ExcludeDirectoryFilterIterator
*/
- public function ignoreVCS(bool $ignoreVCS): static
+ public function ignoreVCS(bool $ignoreVCS)
{
if ($ignoreVCS) {
$this->ignore |= static::IGNORE_VCS_FILES;
@@ -379,7 +381,7 @@ class Finder implements \IteratorAggregate, \Countable
*
* @return $this
*/
- public function ignoreVCSIgnored(bool $ignoreVCSIgnored): static
+ public function ignoreVCSIgnored(bool $ignoreVCSIgnored)
{
if ($ignoreVCSIgnored) {
$this->ignore |= static::IGNORE_VCS_IGNORED_FILES;
@@ -397,7 +399,7 @@ class Finder implements \IteratorAggregate, \Countable
*
* @param string|string[] $pattern VCS patterns to ignore
*/
- public static function addVCSPattern(string|array $pattern)
+ public static function addVCSPattern($pattern)
{
foreach ((array) $pattern as $p) {
self::$vcsPatterns[] = $p;
@@ -417,7 +419,7 @@ class Finder implements \IteratorAggregate, \Countable
*
* @see SortableIterator
*/
- public function sort(\Closure $closure): static
+ public function sort(\Closure $closure)
{
$this->sort = $closure;
@@ -433,7 +435,7 @@ class Finder implements \IteratorAggregate, \Countable
*
* @see SortableIterator
*/
- public function sortByName(bool $useNaturalSort = false): static
+ public function sortByName(bool $useNaturalSort = false)
{
$this->sort = $useNaturalSort ? Iterator\SortableIterator::SORT_BY_NAME_NATURAL : Iterator\SortableIterator::SORT_BY_NAME;
@@ -449,7 +451,7 @@ class Finder implements \IteratorAggregate, \Countable
*
* @see SortableIterator
*/
- public function sortByType(): static
+ public function sortByType()
{
$this->sort = Iterator\SortableIterator::SORT_BY_TYPE;
@@ -467,7 +469,7 @@ class Finder implements \IteratorAggregate, \Countable
*
* @see SortableIterator
*/
- public function sortByAccessedTime(): static
+ public function sortByAccessedTime()
{
$this->sort = Iterator\SortableIterator::SORT_BY_ACCESSED_TIME;
@@ -479,7 +481,7 @@ class Finder implements \IteratorAggregate, \Countable
*
* @return $this
*/
- public function reverseSorting(): static
+ public function reverseSorting()
{
$this->reverseSorting = true;
@@ -499,7 +501,7 @@ class Finder implements \IteratorAggregate, \Countable
*
* @see SortableIterator
*/
- public function sortByChangedTime(): static
+ public function sortByChangedTime()
{
$this->sort = Iterator\SortableIterator::SORT_BY_CHANGED_TIME;
@@ -517,7 +519,7 @@ class Finder implements \IteratorAggregate, \Countable
*
* @see SortableIterator
*/
- public function sortByModifiedTime(): static
+ public function sortByModifiedTime()
{
$this->sort = Iterator\SortableIterator::SORT_BY_MODIFIED_TIME;
@@ -534,7 +536,7 @@ class Finder implements \IteratorAggregate, \Countable
*
* @see CustomFilterIterator
*/
- public function filter(\Closure $closure): static
+ public function filter(\Closure $closure)
{
$this->filters[] = $closure;
@@ -546,7 +548,7 @@ class Finder implements \IteratorAggregate, \Countable
*
* @return $this
*/
- public function followLinks(): static
+ public function followLinks()
{
$this->followLinks = true;
@@ -560,7 +562,7 @@ class Finder implements \IteratorAggregate, \Countable
*
* @return $this
*/
- public function ignoreUnreadableDirs(bool $ignore = true): static
+ public function ignoreUnreadableDirs(bool $ignore = true)
{
$this->ignoreUnreadableDirs = $ignore;
@@ -576,7 +578,7 @@ class Finder implements \IteratorAggregate, \Countable
*
* @throws DirectoryNotFoundException if one of the directories does not exist
*/
- public function in(string|array $dirs): static
+ public function in($dirs)
{
$resolvedDirs = [];
@@ -585,7 +587,7 @@ class Finder implements \IteratorAggregate, \Countable
$resolvedDirs[] = [$this->normalizeDir($dir)];
} elseif ($glob = glob($dir, (\defined('GLOB_BRACE') ? \GLOB_BRACE : 0) | \GLOB_ONLYDIR | \GLOB_NOSORT)) {
sort($glob);
- $resolvedDirs[] = array_map($this->normalizeDir(...), $glob);
+ $resolvedDirs[] = array_map([$this, 'normalizeDir'], $glob);
} else {
throw new DirectoryNotFoundException(sprintf('The "%s" directory does not exist.', $dir));
}
@@ -605,7 +607,8 @@ class Finder implements \IteratorAggregate, \Countable
*
* @throws \LogicException if the in() method has not been called
*/
- public function getIterator(): \Iterator
+ #[\ReturnTypeWillChange]
+ public function getIterator()
{
if (0 === \count($this->dirs) && 0 === \count($this->iterators)) {
throw new \LogicException('You must call one of in() or append() methods before iterating over a Finder.');
@@ -648,7 +651,7 @@ class Finder implements \IteratorAggregate, \Countable
*
* @throws \InvalidArgumentException when the given argument is not iterable
*/
- public function append(iterable $iterator): static
+ public function append(iterable $iterator)
{
if ($iterator instanceof \IteratorAggregate) {
$this->iterators[] = $iterator->getIterator();
@@ -670,8 +673,10 @@ class Finder implements \IteratorAggregate, \Countable
/**
* Check if any results were found.
+ *
+ * @return bool
*/
- public function hasResults(): bool
+ public function hasResults()
{
foreach ($this->getIterator() as $_) {
return true;
@@ -682,8 +687,11 @@ class Finder implements \IteratorAggregate, \Countable
/**
* Counts all the results collected by the iterators.
+ *
+ * @return int
*/
- public function count(): int
+ #[\ReturnTypeWillChange]
+ public function count()
{
return iterator_count($this->getIterator());
}
diff --git a/web/app/vendor/symfony/finder/Gitignore.php b/web/app/vendor/symfony/finder/Gitignore.php
index 070074b..d42cca1 100644
--- a/web/app/vendor/symfony/finder/Gitignore.php
+++ b/web/app/vendor/symfony/finder/Gitignore.php
@@ -43,7 +43,7 @@ class Gitignore
foreach ($gitignoreLines as $line) {
$line = preg_replace('~(? $iterator The Iterator to filter
@@ -45,8 +45,11 @@ class CustomFilterIterator extends \FilterIterator
/**
* Filters the iterator values.
+ *
+ * @return bool
*/
- public function accept(): bool
+ #[\ReturnTypeWillChange]
+ public function accept()
{
$fileinfo = $this->current();
diff --git a/web/app/vendor/symfony/finder/Iterator/DateRangeFilterIterator.php b/web/app/vendor/symfony/finder/Iterator/DateRangeFilterIterator.php
index 718d42b..f592e19 100644
--- a/web/app/vendor/symfony/finder/Iterator/DateRangeFilterIterator.php
+++ b/web/app/vendor/symfony/finder/Iterator/DateRangeFilterIterator.php
@@ -22,7 +22,7 @@ use Symfony\Component\Finder\Comparator\DateComparator;
*/
class DateRangeFilterIterator extends \FilterIterator
{
- private array $comparators = [];
+ private $comparators = [];
/**
* @param \Iterator $iterator
@@ -37,8 +37,11 @@ class DateRangeFilterIterator extends \FilterIterator
/**
* Filters the iterator values.
+ *
+ * @return bool
*/
- public function accept(): bool
+ #[\ReturnTypeWillChange]
+ public function accept()
{
$fileinfo = $this->current();
diff --git a/web/app/vendor/symfony/finder/Iterator/DepthRangeFilterIterator.php b/web/app/vendor/symfony/finder/Iterator/DepthRangeFilterIterator.php
index 1cddb5f..f593a3f 100644
--- a/web/app/vendor/symfony/finder/Iterator/DepthRangeFilterIterator.php
+++ b/web/app/vendor/symfony/finder/Iterator/DepthRangeFilterIterator.php
@@ -23,7 +23,7 @@ namespace Symfony\Component\Finder\Iterator;
*/
class DepthRangeFilterIterator extends \FilterIterator
{
- private int $minDepth = 0;
+ private $minDepth = 0;
/**
* @param \RecursiveIteratorIterator<\RecursiveIterator> $iterator The Iterator to filter
@@ -40,8 +40,11 @@ class DepthRangeFilterIterator extends \FilterIterator
/**
* Filters the iterator values.
+ *
+ * @return bool
*/
- public function accept(): bool
+ #[\ReturnTypeWillChange]
+ public function accept()
{
return $this->getInnerIterator()->getDepth() >= $this->minDepth;
}
diff --git a/web/app/vendor/symfony/finder/Iterator/ExcludeDirectoryFilterIterator.php b/web/app/vendor/symfony/finder/Iterator/ExcludeDirectoryFilterIterator.php
index efe9364..d9e182c 100644
--- a/web/app/vendor/symfony/finder/Iterator/ExcludeDirectoryFilterIterator.php
+++ b/web/app/vendor/symfony/finder/Iterator/ExcludeDirectoryFilterIterator.php
@@ -11,27 +11,24 @@
namespace Symfony\Component\Finder\Iterator;
-use Symfony\Component\Finder\SplFileInfo;
-
/**
* ExcludeDirectoryFilterIterator filters out directories.
*
* @author Fabien Potencier
*
- * @extends \FilterIterator
- * @implements \RecursiveIterator
+ * @extends \FilterIterator
+ * @implements \RecursiveIterator
*/
class ExcludeDirectoryFilterIterator extends \FilterIterator implements \RecursiveIterator
{
- /** @var \Iterator */
- private \Iterator $iterator;
- private bool $isRecursive;
- private array $excludedDirs = [];
- private ?string $excludedPattern = null;
+ private $iterator;
+ private $isRecursive;
+ private $excludedDirs = [];
+ private $excludedPattern;
/**
- * @param \Iterator $iterator The Iterator to filter
- * @param string[] $directories An array of directories to exclude
+ * @param \Iterator $iterator The Iterator to filter
+ * @param string[] $directories An array of directories to exclude
*/
public function __construct(\Iterator $iterator, array $directories)
{
@@ -55,8 +52,11 @@ class ExcludeDirectoryFilterIterator extends \FilterIterator implements \Recursi
/**
* Filters the iterator values.
+ *
+ * @return bool
*/
- public function accept(): bool
+ #[\ReturnTypeWillChange]
+ public function accept()
{
if ($this->isRecursive && isset($this->excludedDirs[$this->getFilename()]) && $this->isDir()) {
return false;
@@ -72,12 +72,20 @@ class ExcludeDirectoryFilterIterator extends \FilterIterator implements \Recursi
return true;
}
- public function hasChildren(): bool
+ /**
+ * @return bool
+ */
+ #[\ReturnTypeWillChange]
+ public function hasChildren()
{
return $this->isRecursive && $this->iterator->hasChildren();
}
- public function getChildren(): self
+ /**
+ * @return self
+ */
+ #[\ReturnTypeWillChange]
+ public function getChildren()
{
$children = new self($this->iterator->getChildren(), []);
$children->excludedDirs = $this->excludedDirs;
diff --git a/web/app/vendor/symfony/finder/Iterator/FileTypeFilterIterator.php b/web/app/vendor/symfony/finder/Iterator/FileTypeFilterIterator.php
index 2130378..793ae35 100644
--- a/web/app/vendor/symfony/finder/Iterator/FileTypeFilterIterator.php
+++ b/web/app/vendor/symfony/finder/Iterator/FileTypeFilterIterator.php
@@ -23,11 +23,11 @@ class FileTypeFilterIterator extends \FilterIterator
public const ONLY_FILES = 1;
public const ONLY_DIRECTORIES = 2;
- private int $mode;
+ private $mode;
/**
- * @param \Iterator $iterator The Iterator to filter
- * @param int $mode The mode (self::ONLY_FILES or self::ONLY_DIRECTORIES)
+ * @param \Iterator $iterator The Iterator to filter
+ * @param int $mode The mode (self::ONLY_FILES or self::ONLY_DIRECTORIES)
*/
public function __construct(\Iterator $iterator, int $mode)
{
@@ -38,8 +38,11 @@ class FileTypeFilterIterator extends \FilterIterator
/**
* Filters the iterator values.
+ *
+ * @return bool
*/
- public function accept(): bool
+ #[\ReturnTypeWillChange]
+ public function accept()
{
$fileinfo = $this->current();
if (self::ONLY_DIRECTORIES === (self::ONLY_DIRECTORIES & $this->mode) && $fileinfo->isFile()) {
diff --git a/web/app/vendor/symfony/finder/Iterator/FilecontentFilterIterator.php b/web/app/vendor/symfony/finder/Iterator/FilecontentFilterIterator.php
index bdc71ff..79f8c29 100644
--- a/web/app/vendor/symfony/finder/Iterator/FilecontentFilterIterator.php
+++ b/web/app/vendor/symfony/finder/Iterator/FilecontentFilterIterator.php
@@ -11,22 +11,23 @@
namespace Symfony\Component\Finder\Iterator;
-use Symfony\Component\Finder\SplFileInfo;
-
/**
* FilecontentFilterIterator filters files by their contents using patterns (regexps or strings).
*
* @author Fabien Potencier
* @author Włodzimierz Gajda
*
- * @extends MultiplePcreFilterIterator
+ * @extends MultiplePcreFilterIterator
*/
class FilecontentFilterIterator extends MultiplePcreFilterIterator
{
/**
* Filters the iterator values.
+ *
+ * @return bool
*/
- public function accept(): bool
+ #[\ReturnTypeWillChange]
+ public function accept()
{
if (!$this->matchRegexps && !$this->noMatchRegexps) {
return true;
@@ -50,8 +51,10 @@ class FilecontentFilterIterator extends MultiplePcreFilterIterator
* Converts string to regexp if necessary.
*
* @param string $str Pattern: string or regexp
+ *
+ * @return string
*/
- protected function toRegex(string $str): string
+ protected function toRegex(string $str)
{
return $this->isRegex($str) ? $str : '/'.preg_quote($str, '/').'/';
}
diff --git a/web/app/vendor/symfony/finder/Iterator/FilenameFilterIterator.php b/web/app/vendor/symfony/finder/Iterator/FilenameFilterIterator.php
index 05d9535..77b3b24 100644
--- a/web/app/vendor/symfony/finder/Iterator/FilenameFilterIterator.php
+++ b/web/app/vendor/symfony/finder/Iterator/FilenameFilterIterator.php
@@ -24,8 +24,11 @@ class FilenameFilterIterator extends MultiplePcreFilterIterator
{
/**
* Filters the iterator values.
+ *
+ * @return bool
*/
- public function accept(): bool
+ #[\ReturnTypeWillChange]
+ public function accept()
{
return $this->isAccepted($this->current()->getFilename());
}
@@ -37,8 +40,10 @@ class FilenameFilterIterator extends MultiplePcreFilterIterator
* Glob strings are transformed with Glob::toRegex().
*
* @param string $str Pattern: glob or regexp
+ *
+ * @return string
*/
- protected function toRegex(string $str): string
+ protected function toRegex(string $str)
{
return $this->isRegex($str) ? $str : Glob::toRegex($str);
}
diff --git a/web/app/vendor/symfony/finder/Iterator/LazyIterator.php b/web/app/vendor/symfony/finder/Iterator/LazyIterator.php
index 5b5806b..32cc37f 100644
--- a/web/app/vendor/symfony/finder/Iterator/LazyIterator.php
+++ b/web/app/vendor/symfony/finder/Iterator/LazyIterator.php
@@ -18,11 +18,11 @@ namespace Symfony\Component\Finder\Iterator;
*/
class LazyIterator implements \IteratorAggregate
{
- private \Closure $iteratorFactory;
+ private $iteratorFactory;
public function __construct(callable $iteratorFactory)
{
- $this->iteratorFactory = $iteratorFactory(...);
+ $this->iteratorFactory = $iteratorFactory;
}
public function getIterator(): \Traversable
diff --git a/web/app/vendor/symfony/finder/Iterator/MultiplePcreFilterIterator.php b/web/app/vendor/symfony/finder/Iterator/MultiplePcreFilterIterator.php
index 82a9df3..564765d 100644
--- a/web/app/vendor/symfony/finder/Iterator/MultiplePcreFilterIterator.php
+++ b/web/app/vendor/symfony/finder/Iterator/MultiplePcreFilterIterator.php
@@ -27,9 +27,9 @@ abstract class MultiplePcreFilterIterator extends \FilterIterator
protected $noMatchRegexps = [];
/**
- * @param \Iterator $iterator The Iterator to filter
- * @param string[] $matchPatterns An array of patterns that need to match
- * @param string[] $noMatchPatterns An array of patterns that need to not match
+ * @param \Iterator $iterator The Iterator to filter
+ * @param string[] $matchPatterns An array of patterns that need to match
+ * @param string[] $noMatchPatterns An array of patterns that need to not match
*/
public function __construct(\Iterator $iterator, array $matchPatterns, array $noMatchPatterns)
{
@@ -50,8 +50,10 @@ abstract class MultiplePcreFilterIterator extends \FilterIterator
* If there is no regexps defined in the class, this method will accept the string.
* Such case can be handled by child classes before calling the method if they want to
* apply a different behavior.
+ *
+ * @return bool
*/
- protected function isAccepted(string $string): bool
+ protected function isAccepted(string $string)
{
// should at least not match one rule to exclude
foreach ($this->noMatchRegexps as $regex) {
@@ -77,8 +79,10 @@ abstract class MultiplePcreFilterIterator extends \FilterIterator
/**
* Checks whether the string is a regex.
+ *
+ * @return bool
*/
- protected function isRegex(string $str): bool
+ protected function isRegex(string $str)
{
$availableModifiers = 'imsxuADU';
@@ -106,6 +110,8 @@ abstract class MultiplePcreFilterIterator extends \FilterIterator
/**
* Converts string into regexp.
+ *
+ * @return string
*/
- abstract protected function toRegex(string $str): string;
+ abstract protected function toRegex(string $str);
}
diff --git a/web/app/vendor/symfony/finder/Iterator/PathFilterIterator.php b/web/app/vendor/symfony/finder/Iterator/PathFilterIterator.php
index c6d5813..7974c4e 100644
--- a/web/app/vendor/symfony/finder/Iterator/PathFilterIterator.php
+++ b/web/app/vendor/symfony/finder/Iterator/PathFilterIterator.php
@@ -11,22 +11,23 @@
namespace Symfony\Component\Finder\Iterator;
-use Symfony\Component\Finder\SplFileInfo;
-
/**
* PathFilterIterator filters files by path patterns (e.g. some/special/dir).
*
* @author Fabien Potencier
* @author Włodzimierz Gajda
*
- * @extends MultiplePcreFilterIterator
+ * @extends MultiplePcreFilterIterator
*/
class PathFilterIterator extends MultiplePcreFilterIterator
{
/**
* Filters the iterator values.
+ *
+ * @return bool
*/
- public function accept(): bool
+ #[\ReturnTypeWillChange]
+ public function accept()
{
$filename = $this->current()->getRelativePathname();
@@ -48,8 +49,10 @@ class PathFilterIterator extends MultiplePcreFilterIterator
* Use only / as directory separator (on Windows also).
*
* @param string $str Pattern: regexp or dirname
+ *
+ * @return string
*/
- protected function toRegex(string $str): string
+ protected function toRegex(string $str)
{
return $this->isRegex($str) ? $str : '/'.preg_quote($str, '/').'/';
}
diff --git a/web/app/vendor/symfony/finder/Iterator/RecursiveDirectoryIterator.php b/web/app/vendor/symfony/finder/Iterator/RecursiveDirectoryIterator.php
index c321aee..27589cd 100644
--- a/web/app/vendor/symfony/finder/Iterator/RecursiveDirectoryIterator.php
+++ b/web/app/vendor/symfony/finder/Iterator/RecursiveDirectoryIterator.php
@@ -18,17 +18,23 @@ use Symfony\Component\Finder\SplFileInfo;
* Extends the \RecursiveDirectoryIterator to support relative paths.
*
* @author Victor Berchet
- * @extends \RecursiveDirectoryIterator
*/
class RecursiveDirectoryIterator extends \RecursiveDirectoryIterator
{
- private bool $ignoreUnreadableDirs;
- private ?bool $rewindable = null;
+ /**
+ * @var bool
+ */
+ private $ignoreUnreadableDirs;
+
+ /**
+ * @var bool
+ */
+ private $rewindable;
// these 3 properties take part of the performance optimization to avoid redoing the same work in all iterations
- private string $rootPath;
- private string $subPath;
- private string $directorySeparator = '/';
+ private $rootPath;
+ private $subPath;
+ private $directorySeparator = '/';
/**
* @throws \RuntimeException
@@ -49,15 +55,17 @@ class RecursiveDirectoryIterator extends \RecursiveDirectoryIterator
/**
* Return an instance of SplFileInfo with support for relative paths.
+ *
+ * @return SplFileInfo
*/
- public function current(): SplFileInfo
+ #[\ReturnTypeWillChange]
+ public function current()
{
// the logic here avoids redoing the same work in all iterations
- if (!isset($this->subPath)) {
- $this->subPath = $this->getSubPath();
+ if (null === $subPathname = $this->subPath) {
+ $subPathname = $this->subPath = $this->getSubPath();
}
- $subPathname = $this->subPath;
if ('' !== $subPathname) {
$subPathname .= $this->directorySeparator;
}
@@ -70,7 +78,13 @@ class RecursiveDirectoryIterator extends \RecursiveDirectoryIterator
return new SplFileInfo($basePath.$subPathname, $this->subPath, $subPathname);
}
- public function hasChildren(bool $allowLinks = false): bool
+ /**
+ * @param bool $allowLinks
+ *
+ * @return bool
+ */
+ #[\ReturnTypeWillChange]
+ public function hasChildren($allowLinks = false)
{
$hasChildren = parent::hasChildren($allowLinks);
@@ -82,16 +96,19 @@ class RecursiveDirectoryIterator extends \RecursiveDirectoryIterator
parent::getChildren();
return true;
- } catch (\UnexpectedValueException) {
+ } catch (\UnexpectedValueException $e) {
// If directory is unreadable and finder is set to ignore it, skip children
return false;
}
}
/**
+ * @return \RecursiveDirectoryIterator
+ *
* @throws AccessDeniedException
*/
- public function getChildren(): \RecursiveDirectoryIterator
+ #[\ReturnTypeWillChange]
+ public function getChildren()
{
try {
$children = parent::getChildren();
@@ -113,8 +130,11 @@ class RecursiveDirectoryIterator extends \RecursiveDirectoryIterator
/**
* Do nothing for non rewindable stream.
+ *
+ * @return void
*/
- public function rewind(): void
+ #[\ReturnTypeWillChange]
+ public function rewind()
{
if (false === $this->isRewindable()) {
return;
@@ -125,8 +145,10 @@ class RecursiveDirectoryIterator extends \RecursiveDirectoryIterator
/**
* Checks if the stream is rewindable.
+ *
+ * @return bool
*/
- public function isRewindable(): bool
+ public function isRewindable()
{
if (null !== $this->rewindable) {
return $this->rewindable;
diff --git a/web/app/vendor/symfony/finder/Iterator/SizeRangeFilterIterator.php b/web/app/vendor/symfony/finder/Iterator/SizeRangeFilterIterator.php
index 925830a..575bf29 100644
--- a/web/app/vendor/symfony/finder/Iterator/SizeRangeFilterIterator.php
+++ b/web/app/vendor/symfony/finder/Iterator/SizeRangeFilterIterator.php
@@ -22,7 +22,7 @@ use Symfony\Component\Finder\Comparator\NumberComparator;
*/
class SizeRangeFilterIterator extends \FilterIterator
{
- private array $comparators = [];
+ private $comparators = [];
/**
* @param \Iterator $iterator
@@ -37,8 +37,11 @@ class SizeRangeFilterIterator extends \FilterIterator
/**
* Filters the iterator values.
+ *
+ * @return bool
*/
- public function accept(): bool
+ #[\ReturnTypeWillChange]
+ public function accept()
{
$fileinfo = $this->current();
if (!$fileinfo->isFile()) {
diff --git a/web/app/vendor/symfony/finder/Iterator/SortableIterator.php b/web/app/vendor/symfony/finder/Iterator/SortableIterator.php
index cc4dbd6..9afde5c 100644
--- a/web/app/vendor/symfony/finder/Iterator/SortableIterator.php
+++ b/web/app/vendor/symfony/finder/Iterator/SortableIterator.php
@@ -28,9 +28,8 @@ class SortableIterator implements \IteratorAggregate
public const SORT_BY_MODIFIED_TIME = 5;
public const SORT_BY_NAME_NATURAL = 6;
- /** @var \Traversable */
- private \Traversable $iterator;
- private \Closure|int $sort;
+ private $iterator;
+ private $sort;
/**
* @param \Traversable $iterator
@@ -38,7 +37,7 @@ class SortableIterator implements \IteratorAggregate
*
* @throws \InvalidArgumentException
*/
- public function __construct(\Traversable $iterator, int|callable $sort, bool $reverseOrder = false)
+ public function __construct(\Traversable $iterator, $sort, bool $reverseOrder = false)
{
$this->iterator = $iterator;
$order = $reverseOrder ? -1 : 1;
@@ -76,13 +75,17 @@ class SortableIterator implements \IteratorAggregate
} elseif (self::SORT_BY_NONE === $sort) {
$this->sort = $order;
} elseif (\is_callable($sort)) {
- $this->sort = $reverseOrder ? static function (\SplFileInfo $a, \SplFileInfo $b) use ($sort) { return -$sort($a, $b); } : $sort(...);
+ $this->sort = $reverseOrder ? static function (\SplFileInfo $a, \SplFileInfo $b) use ($sort) { return -$sort($a, $b); } : $sort;
} else {
throw new \InvalidArgumentException('The SortableIterator takes a PHP callable or a valid built-in sort algorithm as an argument.');
}
}
- public function getIterator(): \Traversable
+ /**
+ * @return \Traversable
+ */
+ #[\ReturnTypeWillChange]
+ public function getIterator()
{
if (1 === $this->sort) {
return $this->iterator;
diff --git a/web/app/vendor/symfony/finder/Iterator/VcsIgnoredFilterIterator.php b/web/app/vendor/symfony/finder/Iterator/VcsIgnoredFilterIterator.php
index 29fc2d9..e27158c 100644
--- a/web/app/vendor/symfony/finder/Iterator/VcsIgnoredFilterIterator.php
+++ b/web/app/vendor/symfony/finder/Iterator/VcsIgnoredFilterIterator.php
@@ -13,9 +13,6 @@ namespace Symfony\Component\Finder\Iterator;
use Symfony\Component\Finder\Gitignore;
-/**
- * @extends \FilterIterator
- */
final class VcsIgnoredFilterIterator extends \FilterIterator
{
/**
@@ -33,20 +30,10 @@ final class VcsIgnoredFilterIterator extends \FilterIterator
*/
private $ignoredPathsCache = [];
- /**
- * @param \Iterator $iterator
- */
public function __construct(\Iterator $iterator, string $baseDir)
{
$this->baseDir = $this->normalizePath($baseDir);
- foreach ($this->parentDirectoriesUpwards($this->baseDir) as $parentDirectory) {
- if (@is_dir("{$parentDirectory}/.git")) {
- $this->baseDir = $parentDirectory;
- break;
- }
- }
-
parent::__construct($iterator);
}
@@ -71,7 +58,7 @@ final class VcsIgnoredFilterIterator extends \FilterIterator
$ignored = false;
- foreach ($this->parentDirectoriesDownwards($fileRealPath) as $parentDirectory) {
+ foreach ($this->parentsDirectoryDownward($fileRealPath) as $parentDirectory) {
if ($this->isIgnored($parentDirectory)) {
// rules in ignored directories are ignored, no need to check further.
break;
@@ -102,11 +89,11 @@ final class VcsIgnoredFilterIterator extends \FilterIterator
/**
* @return list
*/
- private function parentDirectoriesUpwards(string $from): array
+ private function parentsDirectoryDownward(string $fileRealPath): array
{
$parentDirectories = [];
- $parentDirectory = $from;
+ $parentDirectory = $fileRealPath;
while (true) {
$newParentDirectory = \dirname($parentDirectory);
@@ -116,30 +103,16 @@ final class VcsIgnoredFilterIterator extends \FilterIterator
break;
}
- $parentDirectories[] = $parentDirectory = $newParentDirectory;
+ $parentDirectory = $newParentDirectory;
+
+ if (0 !== strpos($parentDirectory, $this->baseDir)) {
+ break;
+ }
+
+ $parentDirectories[] = $parentDirectory;
}
- return $parentDirectories;
- }
-
- private function parentDirectoriesUpTo(string $from, string $upTo): array
- {
- return array_filter(
- $this->parentDirectoriesUpwards($from),
- static function (string $directory) use ($upTo): bool {
- return str_starts_with($directory, $upTo);
- }
- );
- }
-
- /**
- * @return list
- */
- private function parentDirectoriesDownwards(string $fileRealPath): array
- {
- return array_reverse(
- $this->parentDirectoriesUpTo($fileRealPath, $this->baseDir)
- );
+ return array_reverse($parentDirectories);
}
/**
diff --git a/web/app/vendor/symfony/finder/SplFileInfo.php b/web/app/vendor/symfony/finder/SplFileInfo.php
index 867e8e8..11604a2 100644
--- a/web/app/vendor/symfony/finder/SplFileInfo.php
+++ b/web/app/vendor/symfony/finder/SplFileInfo.php
@@ -18,8 +18,8 @@ namespace Symfony\Component\Finder;
*/
class SplFileInfo extends \SplFileInfo
{
- private string $relativePath;
- private string $relativePathname;
+ private $relativePath;
+ private $relativePathname;
/**
* @param string $file The file name
@@ -37,8 +37,10 @@ class SplFileInfo extends \SplFileInfo
* Returns the relative path.
*
* This path does not contain the file name.
+ *
+ * @return string
*/
- public function getRelativePath(): string
+ public function getRelativePath()
{
return $this->relativePath;
}
@@ -47,8 +49,10 @@ class SplFileInfo extends \SplFileInfo
* Returns the relative path name.
*
* This path contains the file name.
+ *
+ * @return string
*/
- public function getRelativePathname(): string
+ public function getRelativePathname()
{
return $this->relativePathname;
}
@@ -63,9 +67,11 @@ class SplFileInfo extends \SplFileInfo
/**
* Returns the contents of the file.
*
+ * @return string
+ *
* @throws \RuntimeException
*/
- public function getContents(): string
+ public function getContents()
{
set_error_handler(function ($type, $msg) use (&$error) { $error = $msg; });
try {
diff --git a/web/app/vendor/symfony/finder/composer.json b/web/app/vendor/symfony/finder/composer.json
index 06d129c..ef19911 100644
--- a/web/app/vendor/symfony/finder/composer.json
+++ b/web/app/vendor/symfony/finder/composer.json
@@ -16,10 +16,9 @@
}
],
"require": {
- "php": ">=8.1"
- },
- "require-dev": {
- "symfony/filesystem": "^6.0"
+ "php": ">=7.2.5",
+ "symfony/deprecation-contracts": "^2.1|^3",
+ "symfony/polyfill-php80": "^1.16"
},
"autoload": {
"psr-4": { "Symfony\\Component\\Finder\\": "" },
diff --git a/web/app/vendor/symfony/polyfill-php80/LICENSE b/web/app/vendor/symfony/polyfill-php80/LICENSE
new file mode 100644
index 0000000..5593b1d
--- /dev/null
+++ b/web/app/vendor/symfony/polyfill-php80/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2020 Fabien Potencier
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/web/app/vendor/symfony/polyfill-php80/Php80.php b/web/app/vendor/symfony/polyfill-php80/Php80.php
new file mode 100644
index 0000000..362dd1a
--- /dev/null
+++ b/web/app/vendor/symfony/polyfill-php80/Php80.php
@@ -0,0 +1,115 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Polyfill\Php80;
+
+/**
+ * @author Ion Bazan
+ * @author Nico Oelgart
+ * @author Nicolas Grekas
+ *
+ * @internal
+ */
+final class Php80
+{
+ public static function fdiv(float $dividend, float $divisor): float
+ {
+ return @($dividend / $divisor);
+ }
+
+ public static function get_debug_type($value): string
+ {
+ switch (true) {
+ case null === $value: return 'null';
+ case \is_bool($value): return 'bool';
+ case \is_string($value): return 'string';
+ case \is_array($value): return 'array';
+ case \is_int($value): return 'int';
+ case \is_float($value): return 'float';
+ case \is_object($value): break;
+ case $value instanceof \__PHP_Incomplete_Class: return '__PHP_Incomplete_Class';
+ default:
+ if (null === $type = @get_resource_type($value)) {
+ return 'unknown';
+ }
+
+ if ('Unknown' === $type) {
+ $type = 'closed';
+ }
+
+ return "resource ($type)";
+ }
+
+ $class = \get_class($value);
+
+ if (false === strpos($class, '@')) {
+ return $class;
+ }
+
+ return (get_parent_class($class) ?: key(class_implements($class)) ?: 'class').'@anonymous';
+ }
+
+ public static function get_resource_id($res): int
+ {
+ if (!\is_resource($res) && null === @get_resource_type($res)) {
+ throw new \TypeError(sprintf('Argument 1 passed to get_resource_id() must be of the type resource, %s given', get_debug_type($res)));
+ }
+
+ return (int) $res;
+ }
+
+ public static function preg_last_error_msg(): string
+ {
+ switch (preg_last_error()) {
+ case \PREG_INTERNAL_ERROR:
+ return 'Internal error';
+ case \PREG_BAD_UTF8_ERROR:
+ return 'Malformed UTF-8 characters, possibly incorrectly encoded';
+ case \PREG_BAD_UTF8_OFFSET_ERROR:
+ return 'The offset did not correspond to the beginning of a valid UTF-8 code point';
+ case \PREG_BACKTRACK_LIMIT_ERROR:
+ return 'Backtrack limit exhausted';
+ case \PREG_RECURSION_LIMIT_ERROR:
+ return 'Recursion limit exhausted';
+ case \PREG_JIT_STACKLIMIT_ERROR:
+ return 'JIT stack limit exhausted';
+ case \PREG_NO_ERROR:
+ return 'No error';
+ default:
+ return 'Unknown error';
+ }
+ }
+
+ public static function str_contains(string $haystack, string $needle): bool
+ {
+ return '' === $needle || false !== strpos($haystack, $needle);
+ }
+
+ public static function str_starts_with(string $haystack, string $needle): bool
+ {
+ return 0 === strncmp($haystack, $needle, \strlen($needle));
+ }
+
+ public static function str_ends_with(string $haystack, string $needle): bool
+ {
+ if ('' === $needle || $needle === $haystack) {
+ return true;
+ }
+
+ if ('' === $haystack) {
+ return false;
+ }
+
+ $needleLength = \strlen($needle);
+
+ return $needleLength <= \strlen($haystack) && 0 === substr_compare($haystack, $needle, -$needleLength);
+ }
+}
diff --git a/web/app/vendor/symfony/polyfill-php80/PhpToken.php b/web/app/vendor/symfony/polyfill-php80/PhpToken.php
new file mode 100644
index 0000000..fe6e691
--- /dev/null
+++ b/web/app/vendor/symfony/polyfill-php80/PhpToken.php
@@ -0,0 +1,103 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Polyfill\Php80;
+
+/**
+ * @author Fedonyuk Anton
+ *
+ * @internal
+ */
+class PhpToken implements \Stringable
+{
+ /**
+ * @var int
+ */
+ public $id;
+
+ /**
+ * @var string
+ */
+ public $text;
+
+ /**
+ * @var int
+ */
+ public $line;
+
+ /**
+ * @var int
+ */
+ public $pos;
+
+ public function __construct(int $id, string $text, int $line = -1, int $position = -1)
+ {
+ $this->id = $id;
+ $this->text = $text;
+ $this->line = $line;
+ $this->pos = $position;
+ }
+
+ public function getTokenName(): ?string
+ {
+ if ('UNKNOWN' === $name = token_name($this->id)) {
+ $name = \strlen($this->text) > 1 || \ord($this->text) < 32 ? null : $this->text;
+ }
+
+ return $name;
+ }
+
+ /**
+ * @param int|string|array $kind
+ */
+ public function is($kind): bool
+ {
+ foreach ((array) $kind as $value) {
+ if (\in_array($value, [$this->id, $this->text], true)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ public function isIgnorable(): bool
+ {
+ return \in_array($this->id, [\T_WHITESPACE, \T_COMMENT, \T_DOC_COMMENT, \T_OPEN_TAG], true);
+ }
+
+ public function __toString(): string
+ {
+ return (string) $this->text;
+ }
+
+ /**
+ * @return static[]
+ */
+ public static function tokenize(string $code, int $flags = 0): array
+ {
+ $line = 1;
+ $position = 0;
+ $tokens = token_get_all($code, $flags);
+ foreach ($tokens as $index => $token) {
+ if (\is_string($token)) {
+ $id = \ord($token);
+ $text = $token;
+ } else {
+ [$id, $text, $line] = $token;
+ }
+ $tokens[$index] = new static($id, $text, $line, $position);
+ $position += \strlen($text);
+ }
+
+ return $tokens;
+ }
+}
diff --git a/web/app/vendor/symfony/polyfill-php80/README.md b/web/app/vendor/symfony/polyfill-php80/README.md
new file mode 100644
index 0000000..3816c55
--- /dev/null
+++ b/web/app/vendor/symfony/polyfill-php80/README.md
@@ -0,0 +1,25 @@
+Symfony Polyfill / Php80
+========================
+
+This component provides features added to PHP 8.0 core:
+
+- [`Stringable`](https://php.net/stringable) interface
+- [`fdiv`](https://php.net/fdiv)
+- [`ValueError`](https://php.net/valueerror) class
+- [`UnhandledMatchError`](https://php.net/unhandledmatcherror) class
+- `FILTER_VALIDATE_BOOL` constant
+- [`get_debug_type`](https://php.net/get_debug_type)
+- [`PhpToken`](https://php.net/phptoken) class
+- [`preg_last_error_msg`](https://php.net/preg_last_error_msg)
+- [`str_contains`](https://php.net/str_contains)
+- [`str_starts_with`](https://php.net/str_starts_with)
+- [`str_ends_with`](https://php.net/str_ends_with)
+- [`get_resource_id`](https://php.net/get_resource_id)
+
+More information can be found in the
+[main Polyfill README](https://github.com/symfony/polyfill/blob/main/README.md).
+
+License
+=======
+
+This library is released under the [MIT license](LICENSE).
diff --git a/web/app/vendor/symfony/polyfill-php80/Resources/stubs/Attribute.php b/web/app/vendor/symfony/polyfill-php80/Resources/stubs/Attribute.php
new file mode 100644
index 0000000..7ea6d27
--- /dev/null
+++ b/web/app/vendor/symfony/polyfill-php80/Resources/stubs/Attribute.php
@@ -0,0 +1,22 @@
+flags = $flags;
+ }
+}
diff --git a/web/app/vendor/symfony/polyfill-php80/Resources/stubs/PhpToken.php b/web/app/vendor/symfony/polyfill-php80/Resources/stubs/PhpToken.php
new file mode 100644
index 0000000..72f1081
--- /dev/null
+++ b/web/app/vendor/symfony/polyfill-php80/Resources/stubs/PhpToken.php
@@ -0,0 +1,7 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+use Symfony\Polyfill\Php80 as p;
+
+if (\PHP_VERSION_ID >= 80000) {
+ return;
+}
+
+if (!defined('FILTER_VALIDATE_BOOL') && defined('FILTER_VALIDATE_BOOLEAN')) {
+ define('FILTER_VALIDATE_BOOL', \FILTER_VALIDATE_BOOLEAN);
+}
+
+if (!function_exists('fdiv')) {
+ function fdiv(float $num1, float $num2): float { return p\Php80::fdiv($num1, $num2); }
+}
+if (!function_exists('preg_last_error_msg')) {
+ function preg_last_error_msg(): string { return p\Php80::preg_last_error_msg(); }
+}
+if (!function_exists('str_contains')) {
+ function str_contains(?string $haystack, ?string $needle): bool { return p\Php80::str_contains($haystack ?? '', $needle ?? ''); }
+}
+if (!function_exists('str_starts_with')) {
+ function str_starts_with(?string $haystack, ?string $needle): bool { return p\Php80::str_starts_with($haystack ?? '', $needle ?? ''); }
+}
+if (!function_exists('str_ends_with')) {
+ function str_ends_with(?string $haystack, ?string $needle): bool { return p\Php80::str_ends_with($haystack ?? '', $needle ?? ''); }
+}
+if (!function_exists('get_debug_type')) {
+ function get_debug_type($value): string { return p\Php80::get_debug_type($value); }
+}
+if (!function_exists('get_resource_id')) {
+ function get_resource_id($resource): int { return p\Php80::get_resource_id($resource); }
+}
diff --git a/web/app/vendor/symfony/polyfill-php80/composer.json b/web/app/vendor/symfony/polyfill-php80/composer.json
new file mode 100644
index 0000000..cd3e9b6
--- /dev/null
+++ b/web/app/vendor/symfony/polyfill-php80/composer.json
@@ -0,0 +1,40 @@
+{
+ "name": "symfony/polyfill-php80",
+ "type": "library",
+ "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions",
+ "keywords": ["polyfill", "shim", "compatibility", "portable"],
+ "homepage": "https://symfony.com",
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "Ion Bazan",
+ "email": "ion.bazan@gmail.com"
+ },
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "require": {
+ "php": ">=7.1"
+ },
+ "autoload": {
+ "psr-4": { "Symfony\\Polyfill\\Php80\\": "" },
+ "files": [ "bootstrap.php" ],
+ "classmap": [ "Resources/stubs" ]
+ },
+ "minimum-stability": "dev",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "1.26-dev"
+ },
+ "thanks": {
+ "name": "symfony/polyfill",
+ "url": "https://github.com/symfony/polyfill"
+ }
+ }
+}
diff --git a/web/css/uoj-bs5.css b/web/css/uoj-bs5.css
index 1019f61..80ac420 100644
--- a/web/css/uoj-bs5.css
+++ b/web/css/uoj-bs5.css
@@ -463,3 +463,8 @@ form.uoj-bs4-form-compressed button {
--bs-btn-hover-bg: #d3d4d570;
--bs-btn-hover-border-color: transparent;
}
+
+.remote-content center > img + span {
+ display: block;
+ font-size: 90%;
+}