使用CakePhp Shopify私有应用插件在服务器上获取错误

时间:2015-05-19 18:50:13

标签: php cakephp curl shopify

当我将Cakephp代码上传到Site5服务器时,我得到了这个奇怪的错误。我试图通过私人应用程序插件连接到shopify商店。我不确定,但我认为问题可能是服务器Site5限制进行卷曲调用。我从公共git中心页面抓取代码并且没有对其进行任何更改。当我通过我的localhost中的插件连接它工作正常,但当我尝试连接在服务器上执行相同操作时,它将引发错误。私有应用程序的代码是下一个:

class PrivateAPI {
    const _LOGIN_URL = 'auth/login';
    const _REPORT_CENTER = 'https://reportcenter.shopify.com/';

    const _COOKIE_STORE = '/tmp/shopify_cookie.txt';
    const _USER_AGENT = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_3) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.57 Safari/537.17';

    protected $ch = null,
          $ci = null;
    private $inputs = false,
        $username = false,
        $password = false,
        $store = false,
        $_token = false,
        $_dashboardToken = false;

    public function __construct($user, $pass, $store) {
        if (!preg_match('/\:\/\//', $store)) {
            $store = 'https://' . $store;
        }
        if (!filter_var($store, FILTER_VALIDATE_URL)) {
            throw new \Exception('Invalid store URL');
        }
        $this->store = $store . (substr($store, -1) == '/' ? '' : '/');
        $this->username = $user;
        $this->password = $pass;
    }
    public function __destruct() {
        if (is_resource($this->ch)) {
            curl_close($this->ch);
        }
    }
    public function isLoggedIn() {
        return !is_array($this->getFields());
    }
    public function dashboardToken() {
        return $this->_dashboardToken;
    }
    public function login() {
        $fields = $this->inputs ?: $this->getFields();
        $fields['login']  = $this->username;
        $fields['password'] = $this->password;
        if (isset($fields['_method'])) {
            unset($fields['_method']);
        }
        $url = $this->store . self::_LOGIN_URL;
        $this->ch = curl_init($url);
        $this->setOpts(array(
            CURLOPT_POST       => true,
            CURLOPT_POSTFIELDS => http_build_query($fields),
            CURLOPT_HTTPHEADER => array('Shopify-Auth-Mechanisms:password')
        ));
        $data = curl_exec($this->ch);
        $http_code = curl_getinfo($this->ch, CURLINFO_HTTP_CODE);
        return ($http_code == 200 && $this->setToken($data));
    }
    public function doRequest($method, $function, $parameters) {
        $this->ch = curl_init();        
        $reportCenter = false;
        if (isset($parameters['reportcenter'])) {
            $url = self::_REPORT_CENTER . $function;
            $reportCenter = true;
            $parameters['callback'] = 'fake_function';
            $parameters['token'] = $this->dashboardToken();
            unset($parameters['reportcenter']);
        } else {
            $url = (!filter_var($function, FILTER_VALIDATE_URL) ? $this->store : '') . $function;
        }
        switch ($method) {
            case 'POST':
                $this->setOpts(array(
                    CURLOPT_POST => true,
                    CURLOPT_POSTFIELDS => json_encode($parameters),
                    CURLOPT_URL => $url,
                    CURLOPT_HTTPHEADER => array(
                        'X-Shopify-Api-Features: pagination-headers',
                        'X-CSRF-Token: ' . $this->_token,
                        'X-Requested-With: XMLHttpRequest',
                        'Content-Type: application/json',
                        'Accept: application/json'
                    )
                ));
                break;
            case 'GET':
            default:
                $this->setOpts(array(
                    CURLOPT_HTTPGET => true,
                    CURLOPT_URL => $url . (count($parameters) ? '?' . urldecode(http_build_query($parameters)) : '')
                ));
        }
        $response = curl_exec($this->ch);
        if (curl_errno($this->ch)) {
            throw new \Exception('Shopify Private API exception: ' . curl_error($this->ch));
        }
        if ($reportCenter) {
            if (strpos($response, 'fake_function') !== FALSE) {
                $response = substr($response, strpos($response, '{'));
                $response = substr($response, 0, -2);
            }
        }
        $data = json_decode($response);
        return is_object($data) ? $data : $response;
    }
    public function setToken($input) {
        $data = filter_var($input, FILTER_VALIDATE_URL) ? $this->initGetData($input) : $input;
        if (preg_match('/<meta content="(.*)" name="csrf-token" \/>/i', $data, $token)) {
            $this->_token = $token[1];
            if (preg_match('/Shopify.set\(\'controllers.dashboard.token\', "(.*)"\)/i', $data, $dashboardToken)) {
                $this->_dashboardToken = $dashboardToken[1];
            }
            return true;
        }
        throw new \Exception('Failed to set token');
    }
    private function initGetData($url, $opts = array()) {
        if (!filter_var($url, FILTER_VALIDATE_URL)) {
            throw new \Exception('Invalid URL: ' . $url);
        }
        $this->ch = curl_init($url);
        $this->setOpts($opts);
        if (($http_code = curl_getinfo($this->ch, CURLINFO_HTTP_CODE)) > 300) {
            throw new \Exception('Failed to fetch ' . $url . ' (' . $http_code . ')');
        }
        $data = curl_exec($this->ch);
        return $data;
    }
    private function setOpts($extra = array()) { 
        $default = array(
            CURLOPT_USERAGENT => self::_USER_AGENT,
            CURLOPT_COOKIEJAR => self::_COOKIE_STORE,
            CURLOPT_COOKIEFILE => self::_COOKIE_STORE,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_FOLLOWLOCATION => true
        );
        $options = $default + array_filter($extra, function($v) {
            return !is_null($v);
        });
        curl_setopt_array($this->ch, $options);
    }
    private function getFields($data = false) {
        $data = $data ?: $this->initGetData($this->store);
        if (preg_match('/(<form.*?.*?<\/form>)/is', $data, $matches)) {
            $this->inputs = $this->getInputs($matches[1]);
        }
        return is_array($this->inputs) ? $this->inputs : false;
    }
    private function getInputs($form, $inputs = array()) {
        if (!($els = preg_match_all('/(<input[^>]+>)/is', $form, $matches))) {
            return false;
        }
        for ($i = 0; $i < $els; $i++) {
            $el = preg_replace('/\s{2,}/', ' ', $matches[1][$i]);
            if (preg_match('/name=(?:["\'])?([^"\'\s]*)/i', $el, $name) 
             && preg_match('/value=(?:["\'])?([^"\'\s]*)/i', $el, $value)) {
                $inputs[$name[1]] = $value[1];
            }
        }
        return $inputs;
    }
}

