-1

I'm a .NET developer, and (confession time) I've never used PHP for anything ever. I find myself needing to convert some PHP to test an API. I've converted much of it, bringing my error count from over 400 to 69, however, the further I go, the more convinced I am that it's just going to be broken.

So, I've decided to throw myself at the mercy of my fellow devs and ask for some help.

What I'm converting is this, a wrapper class that calls the API and returns XML or JSON.

<?php

class APIv2 {
protected $accessToken;
protected $baseURL;
protected $functions = array();
protected $format = 'json';

public function __construct($accountid, $key, $baseURL = 'https://www.eiseverywhere.com')
{
    $this->baseURL = rtrim($baseURL,'/').'/api/v2/';
    $request = $this->rawRequest($this->baseURL.'global/authorize.json',
                                  array('accountid' => $accountid,'key' => $key));
    $response = json_decode($request['response'], true);
    if (empty($response['accesstoken'])) {
        throw new \Exception(__CLASS__.': Bad url or parameters given. '.print_r($response,1));
    }
    $this->accessToken = $response['accesstoken'];
    $response = $this->rawRequest($this->baseURL.'global/listAvailableFunctions.json',
                                   array('accesstoken' => $this->accessToken));
    $functions = json_decode($response['response'], true);
    foreach ($functions as $sectionName=>$section) {
        foreach ($section as $methodName=>$functionArray) {
            foreach ($functionArray as $functionName) {
                $this->functions[$functionName] = array('method'=>$methodName, 'section'=>$sectionName);
            }
        }
    }
}

public function setFormat($format)
{
    $validFormats = array('xml','json');
    if (! in_array($format, $validFormats)) {
        $message = __CLASS__.": Invalid format: $format. Not one of the following:";
        foreach ($validFormats as $value) { 
            $message .= ' '.$value;
        }
        throw new \Exception($message);
    }
    $this->format = $format;
}

public function request($request, $parameters = array())
{
    $parameters['accesstoken'] = $this->accessToken;
    if (! array_key_exists($request, $this->functions)) {
        return array(
            'response' => '',
            'info' => $this->functions,
            'errors' => "Unknown function: $request",
        );
    }
    $function = $this->functions[$request];
    $url = $this->baseURL.$function['section'].'/'.$request.'.'.$this->format;
    return $this->rawRequest($url, $parameters, $function['method']);
}

public static function rawRequest($url, $parameters = array(), $method = 'get')
{
    $response = 'Unable to use etouches API, please enable cURL functionality (http://php.net/curl) for your server and try again';
    $info = '';
    $errors = '';
    $method = strtolower($method);
    if (function_exists('curl_init')) {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
        $paramString = http_build_query($parameters);
        curl_setopt($ch, CURLOPT_URL, $url . (!empty($paramString)?'?'.$paramString:''));
        if ($method == 'post') {
            foreach ($parameters as &$value) {
                if (is_array($value)) {
                    $value = http_build_query($value);
                }
            }
            curl_setopt($ch, CURLOPT_POSTFIELDS, $parameters);
        } else if ($method == 'put') {
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Length: ' . strlen($paramString)));
            curl_setopt($ch, CURLOPT_POSTFIELDS, $paramString);
        }
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
        curl_setopt($ch, CURLOPT_TIMEOUT, 30);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

        $response = curl_exec($ch);
        $info = curl_getinfo($ch);
        $errors = curl_error($ch);

        curl_close($ch);
    }
    return array(
        'response' => $response,
        'info' => $info,
        'errors' => $errors
        );
}

}

function dump($h1, $var)
{
    echo "<h1>$h1</h1>";
    var_dump($var);
}

$api = new etouchesAPIv2($yourAccountId, $yourAPIKey);

$response = $api->request($call = 'listFolders');
$folders = json_decode($response['response'], true);
dump($call, $folders);

$parameters = array('name' => "New event created by etouches API",
                    'modules' => array('eHome','eMobile','eSelect','eReg','eBooth','eConnect','eSocial','eSeating'),);
if (count($folders)) {
    $parameters['folder'] = $folders[0]['folderid'];
}
$api->setFormat('xml');
$response = $api->request($call = 'createEvent', $parameters);
$newEvent = new SimpleXMLElement($response['response']);
dump($call, $newEvent);

$api->setFormat('json');
$response = $api->request($call = 'listEvents');
$events = json_decode($response['response'], true);
dump($call, $events);

$api->setFormat('xml');
$response = $api->request($call = 'listSpeakers', array('eventid' => $events[0]['eventid']));
$speakers = new SimpleXMLElement($response['response']);
dump($call, $speakers);

$response = $api->request($call = 'getEvent', array('eventid' => $events[0]['eventid']));
$event = new SimpleXMLElement($response['response']);
dump($call, $event);

