1<?php
2/**
3 * -----------------------------------------------------------------------
4 * vBSSO is a solution which helps you connect to different software platforms
5 * via secure Single Sign-On.
6 *
7 * Copyright (c) 2011-2017 vBSSO. All Rights Reserved.
8 * This software is the proprietary information of vBSSO.
9 *
10 * Author URI: http://www.vbsso.com
11 * License: GPL version 2 or later - http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
12 * -----------------------------------------------------------------------
13 *
14 */
15
16if (!defined('SHAREDAPI')) {
17    define ('SHAREDAPI_PRODUCT_VERSION_1_9', '1.9');
18    define ('SHAREDAPI_PRODUCT_VERSION_1_8', '1.8');
19    define ('SHAREDAPI_PRODUCT_VERSION_1_7', '1.7');
20    define ('SHAREDAPI_PRODUCT_VERSION_1_6', '1.6');
21    define ('SHAREDAPI_PRODUCT_VERSION_1_5', '1.5');
22    define ('SHAREDAPI_PRODUCT_VERSION_1_4', '1.4');
23    define ('SHAREDAPI_PRODUCT_VERSION_1_3', '1.3');
24    define ('SHAREDAPI_PRODUCT_VERSION_1_2', '1.2');
25    define ('SHAREDAPI_PRODUCT_VERSION_1_1', '1.1');
26    define ('SHAREDAPI_PRODUCT_VERSION_1_0', '1.0');
27
28    define ('SHAREDAPI', SHAREDAPI_PRODUCT_VERSION_1_9);
29
30    define ('SHAREDAPI_PRODUCT_ID', 'sharedapi');
31    define ('SHAREDAPI_PRODUCT_NAME', 'SharedAPI');
32    define ('SHAREDAPI_PRODUCT_VERSION', SHAREDAPI);
33
34    define ('SHAREDAPI_DEFAULT_API_KEY', 'simplekey');
35    define ('SHAREDAPI_WRONG_API_KEY_MESSAGE', 'Wrong Shared Password');
36
37
38    define ('SHAREDAPI_EVENT_FIELD_EVENT', 'e');
39    define ('SHAREDAPI_EVENT_FIELD_PRODUCT', 'product');
40    define ('SHAREDAPI_EVENT_FIELD_VERSION', 'version');
41    define ('SHAREDAPI_EVENT_FIELD_PLUGIN_VERSION', 'plugin_version');
42    define ('SHAREDAPI_EVENT_FIELD_PLUGIN_REVISION', 'plugin_revision');
43    define ('SHAREDAPI_EVENT_FIELD_VERIFY', 'verify');
44    define ('SHAREDAPI_EVENT_FIELD_PHP_VERSION', 'php');
45    define ('SHAREDAPI_EVENT_FIELD_MEMORY_LIMIT', 'memory_limit');
46    define ('SHAREDAPI_EVENT_FIELD_WP_MEMORY_LIMIT', 'wp_memory_limit');
47
48    define ('SHAREDAPI_EVENT_FIELD_API_KEY', 'apikey');
49    define ('SHAREDAPI_EVENT_FIELD_LID', 'lid');
50    define ('SHAREDAPI_EVENT_FIELD_LISTENER_URL', 'listener_url');
51    define ('SHAREDAPI_EVENT_FIELD_BAA_USERNAME', 'baa_username');
52    define ('SHAREDAPI_EVENT_FIELD_BAA_PASSWORD', 'baa_password');
53
54    define ('SHAREDAPI_EVENT_FIELD_LOGIN_VBULLETIN_URL', 'login_vbulletin_url');
55    define ('SHAREDAPI_EVENT_FIELD_LOGIN_URL', 'login_url');
56    define ('SHAREDAPI_EVENT_FIELD_LOGOUT_URL', 'logout_url');
57    define ('SHAREDAPI_EVENT_FIELD_REGISTER_URL', 'register_url');
58    define ('SHAREDAPI_EVENT_FIELD_LOSTPASSWORD_URL', 'lostpassword_url');
59    define ('SHAREDAPI_EVENT_FIELD_AVATAR_URL', 'avatar_url');
60    define ('SHAREDAPI_EVENT_FIELD_PROFILE_URL', 'profile_url');
61    define ('SHAREDAPI_EVENT_FIELD_USERGROUPS_URL', 'usergroups_url');
62    define ('SHAREDAPI_EVENT_FIELD_USER_UNREAD_STATS_URL', 'user_unread_stats_url');
63    define ('SHAREDAPI_EVENT_FIELD_STATS_URL', 'stats_url');
64
65    define ('SHAREDAPI_EVENT_FIELD_STAT_PM', 'pm'); //personal messages
66    define ('SHAREDAPI_EVENT_FIELD_STAT_VM', 'vm'); //visitors messages
67    define ('SHAREDAPI_EVENT_FIELD_STAT_FR', 'fr'); //friend requests
68    define ('SHAREDAPI_EVENT_FIELD_STAT_PC', 'pc'); //pictures comments
69
70    define ('SHAREDAPI_EVENT_FIELD_DESTINATION', 'd');
71    define ('SHAREDAPI_EVENT_FIELD_TIMEOUT', 'timeout');
72    define ('SHAREDAPI_EVENT_FIELD_MUID', 'muid');
73    define ('SHAREDAPI_EVENT_FIELD_REMEMBERME', 'remember-me');
74
75    define ('SHAREDAPI_EVENT_FIELD_DATA', 'data');
76    define ('SHAREDAPI_EVENT_FIELD_ERROR', 'error');
77    define ('SHAREDAPI_EVENT_FIELD_ERROR_CODE', 'code');
78    define ('SHAREDAPI_EVENT_FIELD_ERROR_MESSAGE', 'message');
79    define ('SHAREDAPI_EVENT_FIELD_ERROR_DATA', 'data');
80
81    define ('SHAREDAPI_EVENT_FIELD_USERLIST', 'userlist');
82    define ('SHAREDAPI_EVENT_FIELD_USERID', 'userid');
83    define ('SHAREDAPI_EVENT_FIELD_USERGROUPS', 'usergroup');
84    define ('SHAREDAPI_EVENT_FIELD_USERGROUPS2', 'usergroup2');
85    define ('SHAREDAPI_EVENT_FIELD_USERNAME', 'username');
86    define ('SHAREDAPI_EVENT_FIELD_USERNAME2', 'username2');
87    define ('SHAREDAPI_EVENT_FIELD_EMAIL', 'email');
88    define ('SHAREDAPI_EVENT_FIELD_EMAIL2', 'email2');
89    define ('SHAREDAPI_EVENT_FIELD_PASSWORD', 'password');
90
91    define ('SHAREDAPI_EVENT_FIELD_PROFILE_FIELDS', 'profile_fields');
92    define ('SHAREDAPI_EVENT_FIELD_PROFILE_FIRST_NAME', 'profile_firstname');
93    define ('SHAREDAPI_EVENT_FIELD_PROFILE_LAST_NAME', 'profile_lastname');
94    define ('SHAREDAPI_EVENT_FIELD_PROFILE_COUNTRY', 'profile_country');
95    define ('SHAREDAPI_EVENT_FIELD_PROFILE_CITY', 'profile_city');
96    define ('SHAREDAPI_EVENT_FIELD_PROFILE_PHONE', 'profile_phone');
97    define ('SHAREDAPI_EVENT_FIELD_PROFILE_BIRTH', 'profile_birth');
98
99    define ('SHAREDAPI_EVENT_UNKNOWN', 0);
100    define ('SHAREDAPI_EVENT_VERIFY', 1);
101
102    define ('SHAREDAPI_EVENT_LOGIN', 2);
103    define ('SHAREDAPI_EVENT_AUTHENTICATION', 3);
104    define ('SHAREDAPI_EVENT_SESSION', 4);
105    define ('SHAREDAPI_EVENT_LOGOUT', 5);
106    define ('SHAREDAPI_EVENT_REGISTER', 6);
107    define ('SHAREDAPI_EVENT_CREDENTIALS', 7);
108    define ('SHAREDAPI_EVENT_PROFILE_FIELDS', 8);
109    define ('SHAREDAPI_EVENT_CONFLICT_USERS', 9);
110
111    define ('SHAREDAPI_EVENT_LAST', 50);
112
113    function sharedapi_get_events() {
114        static $events;
115
116        if (!$events) {
117            $events = array(
118                SHAREDAPI_EVENT_UNKNOWN => 'unknown',
119                SHAREDAPI_EVENT_VERIFY => 'verify',
120                SHAREDAPI_EVENT_LOGIN => 'login',
121                SHAREDAPI_EVENT_AUTHENTICATION => 'i',
122                SHAREDAPI_EVENT_SESSION => 'session',
123                SHAREDAPI_EVENT_LOGOUT => 'o',
124                SHAREDAPI_EVENT_REGISTER => 'register',
125                SHAREDAPI_EVENT_CREDENTIALS => 'credentials',
126                SHAREDAPI_EVENT_PROFILE_FIELDS => 'profile-fields',
127                SHAREDAPI_EVENT_CONFLICT_USERS => 'conflict_users'
128            );
129        }
130
131        return $events;
132    }
133
134    /**
135     * Product constants
136     */
137    define ('SHAREDAPI_PLATFORM_UNKNOWN', 0);
138    define ('SHAREDAPI_PLATFORM_VBULLETIN', 1);
139    define ('SHAREDAPI_PLATFORM_INTERSPIRESHOPPINGCART', 2);
140    define ('SHAREDAPI_PLATFORM_MOODLE', 3);
141    define ('SHAREDAPI_PLATFORM_WORDPRESS', 4);
142    define ('SHAREDAPI_PLATFORM_JOOMLA', 5);
143    define ('SHAREDAPI_PLATFORM_DRUPAL', 6);
144    define ('SHAREDAPI_PLATFORM_PRESTASHOP', 7);
145    define ('SHAREDAPI_PLATFORM_MAGENTO', 8);
146    define ('SHAREDAPI_PLATFORM_MEDIAWIKI', 9);
147    define ('SHAREDAPI_PLATFORM_DOKUWIKI', 10);
148
149    function sharedapi_get_platforms($platform = null) {
150        static $platforms;
151
152        if (!$platforms) {
153            $platforms = array(
154                SHAREDAPI_PLATFORM_UNKNOWN => 'Unknown',
155                SHAREDAPI_PLATFORM_VBULLETIN => 'vBulletin',
156                SHAREDAPI_PLATFORM_INTERSPIRESHOPPINGCART => 'Interspire Shopping Cart',
157                SHAREDAPI_PLATFORM_MOODLE => 'Moodle',
158                SHAREDAPI_PLATFORM_WORDPRESS => 'WordPress',
159                SHAREDAPI_PLATFORM_JOOMLA => 'Joomla',
160                SHAREDAPI_PLATFORM_DRUPAL => 'Drupal',
161                SHAREDAPI_PLATFORM_PRESTASHOP => 'Prestashop',
162                SHAREDAPI_PLATFORM_MAGENTO => 'Magento',
163                SHAREDAPI_PLATFORM_MEDIAWIKI => 'Mediawiki',
164                SHAREDAPI_PLATFORM_DOKUWIKI => 'DokuWiki'
165            );
166        }
167
168        return $platform ? $platforms[$platform] : $platforms;
169    }
170
171    function sharedapi_get_platforms_ids() {
172        static $platforms;
173
174        if (!$platforms) {
175            $platforms = array(
176                SHAREDAPI_PLATFORM_UNKNOWN => 'unknown',
177                SHAREDAPI_PLATFORM_VBULLETIN => 'vbulletin',
178                SHAREDAPI_PLATFORM_INTERSPIRESHOPPINGCART => 'interspireshoppingcart',
179                SHAREDAPI_PLATFORM_MOODLE => 'moodle',
180                SHAREDAPI_PLATFORM_WORDPRESS => 'wordpress',
181                SHAREDAPI_PLATFORM_JOOMLA => 'joomla',
182                SHAREDAPI_PLATFORM_DRUPAL => 'drupal',
183                SHAREDAPI_PLATFORM_PRESTASHOP => 'prestashop',
184                SHAREDAPI_PLATFORM_MAGENTO => 'magento',
185                SHAREDAPI_PLATFORM_MEDIAWIKI => 'mediawiki',
186                SHAREDAPI_PLATFORM_DOKUWIKI => 'dokuwiki'
187            );
188        }
189
190        return $platforms;
191    }
192
193    function SHAREDAPI_NAME_DEFINITION($brand, $definition) {
194        return $brand . '_' . $definition;
195    }
196
197    /**
198     * GPC helpers.
199     **/
200    function sharedapi_extract_gpc_variable($source, $name, $default = '') {
201        $v = $default;
202
203        if (is_array($name)) {
204            $v = array();
205            foreach ($name as $n) {
206                if (isset($source[$n])) {
207                    $v[$n] = $source[$n];
208                }
209            }
210        } else {
211            if (isset($source[$name])) {
212                $v = $source[$name];
213            }
214        }
215
216        return $v;
217    }
218
219    function sharedapi_gpc_variable($name, $default = '', $r = 'g') {
220        $v = $default;
221
222        switch ($r) {
223            case 'g':
224                $v = sharedapi_extract_gpc_variable($_GET, $name, $default);
225                break;
226            case 'p':
227                $v = sharedapi_extract_gpc_variable($_POST, $name, $default);
228                break;
229            case 'c':
230                $v = sharedapi_extract_gpc_variable($_COOKIE, $name, $default);
231                break;
232            case 's':
233                $v = sharedapi_extract_gpc_variable($_SERVER, $name, $default);
234                break;
235        }
236
237        return $v;
238    }
239
240    /**
241     * Trying to extract destination from the following sources in a certain order.
242     * Check in url(destination)
243     * Check in header(referer)
244     * Check in session
245     * */
246    function sharedapi_capture_gpc_variable($name, $gname, $event, $r = 'r', $reset = false) {
247        $variable = '';
248
249        for ($i = 0; $i < strlen($r); $i++) {
250            $ch = $r[$i];
251            switch ($ch) {
252                case 'r':
253                    if (empty($variable) && isset($_SERVER['HTTP_REFERER'])) {
254                        $variable = $_SERVER['HTTP_REFERER'];
255                    }
256                    break;
257                case 's':
258                    if (empty($variable) && isset($_SESSION[$name])) {
259                        $variable = $_SESSION[$name];
260                    }
261                    break;
262                case 'c':
263                    if (empty($variable) && isset($_COOKIE[$name])) {
264                        $variable = sharedapi_gpc_variable($name, '', 'c');
265                    }
266                    break;
267                case 'g':
268                    if (empty($variable) && isset($_GET[$gname])) {
269                        $variable = sharedapi_gpc_variable($gname, '', 'g');
270                    }
271                    break;
272                case 'p':
273                    if (empty($variable) && isset($_GET[$gname])) {
274                        $variable = sharedapi_gpc_variable($gname, '', 'p');
275                    }
276                    break;
277            }
278        }
279
280        if ($reset) {
281            setcookie($name, $_SESSION[$name] = '', 0, '/');
282        }
283
284        if (strpos($variable, $event . ':') !== false) {
285            $variable = substr($variable, strlen($event . ':'));
286        } else /*if (SHAREDAPI_EVENT_UNKNOWN == $event)*/ {
287            if (preg_match('/^\d+:(.*)/', $variable, $matches)) {
288                $variable = $matches[1];
289            }
290        }
291
292        return $variable;
293    }
294
295    function sharedapi_get_destination($pid, $event, $r = 'r', $reset = false) {
296        return sharedapi_capture_gpc_variable(SHAREDAPI_NAME_DEFINITION($pid, SHAREDAPI_EVENT_FIELD_DESTINATION), SHAREDAPI_EVENT_FIELD_DESTINATION, $event, $r, $reset);
297    }
298
299    function sharedapi_get_final_destination($pid, $event) {
300        sharedapi_get_final_lid($pid, $event);
301        return sharedapi_capture_gpc_variable(SHAREDAPI_NAME_DEFINITION($pid, SHAREDAPI_EVENT_FIELD_DESTINATION), SHAREDAPI_EVENT_FIELD_DESTINATION, $event, 'sc', true);
302    }
303
304    function sharedapi_get_lid($pid, $event, $r = 'r', $reset = false) {
305        return sharedapi_capture_gpc_variable(SHAREDAPI_NAME_DEFINITION($pid, SHAREDAPI_EVENT_FIELD_LID), SHAREDAPI_EVENT_FIELD_LID, $event, $r, $reset);
306    }
307
308    function sharedapi_get_final_lid($pid, $event) {
309        return sharedapi_capture_gpc_variable(SHAREDAPI_NAME_DEFINITION($pid, SHAREDAPI_EVENT_FIELD_LID), SHAREDAPI_EVENT_FIELD_LID, $event, 'sc', true);
310    }
311
312    function sharedapi_capture_destination($pid, $event, $api_path) {
313        $expire = time() + 60 * 4; // expire in 4 minutes.
314
315        $destination = sharedapi_get_destination($pid, $event, 'gr');
316        if (!empty($destination) && strpos($destination, $api_path) === false) {
317            setcookie(SHAREDAPI_NAME_DEFINITION($pid, SHAREDAPI_EVENT_FIELD_DESTINATION), $_SESSION[SHAREDAPI_NAME_DEFINITION($pid, SHAREDAPI_EVENT_FIELD_DESTINATION)] = $event . ':' . $destination, $expire, '/');
318        }
319
320        $lid = sharedapi_get_lid($pid, $event, 'g');
321        if (!empty($lid)) {
322            setcookie(SHAREDAPI_NAME_DEFINITION($pid, SHAREDAPI_EVENT_FIELD_LID), $_SESSION[SHAREDAPI_NAME_DEFINITION($pid, SHAREDAPI_EVENT_FIELD_LID)] = $event . ':' . $lid, $expire, '/');
323        }
324    }
325
326    /**
327     * Encryption helpers.
328     **/
329    function sharedapi_encrypt($key, $data) {
330        $key = sharedapi_get_valid_key($key);
331        return trim(base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $data, MCRYPT_MODE_ECB, mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_ECB), MCRYPT_RAND))));
332    }
333
334    function sharedapi_decrypt($key, $data) {
335        $key = sharedapi_get_valid_key($key);
336        return trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, base64_decode($data), MCRYPT_MODE_ECB, mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_ECB), MCRYPT_RAND)));
337    }
338
339    function sharedapi_encode_data($key, $json) {
340        $data = json_encode($json);
341        return sharedapi_encrypt($key, $data);
342    }
343
344    function sharedapi_decode_data($key, $data) {
345        $data = sharedapi_decrypt($key, $data);
346        return json_decode($data, true);
347    }
348
349    /*
350     * The fuction returns key with proper length. Only 16, 24, 32 accepted since PHP 5.6 for MCRYPT_RIJNDAEL_128
351     * Invalid key and iv sizes are no longer accepted.
352     */
353    function sharedapi_get_valid_key($key) {
354        $accepted_length = array(16, 24, 32);
355
356        //1st case: key has valid length
357        if (in_array(strlen($key), $accepted_length)) {
358            return $key;
359        }
360
361        //2nd case: key length is less than MAX allowed
362        foreach ($accepted_length as $length) {
363            if (strlen($key) < $length) {
364                return str_pad($key, $length, "\0");
365            }
366        }
367
368        //3d case: key length is greater than MAX allowed
369        if (strlen($key) > end($accepted_length)) {
370            return substr($key, 0, end($accepted_length));
371        }
372    }
373
374    /**
375     * DATA helpers.
376     **/
377    function sharedapi_is_error_data_item($data) {
378        return is_array($data) && isset($data[SHAREDAPI_EVENT_FIELD_ERROR_MESSAGE]);
379    }
380
381    function sharedapi_data_handler($product, $version, $vbsso_version, $shared_key, $callback) {
382        $ret = null;
383
384        sharedapi_set_cookie_policy();
385
386        $json = sharedapi_accept_data($shared_key);
387        if (is_array($json) && isset($json[SHAREDAPI_EVENT_FIELD_EVENT])) {
388            if (array_key_exists($json[SHAREDAPI_EVENT_FIELD_EVENT], $callback) && function_exists($callback[$json[SHAREDAPI_EVENT_FIELD_EVENT]])) {
389                $ret = call_user_func($callback[$json[SHAREDAPI_EVENT_FIELD_EVENT]], $json);
390            }
391        } else {
392            $ret[SHAREDAPI_EVENT_FIELD_ERROR] = $json;
393        }
394
395        $ret = $ret && is_array($ret) ? $ret : null;
396
397        echo sharedapi_build_response($product, $version, $vbsso_version,
398            $ret && isset($ret[SHAREDAPI_EVENT_FIELD_DATA]) ? $ret[SHAREDAPI_EVENT_FIELD_DATA] : null,
399            $ret && isset($ret[SHAREDAPI_EVENT_FIELD_ERROR]) ? $ret[SHAREDAPI_EVENT_FIELD_ERROR] : null,
400            $shared_key);
401        exit;
402    }
403
404    function sharedapi_accept_data($key, $data = '', $is_response = false) {
405        //Removes UTF-8 Byte order mark (BOM)
406        if (substr($data, 0, 3) == pack('CCC', 239, 187, 191)) {
407            $data = substr($data, 3);
408        }
409
410        if (empty($data)) {
411            $data = isset($_REQUEST[SHAREDAPI_EVENT_FIELD_DATA]) ? $_REQUEST[SHAREDAPI_EVENT_FIELD_DATA] : '';
412        }
413
414        $json = array();
415        if (!empty($data)) {
416            $json = $is_response ? json_decode($data, true) : sharedapi_decode_data($key, $data);
417            $json = ($json) ? $json : SHAREDAPI_WRONG_API_KEY_MESSAGE;
418        }
419
420        if (is_array($json) && isset($json[SHAREDAPI_EVENT_FIELD_PRODUCT]) && isset($json[SHAREDAPI_EVENT_FIELD_DATA])) {
421            $json[SHAREDAPI_EVENT_FIELD_DATA] = sharedapi_decode_data($key, $json[SHAREDAPI_EVENT_FIELD_DATA]);
422        }
423
424//        return is_array($json) && (isset($json[SHAREDAPI_EVENT_FIELD_EVENT]) || isset($json[SHAREDAPI_EVENT_FIELD_PRODUCT]))
425//            ? $json : false;
426        return $json;
427    }
428
429    function sharedapi_build_data_item($key, $data) {
430        return array(SHAREDAPI_EVENT_FIELD_DATA => sharedapi_encode_data($key, $data));
431    }
432
433    function sharedapi_build_response($product, $version, $vbsso_version, $data = null, $error = null, $key = null) {
434        $response = array(
435            SHAREDAPI_EVENT_FIELD_PRODUCT => $product,
436            SHAREDAPI_EVENT_FIELD_VERSION => $version,
437            SHAREDAPI_EVENT_FIELD_PLUGIN_VERSION => $vbsso_version,
438        );
439
440        if ($error) {
441            $response[SHAREDAPI_EVENT_FIELD_ERROR] = $error;
442        }
443
444        if ($data) {
445            $data = json_encode($data);
446            if ($key) {
447                $data = sharedapi_encrypt($key, $data);
448            }
449
450            $response[SHAREDAPI_EVENT_FIELD_DATA] = $data;
451        }
452
453        if (defined('PHP_VERSION')) {
454            $response[SHAREDAPI_EVENT_FIELD_PHP_VERSION] = PHP_VERSION;
455        }
456        $response[SHAREDAPI_EVENT_FIELD_MEMORY_LIMIT] = ini_get('memory_limit');
457        if (defined('WP_MEMORY_LIMIT')) {
458            $response[SHAREDAPI_EVENT_FIELD_WP_MEMORY_LIMIT] = WP_MEMORY_LIMIT;
459        }
460
461
462        return json_encode($response);
463    }
464
465    function sharedapi_post($url, $fields, $username = '', $password = '', $timeout = 5, $connecttimeout = 5) {
466        $ch = curl_init();
467
468        curl_setopt($ch, CURLOPT_URL, $url);
469
470        if (!empty($username)) {
471            curl_setopt($ch, CURLOPT_USERPWD, "$username:$password");
472        }
473
474        curl_setopt($ch, CURLOPT_POST, 1);
475        curl_setopt($ch, CURLOPT_POSTFIELDS, $fields);
476        curl_setopt($ch, CURLOPT_HTTPHEADER, array('User-Agent: vBSSO'));
477        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
478        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
479        curl_setopt($ch, CURLOPT_HEADER, 0);
480        curl_setopt($ch, CURLOPT_TIMEOUT, intval($timeout));
481        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, intval($connecttimeout));
482
483        $data = curl_exec($ch);
484
485        $code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
486        $error_string = ($code != 200) ? curl_error($ch) : '';
487        curl_close($ch);
488
489        return array('code' => $code, 'response' => $data, 'error_string' => $error_string);
490    }
491
492    function sharedapi_http_status_error($status) {
493        $status = intval($status);
494        return $status >= 400;
495    }
496
497    function sharedapi_log($data, $file = 'default', $path = null) {
498        if (!$path) {
499            $path = dirname(__FILE__);
500        }
501
502        if ($file == 'default') {
503            $file = 'sharedapi.log';
504        }
505
506        $handle = fopen($path . '/' . $file, "a+");
507
508        $output = '';
509        if (is_array($data)) {
510            foreach ($data as $key => $value) {
511                $output .= $key . '=' . $value . '&';
512            }
513        } else if (is_bool($data)) {
514            $output = $data ? 'true' : 'false';
515        } else {
516            $output = $data;
517        }
518
519        $datetime = date('Y-m-d_H-i-s', time());
520        fwrite($handle, $datetime . ': ' . $output . "\n");
521        fclose($handle);
522    }
523
524    /**
525     * URL helpers.
526     **/
527    function sharedapi_url_add_destination($url, $capture_referrer = true, $default = '', $lid = '', $query = '') {
528        if (!empty($url)) {
529            $referrer = '';
530
531            if ($capture_referrer === true || $capture_referrer > 0) {
532                $referrer = sharedapi_gpc_variable('HTTP_REFERER', '', 's');
533            } else if ($capture_referrer !== false && $capture_referrer !== 0) {
534                $referrer = sharedapi_get_server_url();
535            }
536
537            if (empty($referrer) && $default && !empty($default)) {
538                $referrer = $default;
539            }
540
541            if (empty($referrer)) {
542                $referrer = sharedapi_get_server_url();
543            }
544
545            if (!empty($referrer)) {
546                $url = sharedapi_url_add_query($url, SHAREDAPI_EVENT_FIELD_DESTINATION . '=' . urlencode($referrer));
547
548                if ($lid && !empty($lid)) {
549                    $url = sharedapi_url_add_query($url, SHAREDAPI_EVENT_FIELD_LID . '=' . $lid);
550                }
551
552                if ($query && !empty($query) && is_string($query)) {
553                    $url = sharedapi_url_add_query($url, $query);
554                }
555            }
556        }
557
558        return $url;
559    }
560
561    function sharedapi_url_get_referrer() {
562        return sharedapi_gpc_variable('HTTP_REFERER', '', 's');
563    }
564
565    function sharedapi_url_add_lid($url, $lid = '', $query = '') {
566        if (!empty($url)) {
567            if ($lid && !empty($lid)) {
568                $url = sharedapi_url_add_query($url, SHAREDAPI_EVENT_FIELD_LID . '=' . $lid);
569            }
570
571            if ($query && !empty($query) && is_string($query)) {
572                $url = sharedapi_url_add_query($url, $query);
573            }
574        }
575
576        return $url;
577    }
578
579    function sharedapi_url_add_query($url, $query) {
580        if (!empty($url)) {
581            if (strpos($url, '?') === false) {
582                $url .= '?';
583            } else {
584                $url .= '&';
585            }
586        }
587
588        return $url . $query;
589    }
590
591    function sharedapi_url_redirect($url) {
592        if (!empty($url)) {
593            header('Location: ' . $url);
594        }
595    }
596
597    function sharedapi_get_server_url($uri = true) {
598        if ($_SERVER['SERVER_PORT'] == '80') {
599            $url = 'http://' . $_SERVER['SERVER_NAME'] . '';
600        } else if (isset($_SERVER['HTTPS'])) {
601            $url = 'https://' . $_SERVER['SERVER_NAME'] . '';
602        } else {
603            $url = 'http://' . $_SERVER['SERVER_NAME'] . ':' . $_SERVER['SERVER_PORT'] . '';
604        }
605
606        if ($uri === true) {
607            $url .= $_SERVER['REQUEST_URI'];
608        } else if (is_string($uri)) {
609            $url .= $uri;
610        }
611
612        return $url;
613    }
614
615    //rsf is register_shutdown_function. Some hosting providers disable it for security reasons.
616    function sharedapi_is_rsf_disabled() {
617        return in_array('register_shutdown_function', explode(',', ini_get('disable_functions')));
618    }
619
620    function sharedapi_get_primary_domain($url) {
621        if (empty($url)) {
622            return '';
623        }
624
625        $url_host = parse_url(strtolower($url), PHP_URL_HOST);
626        if (strpos('www.', $url_host) === 0) {
627            $url_host = substr($url_host, 4);
628        }
629
630        $dots_count = substr_count('.', $url_host);
631        if ($dots_count < 2 OR ($dots_count == 4 && ip2long($url_host))) {
632            return $url_host;
633        }
634
635        $domainArray = explode('.', $url_host);
636        $topLevelDomainArray = array(array_pop($domainArray), array_pop($domainArray));
637        krsort($topLevelDomainArray);
638        return strtolower(join('.', $topLevelDomainArray));
639    }
640
641    function sharedapi_set_cookie_policy(){
642        $referer_primary_domain = sharedapi_get_primary_domain(sharedapi_gpc_variable('HTTP_REFERER', '', 's'));
643        $server_primary_domain = sharedapi_get_primary_domain(sharedapi_get_server_url());
644
645        if ($referer_primary_domain !== $server_primary_domain) {
646            header("p3p:CP=\"NOI ADM DEV COM NAV OUR STP\"");
647        }
648    }
649}