我得到的错误真的很长,但最后出现的几个错误是下一个。

    |Exception Object
(
    [message:protected] => Failed to set token
    [string:Exception:private] => 
    [code:protected] => 0
    [file:protected] => /home/bebe2goc/public_html/facturas.bebe2go.com/app/Controller/SamplesController.php
    [line:protected] => 215
    [trace:Exception:private] => Array
        (
            [0] => Array
                (
                    [file] => /home/bebe2goc/public_html/facturas.bebe2go.com/app/Controller/SamplesController.php
                    [line] => 157
                    [function] => setToken
                    [class] => PrivateAPI
                    [type] => ->
                    [args] => Array
                        (
                            [0] => 

显然,由于某种原因,与shopify的连接无法完成。我想知道问题是否在我的代码中,或者服务器是否可能限制插件使用的curl调用。 setToken()方法出错。任何人都可以至少指出我正确的方向:P我似乎无法找到这个问题。

更新: 显然,对shopify的呼吁很好。我使用curl_getinfo来查看它在exec之后返回的内容,这是返回:

    Array ( 
[url] => https://bebe2go.myshopify.com/admin/auth/login 
[content_type] => text/html; charset=utf-8 
[http_code] => 200 
[header_size] => 2774 
[request_size] => 611 
[filetime] => -1 
[ssl_verify_result] => 0 
[redirect_count] => 0 
[total_time] => 0.253468 
[namelookup_time] => 3.8E-5 
[connect_time] => 0.040116 
[pretransfer_time] => 0.138109 
[size_upload] => 210 
[size_download] => 21475 
[speed_download] => 84724 
[speed_upload] => 828 
[download_content_length] => -1 
[upload_content_length] => 210 
[starttransfer_time] => 0.253146 
[redirect_time] => 0 
[certinfo] => Array ( ) 
[primary_ip] => 23.227.38.68 
[primary_port] => 443 
[local_ip] => 174.120.252.82 
[local_port] => 33288 
[redirect_url] => )

由于某种原因登录功能在服务器上不起作用,它返回密码或用户名不正确。但是在我的localhost中,它工作得很好。 D:有什么想法吗?

0 个答案:

没有答案