<?php
/*
class-scc-http.php

Description: This class is a common utility
Author: Daisuke Maruyama
Author URI: http://marubon.info/
License: GPL2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.txt
*/

/*
Copyright (C) 2014 - 2018 Daisuke Maruyama

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*/

class SCC_HTTP {

	/**
	 * Class constarctor
	 * Hook onto all of the actions and filters needed by the plugin.
	 *
	 */
	protected function __construct() {
		SCC_Logger::log( '[' . __METHOD__ . '] (line=' . __LINE__ . ')' );
	}

	/**
	 * Get cout data from SNS using GET method.
	 * @param  [type]  $urls      [description]
	 * @param  [type]  $headers   [description]
	 * @param  integer $timeout   [description]
	 * @param  boolean $sslverify [description]
	 * @param  boolean $curl      [description]
	 * @return [type]             [description]
	 */
	public static function multi_remote_get( $urls, $headers, $timeout = 0, $sslverify = true, $curl = false ) {
		global $wp_version;

		$responses = array();

		if ( empty( $urls ) ) {
			return $responses;
		}

		if ( $curl ) {
			SCC_Logger::log( '[' . __METHOD__ . '] cURL: On' );

			$mh = curl_multi_init();
			$ch = array();

			foreach ( $urls as $sns => $url ) {
				$ch[ $sns ] = curl_init();

				curl_setopt( $ch[ $sns ], CURLOPT_URL, $url );
				curl_setopt( $ch[ $sns ], CURLOPT_USERAGENT, 'WordPress/' . $wp_version . '; ' . get_bloginfo( 'url' ) );
				curl_setopt( $ch[ $sns ], CURLOPT_FOLLOWLOCATION, true );
				curl_setopt( $ch[ $sns ], CURLOPT_RETURNTRANSFER, true );
				curl_setopt( $ch[ $sns ], CURLOPT_ENCODING, 'gzip' );

				if ( ! empty( $headers[ $sns ] ) ) {
					//curl_setopt( $ch[$sns], CURLOPT_HEADER, true );

					$http_headers = array();

					foreach ( $headers[ $sns ] as $key => $value ) {
						$http_headers[] = $key . ': ' . $value;
					}

					curl_setopt( $ch[ $sns ], CURLOPT_HTTPHEADER, $http_headers );
				}

				if ( $sslverify ) {
					curl_setopt( $ch[ $sns ], CURLOPT_SSL_VERIFYPEER, true );
					curl_setopt( $ch[ $sns ], CURLOPT_SSL_VERIFYHOST, 2 );
				} else {
					curl_setopt( $ch[ $sns ], CURLOPT_SSL_VERIFYPEER, false );
					curl_setopt( $ch[ $sns ], CURLOPT_SSL_VERIFYHOST, 0 );
				}

				if ( $timeout > 0 ) {
					curl_setopt( $ch[ $sns ], CURLOPT_CONNECTTIMEOUT, $timeout );
					curl_setopt( $ch[ $sns ], CURLOPT_TIMEOUT, $timeout );
				}

				curl_multi_add_handle( $mh, $ch[ $sns ] );
			} // End foreach().

			$active = null;

			do {
				curl_multi_exec( $mh, $active );
				curl_multi_select( $mh );
			} while ( $active > 0 );

			foreach ( $urls as $sns => $url ) {
				$responses[ $sns ]['error'] = curl_error( $ch[ $sns ] );

				if ( ! empty( $responses[ $sns ]['error'] ) ) {
					$responses[ $sns ]['data']  = '';
				} else {
					$responses[ $sns ]['data']  = curl_multi_getcontent( $ch[ $sns ] );
				}

				curl_multi_remove_handle( $mh, $ch[ $sns ] );
				curl_close( $ch[ $sns ] );
			}

			curl_multi_close( $mh );

			return $responses;
		} else {

			SCC_Logger::log( '[' . __METHOD__ . '] cURL: Off' );

			foreach ( $urls as $sns => $url ) {

				$options = array(
					'user-agent' => 'WordPress/' . $wp_version . '; ' . get_bloginfo( 'url' ),
				);

				if ( $sslverify ) {
					$options['sslverify'] = true;
				} else {
					$options['sslverify'] = false;
				}

				if ( $timeout > 0 ) {
					$options['timeout'] = $timeout;
				}

				if ( ! empty( $headers[ $sns ] ) ) {
					$options['headers'] = $headers[ $sns ];
				}

				$response = wp_remote_get( $url, $options );

				if ( ! is_wp_error( $response ) ) {
					if ( 200 === $response['response']['code'] ) {
						$responses[ $sns ]['data'] = $response['body'];
					} else {
						$responses[ $sns ]['data'] = '';
						$responses[ $sns ]['error'] = $response['response']['code'] . ': ' . $response['response']['message'];
					}
				} else {
					$responses[ $sns ]['data'] = '';
					$responses[ $sns ]['error'] = $response->get_error_message();
				}
			}

			return $responses;
		} // End if().
	}

