Plugin Directory

Changeset 2109459


Ignore:
Timestamp:
06/20/2019 11:38:46 AM (7 years ago)
Author:
finteza
Message:

Update Finteza PHP SDK

File:
1 edited

Legend:

Unmodified
Added
Removed
  • finteza-analytics/trunk/lib/finteza-analytics.php

    r2071245 r2109459  
    4040     * Used if url did not specified in functions call
    4141     *
    42      * @@const string
     42     * @const string
    4343     */
    4444    const DEFAULT_URL = "https://content.mql5.com";
     45
     46    /**
     47     * Default user-agent for server-side events
     48     *
     49     * @const string
     50     */
     51    const DEFAULT_USER_AGENT = 'FintezaPHP/1.0';
    4552
    4653    /**
     
    105112        $path,
    106113        $websiteId,
    107         $referer = null,
    108         $token = null
     114        $referer,
     115        $token
    109116    ) {
    110         $this->_url = (is_null($url) || empty($url)) ? self::DEFAULT_URL : $url;
    111         $this->_token = $token;
     117
     118        // default values
     119        $url = (is_null($url) || empty($url)) ? self::DEFAULT_URL : $url;
     120        $path = (is_null($path) || empty($path)) ? '/' : $path;
     121        $websiteId = (is_null($websiteId) || empty($websiteId)) ? '' : $websiteId;
     122
     123        // check referer
     124        if (is_null($referer) || empty($referer)) {
     125            $is_ssl = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on';
     126            $referer = $is_ssl ? 'https' : 'http';
     127            $referer .= "://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
     128        }
     129
     130        // check path
     131        if (substr($path, 0, 1) != '/') {
     132            $path = '/' . $path;
     133        }
     134
     135        // save options
     136        $this->_url = $url;
    112137        $this->_path = $path;
    113138        $this->_websiteId = $websiteId;
    114139        $this->_referer = $referer;
     140        $this->_token = $token;
     141    }
     142
     143    /**
     144     * Send server event to Finteza
     145     *
     146     * @param array $options Event options
     147     *
     148     * @return bool True if request was sent successfully; otherwise False;
     149     *
     150     * @see https://www.finteza.com/en/integrations/php-sdk/php-sdk-events
     151     */
     152    public static function event($options)
     153    {
     154        if (is_null($options)) {
     155            return false;
     156        }
     157
     158        $fsdk = new self(
     159            $options['url'],
     160            null,
     161            $options['websiteId'],
     162            $options['referer'],
     163            $options['token']
     164        );
     165
     166        return $fsdk->_sendEvent(
     167            isset($options['name']) ? $options['name'] : null,
     168            isset($options['backReferer']) ? $options['backReferer'] : null,
     169            isset($options['userIp']) ? $options['userIp'] : null,
     170            isset($options['userAgent'])
     171                ? $options['userAgent']
     172                : DEFAULT_USER_AGENT,
     173            isset($options['value']) ? $options['value'] : null,
     174            isset($options['unit']) ? $options['unit'] : null
     175        );
     176    }
     177
     178    /**
     179     * Send event to Finteza
     180     *
     181     * @param string      $name        Event name
     182     * @param string|null $backReferer Back referer for event
     183     * @param string|null $userIp      User client ip for event
     184     * @param string|null $userAgent   User-Agent for event
     185     * @param string|null $value       Value param
     186     * @param string|null $unit        Unit for value param
     187     *
     188     * @return bool True if event was sent successfully; otherwise, False
     189     */
     190    private function _sendEvent(
     191        $name,
     192        $backReferer,
     193        $userIp,
     194        $userAgent,
     195        $value,
     196        $unit
     197    ) {
     198        // check event name
     199        if (empty($name)) {
     200            return false;
     201        }
     202
     203        // replace spaces
     204        $name = str_replace(' ', '+', $name);
     205
     206        // add path
     207        $path = '/tr?';
     208
     209        // add params
     210        $path .= 'id=' . urlencode($this->_websiteId);
     211        $path .= '&event=' . urlencode($name);
     212        $path .= '&ref=' . urlencode($this->_referer);
     213
     214        if (!is_null($backReferer) && !empty($backReferer)) {
     215            $path .= '&back_ref=' . urlencode($backReferer);
     216        }
     217        if (!is_null($value) && !empty($value)) {
     218            $path .= '&value=' . urlencode($value);
     219        }
     220        if (!is_null($unit) && !empty($unit)) {
     221            $path .= '&unit=' . urlencode($unit);
     222        }
     223
     224        // send request
     225        try
     226        {
     227            // get host
     228            $host = parse_url($this->_url)['host'];
     229
     230            // create connect
     231            $errno = '';
     232            $errstr = '';
     233            $fp = stream_socket_client('ssl://'. $host . ':443', $errno, $errstr, 5);
     234            if ($fp === false) {
     235                return false;
     236            }
     237
     238            // build headers
     239            $out  = "GET " . $path . " HTTP/1.1\r\n";
     240            $out .= "Host: " . $host . "\r\n";
     241
     242            if (!is_null($userIp) && !empty($userIp)) {
     243                $out .= "X-Forwarded-For: " . $userIp . "\r\n";
     244                $out .= "X-Forwarded-For-Sign: "
     245                     . md5($userIp . ':' . $this->_token)
     246                     . "\r\n";
     247            }
     248
     249            if (!is_null($userAgent) && !empty($userAgent)) {
     250                $out .= "User-Agent: " . $userAgent . "\r\n";
     251            }
     252
     253            $out .= "Connection: Close\r\n\r\n";
     254
     255            // connect and close
     256            fwrite($fp, $out);
     257            fclose($fp);
     258            return true;
     259        }
     260        catch (Exception $ex)
     261        {
     262            return false;
     263        }
    115264    }
    116265
     
    122271     * @return null Nothing
    123272     *
    124      * @see https://www.finteza.com/developer/sdks/php/
     273     * @see https://www.finteza.com/en/integrations/php-sdk/php-sdk-proxy
    125274     */
    126275    public static function proxy($options)
     
    138287        );
    139288
    140         $fsdk->_proxyTrack();
    141     }
    142 
    143     /**
    144      * Send server event to Finteza
    145      *
    146      * @param array $options Event options
    147      *
    148      * @return bool True if request was sent successfully; otherwise False;
    149      *
    150      * @see https://www.finteza.com/developer/sdks/php/
    151      */
    152     public static function event($options)
     289        $fsdk->_proxyRequest();
     290    }
     291
     292    /**
     293     * Set headers and outputs proxy content
     294     *
     295     * @return null Nothing
     296     */
     297    private function _proxyRequest()
    153298    {
    154         if (is_null($options)) {
    155             return false;
    156         }
    157 
    158         $fsdk = new self(
    159             isset($options['url']) ? $options['url'] : null,
    160             null,
    161             isset($options['websiteId']) ? $options['websiteId'] : null,
    162             isset($options['referer']) ? $options['referer'] : null,
    163             isset($options['token']) ? $options['token'] : null
     299        // get request properties
     300        $request_method = $_SERVER['REQUEST_METHOD'];
     301        $request_host = $_SERVER['HTTP_HOST'];
     302        $request_uri = $_SERVER['REQUEST_URI'];
     303        $request_port = $_SERVER['SERVER_PORT'];
     304        $request_params = $_GET;
     305        $request_body = file_get_contents('php://input');
     306
     307        // create proxy headers
     308        $proxy_headers = $this->_getProxyHeaders();
     309
     310        // create proxy URI (without domain and params)
     311        $proxy_uri = $request_uri;
     312        if (substr($proxy_uri, 0, strlen($this->_path)) == $this->_path) {
     313            $proxy_uri = substr($proxy_uri, strlen($this->_path));
     314        }
     315
     316        // counter scripts handler
     317        $has_corejs = preg_match('/core\.js$/', $proxy_uri) === 1;
     318        $has_ampjs = preg_match('/amp\.js$/', $proxy_uri) === 1;
     319
     320        if ($has_corejs || $has_ampjs) {
     321            $proxy_host = '//' . $request_host;
     322            if ($request_port != 443 && $request_port != 80) {
     323                $proxy_host .= ':' . $request_port;
     324            }
     325
     326            $has_params = strpos($proxy_uri, '?') !== false;
     327            $proxy_uri .= ($has_params ? '&' : '?');
     328            $proxy_uri .= 'host=' . urlencode($proxy_host) . $this->_path;
     329        }
     330
     331        // execute request
     332        $response = $this->_sendProxyRequest(
     333            $request_method,
     334            $proxy_uri,
     335            $proxy_headers,
     336            $request_body
    164337        );
    165338
    166         return $fsdk->_sendEvent(
    167             isset($options['name']) ? $options['name'] : null,
    168             isset($options['backReferer']) ? $options['backReferer'] : null,
    169             isset($options['userIp']) ? $options['userIp'] : null,
    170             isset($options['userAgent']) ? $options['userAgent'] : null,
    171             isset($options['value']) ? $options['value'] : null,
    172             isset($options['unit']) ? $options['unit'] : null
    173         );
    174     }
    175 
    176     /**
    177      * Set headers and outputs proxy content
    178      *
    179      * @return null Nothing
    180      */
    181     private function _proxyTrack()
    182     {
    183         $method = $_SERVER['REQUEST_METHOD'];
    184         $headers = $this->_createRequestHeaders();
    185         $params = $this->_createRequestParams($method);
    186         $url = $this->_createRequestUrl();
    187         $parsedUrl = parse_url($url);
    188 
    189         $path = $this->_path;
    190         $protocol = $_SERVER['SERVER_PORT'] == 443 ? "https://" : "http://";
    191         $port = '';
    192         if ($_SERVER['SERVER_PORT'] != 443 && $_SERVER['SERVER_PORT'] != 80) {
    193             $port = ':'.$_SERVER['SERVER_PORT'];
    194         }
    195 
    196         if (substr($path, 0, 1) != '/') {
    197             $path = '/' . $path;
    198         }
    199         // Handle core.js
    200         if (preg_match('/core\.js$/', $url) !== false
    201             && preg_match('/core\.js$/', $url) !== 0
    202         ) {
    203             $params['host'] = $protocol . $_SERVER['SERVER_NAME'] . $port . $path;
    204         }
    205         // Handle amp.js
    206         if (preg_match('/amp\.js$/', $url) !== false
    207             && preg_match('/amp\.js$/', $url) !== 0
    208         ) {
    209             $params['host'] = $protocol . $_SERVER['SERVER_NAME'] . $port . $path;
    210         }
    211         // Append query string for GET requests
    212         if ($method == 'GET'
    213             && count($params) > 0
    214             && (!array_key_exists('query', $parsedUrl) || empty($parsedUrl['query']))
    215         ) {
    216             $url .= '?' . http_build_query($params);
    217         }
    218         // Send request
    219         $response = $this->_sendRequest($url, $headers, $params, $method);
    220         $responseContent = $this->_processResponse($response);
    221 
    222         // Remove headers
     339        // parse response
     340        $responseContent = $this->_parseProxyResponse($request_method, $response);
     341
     342        // remove headers
    223343        header_remove('X-Powered-By');
    224         header_remove('Server');
    225 
    226         // Output result
     344
     345        // return response
    227346        print($responseContent);
    228347        exit;
     
    230349
    231350    /**
    232      * Send event to Finteza
    233      *
    234      * @param string      $name        Event name
    235      * @param string|null $backReferer Back referer for event
    236      * @param string|null $userIp      User client ip for event
    237      * @param string|null $userAgent   User-Agent for event
    238      * @param string|null $value       Value param
    239      * @param string|null $unit        Unit for value param
    240      *
    241      * @return bool True if event was sent successfully; otherwise, False
    242      */
    243     private function _sendEvent(
    244         $name,
    245         $backReferer = null,
    246         $userIp = null,
    247         $userAgent = null,
    248         $value = null,
    249         $unit = null
    250     ) {
    251         if (empty($name)) {
    252             return false;
    253         }
    254 
    255         $name = str_replace(' ', '+', $name);
    256 
    257         $url = $this->_url;
    258         if (!preg_match('/\/$/', $url)) {
    259             $url .= '/';
    260         }
    261        
    262         $url .= 'tr?';
    263         $query = 'id=' . urlencode($this->_websiteId);
    264         $query .= '&event=' . urlencode($name);
    265         $query .= '&ref=' . urlencode($this->_referer);
    266         if (!is_null($backReferer) && !empty($backReferer)) {
    267             $query .= '&back_ref=' . urlencode($backReferer);
    268         }
    269         if (!is_null($value) && !empty($value)) {
    270             $query .= '&value=' . urlencode($value);
    271         }
    272         if (!is_null($unit) && !empty($unit)) {
    273             $query .= '&unit=' . urlencode($unit);
    274         }
    275 
    276         $parts = parse_url($url);
    277         $parts['path'] .= '?'.$query;
    278 
    279         try {
    280             $fp = stream_socket_client(
    281                 'ssl://'.$parts['host'].':443',
    282                 $errno,
    283                 $errstr,
    284                 5
    285             );
    286             $parts['path'] .= '?'.$query;
    287             $out = "GET ".$parts['path']." HTTP/1.1\r\n";
    288             $out.= "Host: ".$parts['host']."\r\n";
    289             if (!is_null($userIp) && !empty($userIp)) {
    290                 $out.= "X-Forwarded-For: ".$userIp."\r\n";
    291                 $out.= "X-Forwarded-For-Sign: "
    292                     .md5($userIp . ':' . $this->_token)
    293                     ."\r\n";
    294             }
    295             if (!is_null($userAgent) && !empty($userAgent)) {
    296                 $out.= "User-Agent: ".$userAgent."\r\n";
    297             }
    298             $out.= "Connection: Close\r\n\r\n";
    299             fwrite($fp, $out);
    300             fclose($fp);
    301             return true;
    302         } catch (Exception $ex) {
    303             return false;
    304         }
    305     }
    306 
    307     /**
    308351     * Create request headers array for request to finteza server
    309352     *
    310353     * @return array Headers for request
    311354     */
    312     private function _createRequestHeaders()
     355    private function _getProxyHeaders()
    313356    {
    314357        // Identify request headers
     
    358401
    359402    /**
    360      * Create request params array for request to finteza server
    361      *
    362      * @param string $method Request method
    363      *
    364      * @return string|null Request params array or query string
    365      */
    366     private function _createRequestParams($method)
     403     * Sends request to finteza server
     404     *
     405     * @param string $method  Request method
     406     * @param string $uri     Request URI
     407     * @param array  $headers Request headers
     408     * @param string $body    Request body
     409     *
     410     * @return string
     411     */
     412    private function _sendProxyRequest($method, $uri, $headers, $body)
    367413    {
    368         if ('GET' == $method) {
    369             $params = $_GET;
    370         } elseif ('POST' == $method) {
    371             $params = $_POST;
    372             if (empty($params)) {
    373                 $data = file_get_contents('php://input');
    374                 if (!empty($data)) {
    375                     $params = $data;
    376                 }
    377             }
    378         } else {
    379             $params = null;
    380         }
    381 
    382         return $params;
    383     }
    384 
    385     /**
    386      * Create request URL to finteza server
    387      *
    388      * @return string
    389      */
    390     private function _createRequestUrl()
    391     {
    392         $currentUri = parse_url($_SERVER['REQUEST_URI']);
    393         $requestUrl = '';
    394         $cPath = $currentUri['path'];
    395 
    396         if (substr($cPath, 0, strlen($this->_path)) == $this->_path) {
    397             $requestUrl = $this->_url . substr($cPath, strlen($this->_path));
    398         }
    399 
    400         return $requestUrl;
    401     }
    402 
    403     /**
    404      * Sends request to finteza server
    405      *
    406      * @param string       $url     Request URL
    407      * @param array        $headers Request headers string
    408      * @param array|string $params  Request params array or query string
    409      * @param string       $method  Request method
    410      *
    411      * @return string
    412      */
    413     private function _sendRequest($url, $headers, $params, $method)
    414     {
     414
    415415        // let the request begin
    416         $request = curl_init($url);
     416        $request = curl_init($this->_url . $uri);
    417417
    418418        // (re-)send headers
     
    425425        curl_setopt($request, CURLOPT_HEADER, true);
    426426
    427         // add data for POST, PUT or DELETE requests
    428         if ('POST' == $method) {
    429             $postData = is_array($params) ? http_build_query($params) : $params;
     427        // set timeout
     428        curl_setopt($request, CURLOPT_CONNECTTIMEOUT, 5);
     429        curl_setopt($request, CURLOPT_TIMEOUT, 10);
     430
     431        // add data for POST-request
     432        if ($method == 'POST') {
    430433            curl_setopt($request, CURLOPT_POST, true);
    431             curl_setopt($request, CURLOPT_POSTFIELDS, $postData);
    432         }
    433        
     434            curl_setopt($request, CURLOPT_POSTFIELDS, $body);
     435            curl_setopt($request, CURLOPT_HTTPHEADER, array("Expect:"));
     436        }
     437
    434438        // retrieve response (headers and content)
    435439        $response = curl_exec($request);
     440
     441        // check errors
    436442        if (curl_errno($request)) {
    437443            return '';
    438444        }
     445
     446        // close connect
    439447        curl_close($request);
    440         if (false === $response) {
     448
     449        // check response
     450        if ($response == false) {
    441451            $response = '';
    442452        }
     453
    443454        return $response;
    444455    }
     
    447458     * Sets response headers and returns response content
    448459     *
     460     * @param object $method   Request method
    449461     * @param object $response Response handle object
    450462     *
    451463     * @return string Response content
    452464     */
    453     private function _processResponse($response)
     465    private function _parseProxyResponse($method, $response)
    454466    {
    455467        // split response to header and content
    456468        list($headers, $content) = preg_split('/(\r\n){2}/', $response, 2);
    457469
     470        // no parse POST-requests
     471        if ($method == 'POST') {
     472            return $content;
     473        }
     474
    458475        // (re-)send the headers
    459476        $headers = preg_split('/(\r\n){1}/', $headers);
     
    463480            if (substr($header, 0, strlen('Set-Cookie:')) !== 'Set-Cookie:') {
    464481                if (!preg_match('/^(Transfer-Encoding):/', $header)) {
    465                     header($header, false);
     482                    header($header, true);
    466483                }
    467484                continue;
     
    473490            $cookies = '';
    474491            foreach ($matches[1] as $item) {
    475 
    476492                if (!in_array($item, $this->_proxyCookies)) {
    477493                    continue;
     
    484500                    $paramLen = strlen('domain=');
    485501                    if (substr($matches[3][0], 0, $paramLen) === 'domain=') {
    486                         $cookies .= 'domain=' . $_SERVER['SERVER_NAME'];
     502                        $cookies .= 'domain=' . $_SERVER['HTTP_HOST'];
    487503                    }
    488504                }
     
    496512
    497513            if (!empty($cookies)) {
    498                 header('Set-Cookie:' . $cookies, false);
     514                header('Set-Cookie:' . $cookies, true);
    499515            }
    500516
Note: See TracChangeset for help on using the changeset viewer.