$response = $api->request($call = 'cloneEvent', array('eventid' => $events[0]['eventid'],'name'=>"Event cloned via etouches API"));
$clonedEvent = new SimpleXMLElement($response['response']);
dump($call, $clonedEvent);

Where I'm having the most trouble, is the PHP method calls. I've been looking up c# equivalents to the best of my ability, but the final result just isn't pretty.

So, could you please refer me to some 'PHP to C#' tools or conversion references, or help me out with the CURLs, __CLASS__, and other PHP specifics?

I should note, I've looked into Phalanger, and would prefer not to use it if possible. I also haven't found any comprehensive PHP to C# conversion tools or guides as of yet.

Thank you in advance!

EDIT:

As requested, here's my attempt at conversion (I know, it's messy, I'm not proud of it. Not fully converted, in flux.)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Script.Serialization;
using System.Net;
using System.Diagnostics;
using System.Xml;

namespace Test {
    public partial class _Default : System.Web.UI.Page {
        protected static string accessToken;
        protected static string baseURL;
        protected Dictionary<string, string> functions = new Dictionary<string,string>();
        protected string format = "json";

    XmlDocument xml = new XmlDocument();

    protected void Page_Load(object sender, EventArgs e) {
        string accountid = (ACCOUNTID);
        string key = (KEY);
        string baseURL = "https://www.eiseverywhere.com";

        baseURL = baseURL.Remove(baseURL.LastIndexOf("/"),1).TrimEnd() + "/api/v2/";//rtrim(baseURL,"/")+"/api/v2/";

        Debug.WriteLine("baseURL: " + baseURL);

        string request = RawRequest(baseURL+"global/authorize.json",
                                        new string[]{accountid,key});
        //string response = json_decode(request["response"], true);
        var data = new Dictionary<string, string>(); //REF:http://stackoverflow.com/questions/7699972/how-to-decode-a-json-string-using-c
        //data.Add("foo", "baa");
        JavaScriptSerializer ser = new JavaScriptSerializer();
        var JSONString = ser.Serialize(data);
        var JSONObj = ser.Deserialize<Dictionary<string, string>>(JSONString);

        string response = JSONObj["response"];

        //if (empty(response["accesstoken"])) {
        //    throw new Exception(__CLASS__+": Bad url or parameters given. "+print_r(response,1));
        //}
        accessToken = JSONObj["accesstoken"]; //response["accesstoken"];
        response = RawRequest(baseURL+"global/listAvailableFunctions.json", new string[]{accessToken});
        functions = JSONObj;//json_decode(response["response"], true);
        foreach (var section in functions) {
            foreach (var functionArray in section) {
                foreach (var functionName in functionArray) {
                    this.functions[functionName] = new List<string>{methodName, sectionName};
                }
            }
        }


        //_Default api = new _Default();

        string call = "listFolders";

        response = Request(call);
        string folders = json_decode(response["response"], true);
        //Dump(call, folders);

        string[] parameters = new string[]{"New event created by etouches API","eHome","eMobile","eSelect","eReg","eBooth","eConnect","eSocial","eSeating"};
        if (count(folders)) {
            parameters["folder"] = folders[0]["folderid"];
        }

        xml.LoadXml(SomeXMLString);
        string itemID = xml.GetElementsByTagName("itemID")(0).InnerText;

        call="createEvent";
        this.SetFormat("xml");
        response = Request(call, parameters);
        string newEvent = new SimpleXMLElement(response["response"]);
        //Dump(call, newEvent);

        this.SetFormat("json");
        response = Request(call = "listEvents");
        string events = json_decode(response["response"], true);
        //Dump(call, events);

        this.SetFormat("xml");
        response = Request(call = "listSpeakers", new string[]{events[0]["eventid"]});
        string speakers = new SimpleXMLElement(response["response"]);
        //Dump(call, speakers);

        response = Request(call = "getEvent", new string[]{events[0]["eventid"]});
        string eventt = new SimpleXMLElement(response["response"]);
        //Dump(call, eventt);

        response = Request(call = "cloneEvent", new string[]{events[0]["eventid"],"Event cloned via etouches API"});
        string clonedEvent = new SimpleXMLElement(response["response"]);
        //Dump(call, clonedEvent);

    }

    public void SetFormat(string format)
    {
        string[] validFormats = new string[]{"xml","json"};
        if (!validFormats.Contains(format)) {
            string message = __CLASS__+": Invalid format: " + format + " Not one of the following:";
            foreach (var value in validFormats) { 
                message = " "+value;
            }
            throw new Exception(message);
        }
        this.format = format;
    }

    public static string Request(string request, string[] parameters)
    {
        parameters["accesstoken"] = accessToken;
        if (! array_key_exists(request, functions)) {
            return new string[]{
                "",
                functions,
                "Unknown function: request",
        };
        }
        string[] function = functions[request];
        string url = baseURL.function["section"]+"/"+request+"+"+this.format;
        return RawRequest(url, parameters, function["method"]);
    }