	/**
	 * Get cout data from SNS based on given HTTP method.
	 * @param  [type]  $urls      [description]
	 * @param  [type]  $methods   [description]
	 * @param  [type]  $headers   [description]
	 * @param  [type]  $bodies  [description]
	 * @param  integer $timeout   [description]
	 * @param  boolean $sslverify [description]
	 * @param  boolean $curl      [description]
	 * @return [type]             [description]
	 */
	public static function multi_remote_request( $urls, $methods, $headers, $bodies, $timeout = 0, $sslverify = true, $curl = false ) {
		global $wp_version;

		$responses = array();

		if ( empty( $urls ) ) {
			return $responses;
		}

		if ( $curl ) {
			SCC_Logger::log( '[' . __METHOD__ . '] cURL: On' );

			$mh = curl_multi_init();
			$ch = array();

			foreach ( $urls as $sns => $url ) {
				$ch[ $sns ] = curl_init();

				curl_setopt( $ch[ $sns ], CURLOPT_URL, $url );
				curl_setopt( $ch[ $sns ], CURLOPT_USERAGENT, 'WordPress/' . $wp_version . '; ' . get_bloginfo( 'url' ) );
				curl_setopt( $ch[ $sns ], CURLOPT_FOLLOWLOCATION, true );
				curl_setopt( $ch[ $sns ], CURLOPT_RETURNTRANSFER, true );
				curl_setopt( $ch[ $sns ], CURLOPT_ENCODING, 'gzip' );

				if ( ! empty( $headers[ $sns ] ) ) {
					$http_headers = array();

					foreach ( $headers[ $sns ] as $key => $value ) {
						$http_headers[] = $key . ': ' . $value;
					}

					curl_setopt( $ch[ $sns ], CURLOPT_HTTPHEADER, $http_headers );
				}

				if ( $sslverify ) {
					curl_setopt( $ch[ $sns ], CURLOPT_SSL_VERIFYPEER, true );
					curl_setopt( $ch[ $sns ], CURLOPT_SSL_VERIFYHOST, 2 );
				} else {
					curl_setopt( $ch[ $sns ], CURLOPT_SSL_VERIFYPEER, false );
					curl_setopt( $ch[ $sns ], CURLOPT_SSL_VERIFYHOST, 0 );
				}

				if ( $timeout > 0 ) {
					curl_setopt( $ch[ $sns ], CURLOPT_CONNECTTIMEOUT, $timeout );
					curl_setopt( $ch[ $sns ], CURLOPT_TIMEOUT, $timeout );
				}

				if ( isset( $methods[ $sns ] ) && 'POST' === $methods[ $sns ] ) {
					curl_setopt( $ch[ $sns ], CURLOPT_POST, true );
					if ( isset( $bodies[ $sns ] ) ) {
						curl_setopt( $ch[ $sns ], CURLOPT_POSTFIELDS, json_encode( $bodies[ $sns ] ) );
					}
				}

				curl_multi_add_handle( $mh, $ch[ $sns ] );
			} // End foreach().

			$active = null;

			do {
				curl_multi_exec( $mh, $active );
				curl_multi_select( $mh );
			} while ( $active > 0 );

			foreach ( $urls as $sns => $url ) {
				$responses[ $sns ]['error'] = curl_error( $ch[ $sns ] );

				if ( ! empty( $responses[ $sns ]['error'] ) ) {
					$responses[ $sns ]['data']  = '';
				} else {
					$responses[ $sns ]['data']  = curl_multi_getcontent( $ch[ $sns ] );
				}

				curl_multi_remove_handle( $mh, $ch[ $sns ] );
				curl_close( $ch[ $sns ] );
			}

			curl_multi_close( $mh );

			return $responses;
		} else {

			SCC_Logger::log( '[' . __METHOD__ . '] cURL: Off' );

			foreach ( $urls as $sns => $url ) {

				$options = array(
					'user-agent' => 'WordPress/' . $wp_version . '; ' . get_bloginfo( 'url' ),
				);

				if ( $sslverify ) {
					$options['sslverify'] = true;
				} else {
					$options['sslverify'] = false;
				}

				if ( $timeout > 0 ) {
					$options['timeout'] = $timeout;
				}

				if ( ! empty( $headers[ $sns ] ) ) {
					$options['headers'] = $headers[ $sns ];
				}

				if ( isset( $methods[ $sns ] ) ) {
					if ( 'GET' === $methods[ $sns ] ) {
						$response = wp_remote_get( $url, $options );
					} elseif ( 'POST' === $methods[ $sns ] ) {
						if ( isset( $bodies[ $sns ] ) ) {
							$options['body'] = json_encode( $bodies[ $sns ] );
						}
						$response = wp_remote_post( $url, $options );
					} else {
						$response = wp_remote_get( $url, $options );
					}
				}

				if ( ! is_wp_error( $response ) ) {
					if ( 200 === $response['response']['code'] ) {
						$responses[ $sns ]['data'] = $response['body'];
					} else {
						$responses[ $sns ]['data'] = '';
						$responses[ $sns ]['error'] = $response['response']['code'] . ': ' . $response['response']['message'];
					}
				} else {
					$responses[ $sns ]['data'] = '';
					$responses[ $sns ]['error'] = $response->get_error_message();
				}
			} // End foreach().

			return $responses;
		} // End if().
	}

}

?>
