diff --git a/.gitignore b/.gitignore index caed59f..279e495 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ vendor tests/log composer.phar composer.lock +.idea \ No newline at end of file diff --git a/composer.json b/composer.json index 32f70cc..c5f649d 100644 --- a/composer.json +++ b/composer.json @@ -11,8 +11,7 @@ } ], "require": { - "php": ">=5.3.0", - "alexsoft/curl": "0.4.*@dev" + "php": ">=5.3.0" }, "require-dev":{ "phpunit/phpunit":"3.7.*", diff --git a/src/Asakusuma/SugarWrapper/Rest.php b/src/Asakusuma/SugarWrapper/Rest.php index 70a199d..70d9a27 100644 --- a/src/Asakusuma/SugarWrapper/Rest.php +++ b/src/Asakusuma/SugarWrapper/Rest.php @@ -124,7 +124,7 @@ public function loggedInUserInfo() * @param string $rest_url * @param string $username * @param string $password - * @param string $md5_password + * @param boolean $md5_password * @return boolean */ function connect($rest_url = null, $username = null, $password = null, $md5_password = true) @@ -257,7 +257,7 @@ private function login($md5_password = true) * @param \Alexsoft\Curl $curl * @return \Asakusuma\SugarWrapper\Rest */ - public function setCurl(\Alexsoft\Curl $curl) + public function setCurl(Curl $curl) { $this->request = $curl; @@ -384,7 +384,7 @@ public function count_records($module, $query) * $options['where'] = WHERE clause for an SQL statement * $options['order_by'] = ORDER BY clause for an SQL statement * - * @return array + * @return array | boolean */ public function get_with_related($module, $fields, $options = array()) { @@ -698,9 +698,11 @@ public function get_available_modules() * @param array $modules The array of modules to query * @param int $offset A specified offset in the query * @param int $max_results Max number of records to return + * @param string $assigned_user_id + * @param array $fields * @return array */ - public function search_by_module($search_string, $modules, $offset, $max_results) + public function search_by_module($search_string, $modules, $offset, $max_results, $assigned_user_id = '', $fields = array()) { $call_arguments = array( 'session' => $this->session, @@ -708,10 +710,12 @@ public function search_by_module($search_string, $modules, $offset, $max_results 'modules' => $modules, 'offset' => $offset, 'max_results' => $max_results, + 'assigned_user_id' => $assigned_user_id, + 'select_fields' => $fields ); $result = $this->rest_request( - 'search_by_module', $call_arguments + 'search_by_module', $call_arguments ); return $result; @@ -774,7 +778,7 @@ public function get_by_id($id, $module, $fields, $options = array()) $options ); - $records = array(); + $record = array(); if ($results) { foreach ($results['entry_list'] as $entry) { @@ -819,7 +823,7 @@ public function get_by_id($id, $module, $fields, $options = array()) * $options['where'] = WHERE clause for an SQL statement * $options['order_by'] = ORDER BY clause for an SQL statement * - * @return array + * @return array | boolean */ public function get_entry($id, $module, $fields, $options = array()) { diff --git a/src/alexsoft/curl/.gitignore b/src/alexsoft/curl/.gitignore new file mode 100644 index 0000000..241fb83 --- /dev/null +++ b/src/alexsoft/curl/.gitignore @@ -0,0 +1,2 @@ +/vendor +.idea diff --git a/src/alexsoft/curl/.travis.yml b/src/alexsoft/curl/.travis.yml new file mode 100644 index 0000000..e39ac84 --- /dev/null +++ b/src/alexsoft/curl/.travis.yml @@ -0,0 +1,12 @@ +language: php +php: + - 5.4 + - 5.5 + - 5.6 + - hhvm +install: + - composer require lib-curl:* +matrix: + allow_failures: + - php: 5.6 + - php: hhvm diff --git a/src/alexsoft/curl/LICENSE b/src/alexsoft/curl/LICENSE new file mode 100644 index 0000000..5b8c1f8 --- /dev/null +++ b/src/alexsoft/curl/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2013 Alex Plekhanov + +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. \ No newline at end of file diff --git a/src/alexsoft/curl/README.md b/src/alexsoft/curl/README.md new file mode 100644 index 0000000..4382743 --- /dev/null +++ b/src/alexsoft/curl/README.md @@ -0,0 +1,40 @@ +# cURL wrapper + +[![Latest Stable Version](https://poser.pugx.org/alexsoft/curl/v/stable.png)](https://packagist.org/packages/alexsoft/curl) +[![License](https://poser.pugx.org/alexsoft/curl/license.png)](https://packagist.org/packages/alexsoft/curl) + +A copy of the original package from [https://github.com/alexsoft/curl](https://github.com/alexsoft/curl) + +## Versions and changelog + +### v0.4.0-dev (dev-master) +Got rid of get(), post(), head(), put(), delete(), options() methods. +Instead a __call method now does everything. + +### v0.3.0 +Wrapper is totally reworked almost from scratch! +Different approach for setting data, headers and cookies. +Just open the class and see it! +And by the way all class is now documented! + +### v0.2.2 +Added methods: +- PUT +- DELETE +- OPTIONS + +Cookies are parsed with help of preg_match_all. + +### v0.2.1 +Methods: +- GET +- HEAD +- POST + +You can send data, headers and cookies along with the queries. + +## Roadmap +- Make setOptions method +- Make downloading images possible +- Refactor _parseResponse method +- Make a documentation diff --git a/src/alexsoft/curl/composer.json b/src/alexsoft/curl/composer.json new file mode 100644 index 0000000..6a21227 --- /dev/null +++ b/src/alexsoft/curl/composer.json @@ -0,0 +1,21 @@ +{ + "name": "alexsoft/curl", + "description": "cURL wrapper", + "keywords": ["php", "curl"], + "license": "MIT", + "authors": [ + { + "name": "Alex Plekhanov" + } + ], + "require": { + "php": ">=5.4.0", + "lib-curl": "*" + }, + "autoload": { + "psr-0": { + "Alexsoft\\": "src/" + } + }, + "minimum-stability": "stable" +} \ No newline at end of file diff --git a/src/alexsoft/curl/phpunit.xml b/src/alexsoft/curl/phpunit.xml new file mode 100644 index 0000000..e89ac6d --- /dev/null +++ b/src/alexsoft/curl/phpunit.xml @@ -0,0 +1,18 @@ + + + + + ./tests/ + + + \ No newline at end of file diff --git a/src/alexsoft/curl/src/Alexsoft/Curl.php b/src/alexsoft/curl/src/Alexsoft/Curl.php new file mode 100644 index 0000000..45c498d --- /dev/null +++ b/src/alexsoft/curl/src/Alexsoft/Curl.php @@ -0,0 +1,286 @@ + value of data to send + * @var array + */ + protected $data = []; + + /** + * Key => value of headers to send + * @var array + */ + protected $headers = []; + + /** + * Key => value of cookies to send + * @var array + */ + protected $cookies = []; + + /** + * User agent for query + * @var string + */ + protected $userAgent = 'alexsoft/curl'; + + /** + * Array of available HTTP Verbs + * @var array + */ + protected $availableMethods = [self::GET, self::POST, self::HEAD, self::PUT, self::DELETE, self::PATCH]; + + /** + * @param $url string URL for query + */ + public function __construct($url = null) + { + $this->url = $url; + } + + /** + * Add data for sending + * @param array $data + * @return $this + */ + public function addData(array $data) + { + $this->data = array_merge( + $this->data, + $data + ); + return $this; + } + + /** + * Add headers for sending + * @param array $headers + * @return $this + */ + public function addHeaders(array $headers) + { + $this->headers = array_merge( + $this->headers, + $headers + ); + return $this; + } + + /** + * Add cookies for sending + * @param array $cookies + * @return $this + */ + public function addCookies(array $cookies) + { + $this->cookies = array_merge( + $this->cookies, + $cookies + ); + return $this; + } + + /** + * Methods which can be called: + * get(), post(), head(), put(), delete(), options() + * @param $name + * @param $arguments + * @return array|NULL + * @throws \Exception + */ + function __call($name, $arguments) + { + if (!empty($arguments)) { + $url = $arguments[0]; + if (is_string($url) && filter_var($url, FILTER_VALIDATE_URL)) { + $this->url = $url; + } else { + throw new \Exception('Wrong url. Give a correct url in a string format.'); + } + } else { + if (is_null($this->url)) { + throw new \Exception('Provide a url either in constructor or while calling verb method.'); + } + } + + if (in_array(mb_strtoupper($name), $this->availableMethods)) { + return $this->request(mb_strtoupper($name)); + } else { + throw new \Exception('Method ' . mb_strtoupper($name) . ' is not supported'); + } + } + + /** + * @param $method string method of query + * @return array|NULL + */ + protected function request($method) + { + $this->resource = curl_init(); + $this->method = $method; + $this->prepareRequest(); + $this->response = curl_exec($this->resource); + curl_close($this->resource); + return $this->parseResponse(); + } + + /** + * Method which sets all the data, headers, cookies + * and other options for the query + */ + protected function prepareRequest() + { + // Set data for GET queries + if ($this->method === static::GET && !empty($this->data)) { + $url = trim($this->url, '/') . '?'; + $url .= http_build_query($this->data); + } else { + $url = $this->url; + } + + // Set options + $options = array( + CURLOPT_URL => $url, + CURLOPT_POST => $this->method === static::POST, + CURLOPT_HEADER => true, + CURLOPT_NOBODY => $this->method === static::HEAD, + CURLOPT_RETURNTRANSFER => true, + CURLOPT_USERAGENT => $this->userAgent, + CURLOPT_SSL_VERIFYPEER => false + ); + + if (!in_array($this->method, [static::GET, static::HEAD, static::POST])) { + $options[CURLOPT_CUSTOMREQUEST] = $this->method; + } + + // Set data for not GET queries + if (!empty($this->data) && $this->method !== static::GET) { + $options[CURLOPT_POSTFIELDS] = http_build_query($this->data); + } + + // Set headers if needed + if (!empty($this->headers)) { + $headersToSend = []; + foreach ($this->headers as $key => $value) { + $headersToSend[] = "{$key}: {$value}"; + } + $options[CURLOPT_HTTPHEADER] = $headersToSend; + } + + // Set cookies if needed + if (!empty($this->cookies)) { + $cookiesToSend = []; + foreach ($this->cookies as $key => $value) { + $cookiesToSend[] = "{$key}={$value}"; + } + $options[CURLOPT_COOKIE] = implode('; ', $cookiesToSend); + } + + curl_setopt_array($this->resource, $options); + } + + /** + * Method which parses cURL response + * @return array|NULL + */ + protected function parseResponse() + { + if (isset($this->response)) { + list($responseParts['headersString'], $responseParts['body']) = explode("\r\n\r\n", $this->response, 2); + $responseParts['body'] = htmlspecialchars($responseParts['body']); + $headers = explode("\r\n", $responseParts['headersString']); + + $cookies = []; + if (preg_match_all('/Set-Cookie: (.*?)=(.*?)(\n|;)/i', $responseParts['headersString'], $matches)) { + if (!empty($matches)) { + foreach ($matches[1] as $key => $value) { + $cookies[$value] = $matches[2][$key]; + } + $responseParts['cookies'] = $cookies; + } + } + unset($responseParts['headersString']); + + $first = true; + foreach ($headers as $header) { + if ($first) { + list($responseParts['protocol'], $responseParts['statusCode']) = explode(' ', $header, 2); + $first = false; + } else { + $tmp = (explode(': ', $header)); + if ($tmp[0] === 'Set-Cookie') { + continue; + } else { + $responseParts['headersArray'][$tmp[0]] = $tmp[1]; + } + } + } + return $responseParts; + } else { + return null; + } + } + + /** + * Validate that a value is a valid URL. + * @param mixed $value + * @return bool + */ + protected function isValidUrl($value) + { + return filter_var($value, FILTER_VALIDATE_URL) !== false; + } +} \ No newline at end of file diff --git a/src/alexsoft/curl/tests/CurlTest.php b/src/alexsoft/curl/tests/CurlTest.php new file mode 100644 index 0000000..8daa11c --- /dev/null +++ b/src/alexsoft/curl/tests/CurlTest.php @@ -0,0 +1,25 @@ +assertInstanceOf('Alexsoft\Curl', $curl); + + $this->assertInstanceOf('Alexsoft\Curl', $curl->addData(array('data' => 'allalone'))); + + $this->assertInstanceOf( + 'Alexsoft\Curl', + $curl->addHeaders(array('header1' => 'php', 'header2' => 'javascript')) + ); + + $this->assertInstanceOf('Alexsoft\Curl', $curl->addCookies(array('cookie1' => 'ci', 'cookie2' => 'travis'))); + + $this->assertArrayHasKey('statusCode', $curl->get()); + } + +} \ No newline at end of file