    public static string RawRequest(string url, string[] parameters)
    {
        string[] result;
        string method = "get";
        string response = "Unable to use etouches API, please enable cURL functionality (http://php.net/curl) for your server and try again";
        string info = "";
        string errors = "";
        method = method.ToLower();

        //string ch = curl_init();
        HttpWebRequest ch = (HttpWebRequest)WebRequest.Create(this.Request.Url.Scheme);
        curl_setopt(ch, CURLOPT_CUSTOMREQUEST, method);
        string paramString = http_build_query(parameters);
        curl_setopt(ch, CURLOPT_URL, url . (!empty(paramString)?"?"+paramString:""));
        if (method == "post") {
            foreach (var value in parameters) {
                if (is_array(value)) {
                    value = http_build_query(value);
                }
            }
            curl_setopt(ch, CURLOPT_POSTFIELDS, parameters);
        } else if (method == "put") {
            curl_setopt(ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt(ch, CURLOPT_HTTPHEADER, new string[]{"Content-Length: " , paramString.Length});
            curl_setopt(ch, CURLOPT_POSTFIELDS, paramString);
        }
        curl_setopt(ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt(ch, CURLOPT_CONNECTTIMEOUT, 10);
        curl_setopt(ch, CURLOPT_TIMEOUT, 30);
        curl_setopt(ch, CURLOPT_SSL_VERIFYPEER, false);

        response = curl_exec(ch);
        info = curl_getinfo(ch);
        errors = curl_error(ch);

        curl_close(ch);


        result = new string[]{response,info,errors};

        return result;
    }

    //private void Dump(string h1, string var)
    //{
    //    Response.Write("<h1>" + h1 + "</h1>");
    //    var_dump(var);
    //}
}//class
sabastienfyrre
  • 467
  • 1
  • 4
  • 14
  • 3
    At least post what you have done so far. – Cyral Jul 03 '15 at 19:19
  • 2
    The PHP code looks a bit outdated. Dunno if that helps you, but most likely it could not only be compressed in PHP but also in .NET. Perhaps it's easier you understand only broadly what it does and then write the functionality from scratch in .NET. – hakre Jul 03 '15 at 20:17
  • Thanks hakre, honestly, I'm definitely leaning that way. – sabastienfyrre Jul 03 '15 at 20:22
  • 1
    Code dumps are no fun. If you have specific questions about what the .NET/C# equivalent to certain PHP functionality is, you could probably get answers to those fairly quickly, even if you have a lot of them. Opening up my editor and tediously converting a long code dump isn't something I feel like doing for fun though (although I can only speak for myself). – Asad Saeeduddin Jul 03 '15 at 20:48
  • What does the XML look like? Or is it Jason? Can you fetch the XML from website and then parse just XML? – jdweng Jul 03 '15 at 20:50
  • Thank you Asad, I think I'll do that – sabastienfyrre Jul 03 '15 at 20:51
  • Hi jdweng, I'll be looking to get XML, however, I haven't seen what the response will look like. It's for an event registration API, so I'm expecting it to be laid out with an event ID, then attendee data below. I may try running the PHP version to get an idea of what is to come. – sabastienfyrre Jul 03 '15 at 20:57
  • 1
    Add me to the list of people who think you should focus on first understanding what the PHP program is doing, in detail, and then write a .NET program that performs the same behaviour. You'll get better results doing that than trying to translate statement-by-statement. – Dan J Jul 03 '15 at 21:49
  • This is not a particularly good question, since it is unlikely to help others in the future, but I'm still considering an upvote, for never having used php. – Nameless One Jul 03 '15 at 22:32
  • I am going with reproducing the functionality rather than straight translation. Thanks everyone. Something I was hoping to see for those needing help in the future is referral to a tool or a conversion guide. I'm editing my question to include resources I've found to be helpful. But if anyone has some additions they could suggest, please post them here. – sabastienfyrre Jul 06 '15 at 12:04
  • @sabastienfyrre Are you still looking for help on CURLs and \_\_CLASS__ ? – nl-x Jul 07 '15 at 15:17
  • nl-x I certainly wouldn't turn it down. I'd love a better understanding of how those translate to C#. – sabastienfyrre Jul 07 '15 at 15:20
  • 1
    @sabastienfyrre IMHO \_\_CLASS__ in PHP is just the same as `this.GetType().Name` in C# or even `this.className` in some cases. And for CURL in PHP I suggest you make use of HttpWebRequest in C# – nl-x Jul 07 '15 at 15:24
  • Thanks, I'll explore this further. – sabastienfyrre Jul 07 '15 at 15:32

1 Answers1

1

I've created a new Question and Answer called "How to Convert PHP to .NET For Beginners". It's the result of all my research into the topic and explains what worked for me. I hope that it will help you find a fast and simple resolution.

Community
  • 1
  • 1
sabastienfyrre
  • 467
  • 1
  • 4
  • 14