Skip to content

Commit

Permalink
Version 0.8.7
Browse files Browse the repository at this point in the history
* v0.7.8 update
  1. Supporting Wordpress REST API with OAuth 1.0a.
  2. Supporting Wordpress REST API with JWT Authentication.
  3. Fix few minor issues.
  • Loading branch information
XiaoFaye committed Jul 30, 2019
1 parent 80bae31 commit 8b8f25c
Show file tree
Hide file tree
Showing 25 changed files with 2,096 additions and 97 deletions.
1 change: 1 addition & 0 deletions Base/BaseObject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;
using WooCommerce.NET.WordPress.v2;

namespace WooCommerceNET.Base
{
Expand Down
4 changes: 4 additions & 0 deletions Changes.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@

Version History
-------------------
* v0.7.8 update
1. Supporting Wordpress REST API with OAuth 1.0a.
2. Supporting Wordpress REST API with JWT Authentication.
3. Fix few minor issues.
* v0.7.7 update
1. Supporting Wordpress REST API with OAuth 1.0a.
2. Supporting WISDM Customer Specific Pricing REST API.
Expand Down
108 changes: 49 additions & 59 deletions Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,27 @@
A Brief Intro
-------------------

WooCommerce.NET is a .NET library for calling WooCommerce REST API in any .NET applications.
WooCommerce.NET is a .NET library for calling WooCommerce/WordPress REST API with OAuth/JWT in .NET applications.

* [Visit WooCommerce](http://www.woothemes.com/woocommerce/)
* [Visit WooCommerce REST API DOCS](https://woocommerce.github.io/woocommerce-rest-api-docs/)
[Visit WooCommerce](http://www.woothemes.com/woocommerce/)
[Visit WooCommerce REST API DOCS](https://woocommerce.github.io/woocommerce-rest-api-docs/)
[Visit WordPress REST API DOCS](https://developer.wordpress.org/rest-api/)

[![NuGet](https://buildstats.info/nuget/WooCommerceNET)](http://www.nuget.org/packages/WooCommerceNET)

If this project has been helpful for you and you want to support it, please consider [Buying me a coffee](https://www.buymeacoffee.com/YU0SqVyrR):coffee:

Usage (WooCommerce REST API)
-------------------
* [How to use JSON.NET in WooCommerce.NET](https://github.com/XiaoFaye/WooCommerce.NET/wiki/How-to-use-JSON.NET-in-WooCommerce.NET)
* [Specifiy user agent when making requests to WooCommerce](https://github.com/XiaoFaye/WooCommerce.NET/wiki/Specifiy-user-agent-when-making-requests-to-WooCommerce)
* [How to use webRequestFilter and webResponseFilter in WooCommerce.NET](https://github.com/XiaoFaye/WooCommerce.NET/wiki/How-to-use-webRequestFilter-and-webResponseFilter-in-WooCommerce.NET)
* [Use X HTTP MethodOverride header for DELETE PUT](https://github.com/XiaoFaye/WooCommerce.NET/wiki/Use-X-HTTP-MethodOverride-header-for-DELETE-PUT)
* [Handle different types of Meta Value in WC Restful API V2](https://github.com/XiaoFaye/WooCommerce.NET/wiki/Handle-different-types-of-Meta-Value-in-WC-Restful-API-V2)

Usage
-------------------

<details open>
<summary>Click to expand/collapse details...</summary>
```cs
using WooCommerceNET.WooCommerce.v3;
using WooCommerceNET.WooCommerce.v3.Extension;
Expand Down Expand Up @@ -83,75 +88,60 @@ cb.delete = delete;
var c = await wc.Customer.UpdateRange(cb);

```
</details>



Usage (Legacy & V1 API)
Usage (WordPress REST API - OAuth/JWT Authentication)
-------------------
* [How to setup Restful API via OAuth 1.0a in WordPress](https://github.com/XiaoFaye/WooCommerce.NET/wiki/How-to-setup-Restful-API-via-OAuth-1.0a-in-WordPress)
* [How to setup Restful API via JWT Authentication in WordPress](https://github.com/XiaoFaye/WooCommerce.NET/wiki/How-to-setup-Restful-API-via-JWT-Authentication-in-WordPress)

<details>
<summary>Click to expand/collapse details...</summary>

```cs
//Legacy way of calling WooCommerce REST API
//using WooCommerceNET.WooCommerce.Legacy;
//
//RestAPI rest = new RestAPI("http://www.yourstore.co.nz/wc-api/v3/", "<WooCommerce Key>", "<WooCommerce Secret");
//WooCommerceNET.WooCommerce.Legacy.WCObject wc = new WooCommerceNET.WooCommerce.Legacy.WCObject(rest);

using WooCommerceNET.WooCommerce.v1;
//using OAuth
RestAPI rest = new RestAPI("http://www.yourstore.co.nz/wp-json/wp/v2/", "<Client_Key>", "<Client_Secret>");
rest.oauth_token = "<OAuth_Token>";
rest.oauth_token_secret = "<OAuth_Token_Secret>";

RestAPI rest = new RestAPI("http://www.yourstore.co.nz/wp-json/wc/v1/", "<WooCommerce Key>", "<WooCommerce Secret");
WCObject wc = new WCObject(rest);
//using JWT
RestAPI rest = new RestAPI("http://www.yourstore.co.nz/wp-json/jwt-auth/v1/token", "<UserName>", "<Password>");

//Get all products
var products = await wc.GetProducts();
WPObject wp = new WPObject(rest);

//Add new product
Product p = new Product()
{
name = "test product 8",
title = "test product 8",
description = "test product 8",
price = 8.0M
};
await wc.PostProduct(p);
//Get all posts
var posts = await wp.Post.GetAll();

//Update products
await wc.UpdateProduct(128, new Product { name = "test 9" });
//Add a post
var p = new Posts()
{
title = "abc",
content = "<h1>abc</h1>"
};

//Delete product
await wc.DeleteProduct(128);
await wp.Post.Add(p);

//Use parameters
var p = await wc.GetProducts(new Dictionary<string, string>() {
{ "include", "10, 11, 12, 13, 14, 15" },
{ "per_page", "15" } });
//Update post with new values
await wp.Post.Update(123, new { title = "new post" });

//Delete a post
await wp.Post.Delete(123);

//Batch update
CustomerBatch cb = new CustomerBatch();

CustomerList create = new CustomerList();
create.Add(new Customer()
{
first_name = "first",
last_name = "last",
email = "[email protected]",
username = "firstnlast",
password = "12345"
});
//Upload an image
await wp.Media.Add("imagename.jpg", @"C:\path\to\image\file.jpg");

CustomerList update = new CustomerList();
update.Add(new Customer()
//Create a new user
await wp.Users.Add(new Users()
{
id = 4,
last_name = "xu2"
first_name = "test",
last_name = "test",
name = "test",
username = "test123",
email = "[email protected]",
password = "test@12345"
});

List<int> delete = new List<int>() { 8 };

cb.create = create;
cb.update = update;
cb.delete = delete;

var c = await wc.UpdateCustomers(cb);

```
</details>
88 changes: 79 additions & 9 deletions RestAPI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Reflection;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
Expand Down Expand Up @@ -37,6 +38,8 @@ public class RestAPI
/// </summary>
public string oauth_token_secret { get; set; }

public WP_JWT_Object JWT_Object { get; set; }

/// <summary>
/// Initialize the RestAPI object
/// </summary>
Expand Down Expand Up @@ -71,8 +74,13 @@ public RestAPI(string url, string key, string secret, bool authorizedHeader = tr
Version = APIVersion.Version3;
else if (urlLower.Contains("wp-json/wc-"))
Version = APIVersion.ThirdPartyPlugins;
else if (urlLower.EndsWith("wp-json"))
else if (urlLower.EndsWith("wp-json/wp/v2") || urlLower.EndsWith("wp-json"))
Version = APIVersion.WordPressAPI;
else if (urlLower.EndsWith("jwt-auth/v1/token"))
{
Version = APIVersion.WordPressAPIJWT;
url = urlLower.Replace("jwt-auth/v1/token", "wp/v2");
}
else
{
Version = APIVersion.Unknown;
Expand All @@ -84,7 +92,7 @@ public RestAPI(string url, string key, string secret, bool authorizedHeader = tr
AuthorizedHeader = authorizedHeader;

//Why extra '&'? look here: https://wordpress.org/support/topic/woocommerce-rest-api-v3-problem-woocommerce_api_authentication_error/
if ((url.ToLower().Contains("wc-api/v3") || !IsLegacy) && !wc_url.StartsWith("https", StringComparison.OrdinalIgnoreCase) && Version != APIVersion.WordPressAPI)
if ((url.ToLower().Contains("wc-api/v3") || !IsLegacy) && !wc_url.StartsWith("https", StringComparison.OrdinalIgnoreCase) && !(Version == APIVersion.WordPressAPI || Version == APIVersion.WordPressAPIJWT))
wc_secret = secret + "&";
else
wc_secret = secret;
Expand Down Expand Up @@ -120,7 +128,7 @@ public bool IsLegacy
/// <param name="requestBody">If your call doesn't have a body, please pass string.Empty, not null.</param>
/// <param name="parms"></param>
/// <returns>json string</returns>
public async Task<string> SendHttpClientRequest<T>(string endpoint, RequestMethod method, T requestBody, Dictionary<string, string> parms = null)
public virtual async Task<string> SendHttpClientRequest<T>(string endpoint, RequestMethod method, T requestBody, Dictionary<string, string> parms = null)
{
HttpWebRequest httpWebRequest = null;
try
Expand All @@ -131,7 +139,21 @@ public async Task<string> SendHttpClientRequest<T>(string endpoint, RequestMetho
throw new Exception($"oauth_token and oauth_token_secret parameters are required when using WordPress REST API.");
}

if (wc_url.StartsWith("https", StringComparison.OrdinalIgnoreCase) && Version != APIVersion.WordPressAPI)
if( Version == APIVersion.WordPressAPIJWT && JWT_Object == null)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(wc_url.Replace("wp/v2", "jwt-auth/v1/token"));
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
var buffer = Encoding.UTF8.GetBytes($"username={wc_key}&password={wc_secret}");
Stream dataStream = await request.GetRequestStreamAsync().ConfigureAwait(false);
dataStream.Write(buffer, 0, buffer.Length);
WebResponse response = await request.GetResponseAsync().ConfigureAwait(false);
Stream resStream = response.GetResponseStream();
string result = await GetStreamContent(resStream, "UTF-8").ConfigureAwait(false);
JWT_Object = DeserializeJSon<WP_JWT_Object>(result);
}

if (wc_url.StartsWith("https", StringComparison.OrdinalIgnoreCase) && Version != APIVersion.WordPressAPI && Version != APIVersion.WordPressAPIJWT)
{
if (AuthorizedHeader == true)
{
Expand All @@ -154,6 +176,8 @@ public async Task<string> SendHttpClientRequest<T>(string endpoint, RequestMetho
else
{
httpWebRequest = (HttpWebRequest)WebRequest.Create(wc_url + GetOAuthEndPoint(method.ToString(), endpoint, parms));
if (Version == APIVersion.WordPressAPIJWT)
httpWebRequest.Headers["Authorization"] = "Bearer " + JWT_Object.token;
}

// start the stream immediately
Expand All @@ -179,13 +203,32 @@ public async Task<string> SendHttpClientRequest<T>(string endpoint, RequestMetho
{
if (requestBody.ToString() != string.Empty)
{
httpWebRequest.ContentType = "application/json";
var buffer = Encoding.UTF8.GetBytes(requestBody.ToString());
Stream dataStream = await httpWebRequest.GetRequestStreamAsync().ConfigureAwait(false);
dataStream.Write(buffer, 0, buffer.Length);
if (requestBody.ToString() == "fileupload")
{
httpWebRequest.Headers["Content-Disposition"] = $"form-data; filename=\"{parms["name"]}\"";

Stream dataStream = await httpWebRequest.GetRequestStreamAsync().ConfigureAwait(false);
FileStream fileStream = new FileStream(parms["path"], FileMode.Open, FileAccess.Read);
byte[] buffer = new byte[4096];
int bytesRead = 0;

while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
{
dataStream.Write(buffer, 0, bytesRead);
}
fileStream.Close();
}
else
{
httpWebRequest.ContentType = "application/json";
var buffer = Encoding.UTF8.GetBytes(requestBody.ToString());
Stream dataStream = await httpWebRequest.GetRequestStreamAsync().ConfigureAwait(false);
dataStream.Write(buffer, 0, buffer.Length);
}
}
}


// asynchronously get a response
WebResponse wr = await httpWebRequest.GetResponseAsync().ConfigureAwait(false);

Expand Down Expand Up @@ -237,7 +280,7 @@ public async Task<string> DeleteRestful(string endpoint, object jsonObject, Dict

private string GetOAuthEndPoint(string method, string endpoint, Dictionary<string, string> parms = null)
{
if (wc_url.StartsWith("https", StringComparison.OrdinalIgnoreCase) && Version != APIVersion.WordPressAPI)
if (Version == APIVersion.WordPressAPIJWT || (wc_url.StartsWith("https", StringComparison.OrdinalIgnoreCase) && Version != APIVersion.WordPressAPI))
{
if (parms == null)
return endpoint;
Expand Down Expand Up @@ -315,6 +358,11 @@ public virtual string SerializeJSon<T>(T t)
byte[] data = stream.ToArray();
string jsonString = Encoding.UTF8.GetString(data, 0, data.Length);

if (t.GetType().GetMethod("FormatJsonS") != null)
{
jsonString = t.GetType().GetMethod("FormatJsonS").Invoke(null, new object[] { jsonString }).ToString();
}

if (IsLegacy)
if (typeof(T).IsArray)
jsonString = "{\"" + typeof(T).Name.ToLower().Replace("[]", "s") + "\":" + jsonString + "}";
Expand All @@ -339,6 +387,16 @@ public virtual T DeserializeJSon<T>(string jsonString)
if (dT.Name.EndsWith("List"))
dT = dT.GetTypeInfo().DeclaredProperties.First().PropertyType.GenericTypeArguments[0];

if(dT.FullName.StartsWith("System.Collections.Generic.List"))
{
dT = dT.GetProperty("Item").PropertyType;
}

if (dT.GetMethod("FormatJsonD") != null)
{
jsonString = dT.GetMethod("FormatJsonD").Invoke(null, new object[] { jsonString }).ToString();
}

DataContractJsonSerializerSettings settings = new DataContractJsonSerializerSettings()
{
DateTimeFormat = new DateTimeFormat(DateTimeFormat),
Expand All @@ -362,6 +420,17 @@ public string DateTimeFormat
}
}

public class WP_JWT_Object
{
public string token { get; set; }

public string user_email { get; set; }

public string user_nicename { get; set; }

public string user_display_name { get; set; }
}

public enum RequestMethod
{
HEAD = 1,
Expand All @@ -380,6 +449,7 @@ public enum APIVersion
Version2 = 3,
Version3 = 4,
WordPressAPI = 90,
WordPressAPIJWT = 91,
ThirdPartyPlugins = 99
}
}
24 changes: 17 additions & 7 deletions WooCommerce.NET.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,34 @@
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<PackageId>WooCommerceNET</PackageId>
<Version>0.7.7-beta</Version>
<Version>0.7.8</Version>
<Authors>JamesYang@NZ</Authors>
<Company>JamesYang@NZ</Company>
<Description>A .NET Wrapper for WooCommerce REST API</Description>
<Description>A .NET Wrapper for WooCommerce/WordPress REST API</Description>
<Copyright>Copyright © 2015 - 2019 James Yang@NZ</Copyright>
<PackageLicenseUrl>https://github.com/XiaoFaye/WooCommerce.NET/blob/master/License.md</PackageLicenseUrl>
<PackageLicenseUrl></PackageLicenseUrl>
<PackageProjectUrl>https://github.com/XiaoFaye/WooCommerce.NET</PackageProjectUrl>
<PackageReleaseNotes>WooCommerce.NET is a .NET library for calling WooCommerce REST API in any .NET applications.
<PackageReleaseNotes>WooCommerce.NET is a .NET library for calling WooCommerce/WordPress REST API in .NET applications.

GitHub: https://github.com/XiaoFaye/WooCommerce.NET
Changes Doc: https://github.com/XiaoFaye/WooCommerce.NET/blob/master/Changes.md

* v0.7.6 update
1. Supporting WooCommerce Restful API V3.</PackageReleaseNotes>
* v0.7.8 update
1. Supporting Wordpress REST API with OAuth 1.0a.
2. Supporting Wordpress REST API with JWT Authentication.
3. Fix few minor issues.</PackageReleaseNotes>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<AssemblyVersion>0.7.7.0</AssemblyVersion>
<AssemblyVersion>0.7.8.0</AssemblyVersion>
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>sn.key.snk</AssemblyOriginatorKeyFile>
<PackageLicenseFile>License.md</PackageLicenseFile>
</PropertyGroup>

<ItemGroup>
<None Include="License.md">
<Pack>True</Pack>
<PackagePath></PackagePath>
</None>
</ItemGroup>

</Project>
Loading

0 comments on commit 8b8f25c

Please sign in to comment.