diff --git a/Base/BaseObject.cs b/Base/BaseObject.cs
index 6a7303d..e3c5a91 100644
--- a/Base/BaseObject.cs
+++ b/Base/BaseObject.cs
@@ -5,6 +5,7 @@
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;
+using WooCommerce.NET.WordPress.v2;
namespace WooCommerceNET.Base
{
diff --git a/Changes.md b/Changes.md
index aed0389..7c467ee 100644
--- a/Changes.md
+++ b/Changes.md
@@ -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.
diff --git a/Readme.md b/Readme.md
index 743839b..bdece5f 100644
--- a/Readme.md
+++ b/Readme.md
@@ -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
--------------------
-
+
+ Click to expand/collapse details...
+
```cs
using WooCommerceNET.WooCommerce.v3;
using WooCommerceNET.WooCommerce.v3.Extension;
@@ -83,75 +88,60 @@ cb.delete = delete;
var c = await wc.Customer.UpdateRange(cb);
```
+
-
-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)
+
+
+ Click to expand/collapse details...
```cs
-//Legacy way of calling WooCommerce REST API
-//using WooCommerceNET.WooCommerce.Legacy;
-//
-//RestAPI rest = new RestAPI("http://www.yourstore.co.nz/wc-api/v3/", "", "", "");
+rest.oauth_token = "";
+rest.oauth_token_secret = "";
-RestAPI rest = new RestAPI("http://www.yourstore.co.nz/wp-json/wc/v1/", "", "", "");
-//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 = "abc "
+};
-//Delete product
-await wc.DeleteProduct(128);
+await wp.Post.Add(p);
-//Use parameters
-var p = await wc.GetProducts(new Dictionary() {
- { "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 = "first@lastsss.com",
- 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 = "test123@gmail.com",
+ password = "test@12345"
});
-List delete = new List() { 8 };
-
-cb.create = create;
-cb.update = update;
-cb.delete = delete;
-
-var c = await wc.UpdateCustomers(cb);
-
```
+
\ No newline at end of file
diff --git a/RestAPI.cs b/RestAPI.cs
index 0322996..7e835c5 100644
--- a/RestAPI.cs
+++ b/RestAPI.cs
@@ -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;
@@ -37,6 +38,8 @@ public class RestAPI
///
public string oauth_token_secret { get; set; }
+ public WP_JWT_Object JWT_Object { get; set; }
+
///
/// Initialize the RestAPI object
///
@@ -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;
@@ -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;
@@ -120,7 +128,7 @@ public bool IsLegacy
/// If your call doesn't have a body, please pass string.Empty, not null.
///
/// json string
- public async Task SendHttpClientRequest(string endpoint, RequestMethod method, T requestBody, Dictionary parms = null)
+ public virtual async Task SendHttpClientRequest(string endpoint, RequestMethod method, T requestBody, Dictionary parms = null)
{
HttpWebRequest httpWebRequest = null;
try
@@ -131,7 +139,21 @@ public async Task SendHttpClientRequest(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(result);
+ }
+
+ if (wc_url.StartsWith("https", StringComparison.OrdinalIgnoreCase) && Version != APIVersion.WordPressAPI && Version != APIVersion.WordPressAPIJWT)
{
if (AuthorizedHeader == true)
{
@@ -154,6 +176,8 @@ public async Task SendHttpClientRequest(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
@@ -179,13 +203,32 @@ public async Task SendHttpClientRequest(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);
@@ -237,7 +280,7 @@ public async Task DeleteRestful(string endpoint, object jsonObject, Dict
private string GetOAuthEndPoint(string method, string endpoint, Dictionary 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;
@@ -315,6 +358,11 @@ public virtual string SerializeJSon(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 + "}";
@@ -339,6 +387,16 @@ public virtual T DeserializeJSon(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),
@@ -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,
@@ -380,6 +449,7 @@ public enum APIVersion
Version2 = 3,
Version3 = 4,
WordPressAPI = 90,
+ WordPressAPIJWT = 91,
ThirdPartyPlugins = 99
}
}
diff --git a/WooCommerce.NET.csproj b/WooCommerce.NET.csproj
index 66c997b..b6a57ac 100644
--- a/WooCommerce.NET.csproj
+++ b/WooCommerce.NET.csproj
@@ -3,24 +3,34 @@
netstandard2.0
WooCommerceNET
- 0.7.7-beta
+ 0.7.8
JamesYang@NZ
JamesYang@NZ
- A .NET Wrapper for WooCommerce REST API
+ A .NET Wrapper for WooCommerce/WordPress REST API
Copyright © 2015 - 2019 James Yang@NZ
- https://github.com/XiaoFaye/WooCommerce.NET/blob/master/License.md
+
https://github.com/XiaoFaye/WooCommerce.NET
- 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 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.
+* 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.
true
- 0.7.7.0
+ 0.7.8.0
true
sn.key.snk
+ License.md
+
+
+ True
+
+
+
+
\ No newline at end of file
diff --git a/WooCommerce/v1/Customer.cs b/WooCommerce/v1/Customer.cs
index c74ef1b..8e4e983 100644
--- a/WooCommerce/v1/Customer.cs
+++ b/WooCommerce/v1/Customer.cs
@@ -15,7 +15,7 @@ public class Customer
/// read-only
///
[DataMember(EmitDefaultValue = false)]
- public int? id { get; set; }
+ public long? id { get; set; }
///
/// The date the customer was created, in the site’s timezone.
diff --git a/WooCommerce/v2/Customer.cs b/WooCommerce/v2/Customer.cs
index 1ea104d..619860a 100644
--- a/WooCommerce/v2/Customer.cs
+++ b/WooCommerce/v2/Customer.cs
@@ -17,7 +17,7 @@ public class Customer : JsonObject
/// read-only
///
[DataMember(EmitDefaultValue = false)]
- public int? id { get; set; }
+ public long? id { get; set; }
///
/// The date the customer was created, in the site’s timezone.
diff --git a/WooCommerce/v2/Order.cs b/WooCommerce/v2/Order.cs
index aed70b1..687e156 100644
--- a/WooCommerce/v2/Order.cs
+++ b/WooCommerce/v2/Order.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using WooCommerceNET.Base;
@@ -469,25 +469,22 @@ public class OrderLineItem : JsonObject
[DataMember(EmitDefaultValue = false)]
public string tax_class { get; set; }
+
+ [DataMember(EmitDefaultValue = false, Name = "subtotal")]
+ protected object subtotalValue { get; set; }
///
/// Line subtotal (before discounts).
///
public decimal? subtotal { get; set; }
-
- [DataMember(EmitDefaultValue = false, Name = "subtotal")]
- protected object subtotalValue { get; set; }
-
+ [DataMember(EmitDefaultValue = false, Name = "subtotal_tax")]
+ protected object subtotal_taxValue { get; set; }
///
/// Line subtotal tax (before discounts).
/// read-only
///
public decimal? subtotal_tax { get; set; }
- [DataMember(EmitDefaultValue = false, Name = "subtotal_tax")]
- protected object subtotal_taxValue { get; set; }
-
-
[DataMember(EmitDefaultValue = false, Name = "total")]
protected object totalValue { get; set; }
///
@@ -600,21 +597,18 @@ public class TaxItem : JsonObject
[DataMember(EmitDefaultValue = false)]
public int? id { get; set; }
- [DataMember(EmitDefaultValue = false, Name = "total")]
- protected object totalValue { get; set; }
-
///
/// tax item total
///
+ [DataMember(EmitDefaultValue = false, Name = "total")]
+ protected object totalValue { get; set; }
public decimal? total { get; set; }
-
- [DataMember(EmitDefaultValue = false, Name = "subtotal")]
- protected object subtotalValue { get; set; }
-
///
/// tax item subtotal
///
+ [DataMember(EmitDefaultValue = false, Name = "subtotal")]
+ protected object subtotalValue { get; set; }
public decimal? subtotal { get; set; }
}
diff --git a/WooCommerce/v3/Customer.cs b/WooCommerce/v3/Customer.cs
index 60d058f..c24cb10 100644
--- a/WooCommerce/v3/Customer.cs
+++ b/WooCommerce/v3/Customer.cs
@@ -17,7 +17,7 @@ public class Customer : JsonObject
/// read-only
///
[DataMember(EmitDefaultValue = false)]
- public int? id { get; set; }
+ public long? id { get; set; }
///
/// The date the customer was created, in the site’s timezone.
diff --git a/WooCommerce/v3/Product.cs b/WooCommerce/v3/Product.cs
index 033f984..43bd066 100644
--- a/WooCommerce/v3/Product.cs
+++ b/WooCommerce/v3/Product.cs
@@ -243,7 +243,7 @@ public class Product : JsonObject
public bool? manage_stock { get; set; }
[DataMember(EmitDefaultValue = false, Name = "stock_quantity")]
- private object stock_quantityValue { get; set; }
+ protected object stock_quantityValue { get; set; }
///
/// Stock quantity.
///
@@ -449,7 +449,7 @@ public class ProductImage
/// Image ID.
///
[DataMember(EmitDefaultValue = false)]
- public int? id { get; set; }
+ public long? id { get; set; }
///
/// The date the image was created, in the site’s timezone.
diff --git a/WooCommerce/v3/Variation.cs b/WooCommerce/v3/Variation.cs
index 86bdae0..672a9ec 100644
--- a/WooCommerce/v3/Variation.cs
+++ b/WooCommerce/v3/Variation.cs
@@ -180,7 +180,7 @@ public class Variation : JsonObject
public object manage_stock { get; set; }
[DataMember(EmitDefaultValue = false, Name = "stock_quantity")]
- private object stock_quantityValue { get; set; }
+ protected object stock_quantityValue { get; set; }
///
/// Stock quantity.
///
diff --git a/WordPress/v2/Categories.cs b/WordPress/v2/Categories.cs
new file mode 100644
index 0000000..9b6765d
--- /dev/null
+++ b/WordPress/v2/Categories.cs
@@ -0,0 +1,67 @@
+using System;
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+using System.Text;
+
+namespace WooCommerce.NET.WordPress.v2
+{
+ [DataContract]
+ public class Categories
+ {
+ public static string Endpoint { get { return "categories"; } }
+
+ ///
+ /// Unique identifier for the term.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public int id { get; set; }
+
+ ///
+ /// Number of published posts for the term.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public int count { get; set; }
+
+ ///
+ /// HTML description of the term.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string description { get; set; }
+
+ ///
+ /// URL of the term.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string link { get; set; }
+
+ ///
+ /// HTML title for the term.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string name { get; set; }
+
+ ///
+ /// An alphanumeric identifier for the term unique to its type.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string slug { get; set; }
+
+ ///
+ /// Type attribution for the term.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string taxonomy { get; set; }
+
+ ///
+ /// The parent term ID.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public int parent { get; set; }
+
+ ///
+ /// Meta fields.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public object meta { get; set; }
+ }
+}
diff --git a/WordPress/v2/Comments.cs b/WordPress/v2/Comments.cs
new file mode 100644
index 0000000..708dd73
--- /dev/null
+++ b/WordPress/v2/Comments.cs
@@ -0,0 +1,157 @@
+using System;
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+using System.Text;
+
+namespace WooCommerce.NET.WordPress.v2
+{
+ [DataContract]
+ public class Comments
+ {
+ public static string Endpoint { get { return "comments"; } }
+ ///
+ /// Unique identifier for the object.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public int id { get; set; }
+
+ ///
+ /// The ID of the user object, if author was a user.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public int author { get; set; }
+
+ ///
+ /// Email address for the object author.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string author_email { get; set; }
+
+ ///
+ /// IP address for the object author.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string author_ip { get; set; }
+
+ ///
+ /// Display name for the object author.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string author_name { get; set; }
+
+ ///
+ /// URL for the object author.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string author_url { get; set; }
+
+ ///
+ /// User agent for the object author.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string author_user_agent { get; set; }
+
+ ///
+ /// The content for the object.
+ ///
+ [DataMember(EmitDefaultValue = false, Name = "content")]
+ protected ContentObject contentValue { get; set; }
+
+ [IgnoreDataMember]
+ public string content
+ {
+ get
+ {
+ return contentValue.rendered;
+ }
+ set
+ {
+ if (contentValue == null)
+ contentValue = new ContentObject();
+
+ contentValue.rendered = value;
+ }
+ }
+
+ ///
+ /// The date the object was published, in the site's timezone.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string date { get; set; }
+
+ ///
+ /// The date the object was published, as GMT.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string date_gmt { get; set; }
+
+ ///
+ /// URL to the object.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string link { get; set; }
+
+ ///
+ /// The ID for the parent of the object.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public int parent { get; set; }
+
+ ///
+ /// The ID of the associated post object.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public int post { get; set; }
+
+ ///
+ /// State of the object.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string status { get; set; }
+
+ ///
+ /// Type of Comment for the object.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string type { get; set; }
+
+ ///
+ /// Avatar URLs for the object author.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public object author_avatar_urls { get; set; }
+
+ ///
+ /// Meta fields.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public object meta { get; set; }
+
+ ///
+ /// Format json string on Serialize
+ ///
+ ///
+ ///
+ public static string FormatJsonS(string json)
+ {
+ int startIndex = json.IndexOf("{\"rendered\":");
+ int endIndex = 0;
+ string oldPart = string.Empty;
+ string newPart = string.Empty;
+
+ while (startIndex > 0)
+ {
+ endIndex = json.IndexOf("\"}", startIndex);
+
+ oldPart = json.Substring(startIndex, endIndex - startIndex + 2);
+ newPart = oldPart.Substring(12).TrimEnd('}');
+
+ json = json.Replace(oldPart, newPart);
+
+ startIndex = json.IndexOf("{\"rendered\":");
+ }
+
+ return json;
+ }
+ }
+}
diff --git a/WordPress/v2/ContentObject.cs b/WordPress/v2/ContentObject.cs
new file mode 100644
index 0000000..47111a1
--- /dev/null
+++ b/WordPress/v2/ContentObject.cs
@@ -0,0 +1,18 @@
+using System;
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+using System.Text;
+using WooCommerceNET.Base;
+
+namespace WooCommerce.NET.WordPress.v2
+{
+ [DataContract]
+ public class ContentObject
+ {
+ [DataMember(EmitDefaultValue = false)]
+ public string rendered { get; set; }
+
+ [DataMember(EmitDefaultValue = false, Name = "protected")]
+ public bool _protected { get; set; }
+ }
+}
diff --git a/WordPress/v2/Media.cs b/WordPress/v2/Media.cs
new file mode 100644
index 0000000..1b65cf2
--- /dev/null
+++ b/WordPress/v2/Media.cs
@@ -0,0 +1,248 @@
+using System;
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+using System.Text;
+
+namespace WooCommerce.NET.WordPress.v2
+{
+ [DataContract]
+ public class Media
+ {
+ public static string Endpoint { get { return "media"; } }
+
+ ///
+ /// The date the object was published, in the site's timezone.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string date { get; set; }
+
+ ///
+ /// The date the object was published, as GMT.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string date_gmt { get; set; }
+
+ ///
+ /// The globally unique identifier for the object.
+ ///
+ [DataMember(EmitDefaultValue = false, Name = "guid")]
+ protected ContentObject guidValue { get; set; }
+
+ [IgnoreDataMember]
+ public string guid
+ {
+ get
+ {
+ return guidValue.rendered;
+ }
+ set
+ {
+ if (guidValue == null)
+ guidValue = new ContentObject();
+
+ guidValue.rendered = value;
+ }
+ }
+
+ ///
+ /// Unique identifier for the object.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public int id { get; set; }
+
+ ///
+ /// URL to the object.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string link { get; set; }
+
+ ///
+ /// The date the object was last modified, in the site's timezone.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string modified { get; set; }
+
+ ///
+ /// The date the object was last modified, as GMT.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string modified_gmt { get; set; }
+
+ ///
+ /// An alphanumeric identifier for the object unique to its type.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string slug { get; set; }
+
+ ///
+ /// A named status for the object.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string status { get; set; }
+
+ ///
+ /// Type of Post for the object.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string type { get; set; }
+
+ ///
+ /// The title for the object.
+ ///
+ [DataMember(EmitDefaultValue = false, Name = "title")]
+ protected ContentObject titleValue { get; set; }
+
+ [IgnoreDataMember]
+ public string title
+ {
+ get
+ {
+ return titleValue.rendered;
+ }
+ set
+ {
+ if (titleValue == null)
+ titleValue = new ContentObject();
+
+ titleValue.rendered = value;
+ }
+ }
+
+ ///
+ /// The ID for the author of the object.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public int author { get; set; }
+
+ ///
+ /// Whether or not comments are open on the object.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string comment_status { get; set; }
+
+ ///
+ /// Whether or not the object can be pinged.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string ping_status { get; set; }
+
+ ///
+ /// Meta fields.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public List meta { get; set; }
+
+ ///
+ /// The theme file to use to display the object.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string template { get; set; }
+
+ ///
+ /// Alternative text to display when attachment is not displayed.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string alt_text { get; set; }
+
+ ///
+ /// The attachment caption.
+ ///
+ [DataMember(EmitDefaultValue = false, Name = "caption")]
+ protected ContentObject captionValue { get; set; }
+
+ [IgnoreDataMember]
+ public string caption
+ {
+ get
+ {
+ return captionValue.rendered;
+ }
+ set
+ {
+ if (captionValue == null)
+ captionValue = new ContentObject();
+
+ captionValue.rendered = value;
+ }
+ }
+
+ ///
+ /// The attachment description.
+ ///
+ [DataMember(EmitDefaultValue = false, Name = "description")]
+ protected ContentObject descriptionValue { get; set; }
+
+ [IgnoreDataMember]
+ public string description
+ {
+ get
+ {
+ return descriptionValue.rendered;
+ }
+ set
+ {
+ if (descriptionValue == null)
+ descriptionValue = new ContentObject();
+
+ descriptionValue.rendered = value;
+ }
+ }
+
+ ///
+ /// Attachment type.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string media_type { get; set; }
+
+ ///
+ /// The attachment MIME type.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string mime_type { get; set; }
+
+ ///
+ /// Details about the media file, specific to its type.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public object media_details { get; set; }
+
+ ///
+ /// The ID for the associated post of the attachment.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public int? post { get; set; }
+
+ ///
+ /// URL to the original attachment file.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string source_url { get; set; }
+
+ ///
+ /// Format json string on Serialize
+ ///
+ ///
+ ///
+ public static string FormatJsonS(string json)
+ {
+ int startIndex = json.IndexOf("{\"rendered\":");
+ int endIndex = 0;
+ string oldPart = string.Empty;
+ string newPart = string.Empty;
+
+ while (startIndex > 0)
+ {
+ endIndex = json.IndexOf("\"}", startIndex);
+
+ oldPart = json.Substring(startIndex, endIndex - startIndex + 2);
+ newPart = oldPart.Substring(12).TrimEnd('}');
+
+ json = json.Replace(oldPart, newPart);
+
+ startIndex = json.IndexOf("{\"rendered\":");
+ }
+
+ return json;
+ }
+ }
+}
diff --git a/WordPress/v2/Pages.cs b/WordPress/v2/Pages.cs
new file mode 100644
index 0000000..214aebd
--- /dev/null
+++ b/WordPress/v2/Pages.cs
@@ -0,0 +1,237 @@
+using System;
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+using System.Text;
+
+namespace WooCommerce.NET.WordPress.v2
+{
+ [DataContract]
+ public class Pages
+ {
+ public static string Endpoint { get { return "pages"; } }
+
+ ///
+ /// The date the object was published, in the site's timezone.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string date { get; set; }
+
+ ///
+ /// The date the object was published, as GMT.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string date_gmt { get; set; }
+
+ ///
+ /// The globally unique identifier for the object.
+ ///
+ [DataMember(EmitDefaultValue = false, Name = "guid")]
+ protected ContentObject guidValue { get; set; }
+
+ [IgnoreDataMember]
+ public string guid
+ {
+ get
+ {
+ return guidValue.rendered;
+ }
+ set
+ {
+ if (guidValue == null)
+ guidValue = new ContentObject();
+
+ guidValue.rendered = value;
+ }
+ }
+
+ ///
+ /// Unique identifier for the object.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public int id { get; set; }
+
+ ///
+ /// URL to the object.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string link { get; set; }
+
+ ///
+ /// The date the object was last modified, in the site's timezone.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string modified { get; set; }
+
+ ///
+ /// The date the object was last modified, as GMT.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string modified_gmt { get; set; }
+
+ ///
+ /// An alphanumeric identifier for the object unique to its type.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string slug { get; set; }
+
+ ///
+ /// A named status for the object.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string status { get; set; }
+
+ ///
+ /// Type of Post for the object.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string type { get; set; }
+
+ ///
+ /// A password to protect access to the content and excerpt.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string password { get; set; }
+
+ ///
+ /// The ID for the parent of the object.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public int parent { get; set; }
+
+ ///
+ /// The title for the object.
+ ///
+ [DataMember(EmitDefaultValue = false, Name = "title")]
+ protected ContentObject titleValue { get; set; }
+
+ [IgnoreDataMember]
+ public string title
+ {
+ get
+ {
+ return titleValue.rendered;
+ }
+ set
+ {
+ if (titleValue == null)
+ titleValue = new ContentObject();
+
+ titleValue.rendered = value;
+ }
+ }
+
+ ///
+ /// The content for the object.
+ ///
+ [DataMember(EmitDefaultValue = false, Name = "content")]
+ protected ContentObject contentValue { get; set; }
+
+ [IgnoreDataMember]
+ public string content
+ {
+ get
+ {
+ return contentValue.rendered;
+ }
+ set
+ {
+ if (contentValue == null)
+ contentValue = new ContentObject();
+
+ contentValue.rendered = value;
+ }
+ }
+
+
+ ///
+ /// The ID for the author of the object.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public int author { get; set; }
+
+ ///
+ /// The excerpt for the object.
+ ///
+ [DataMember(EmitDefaultValue = false, Name = "excerpt")]
+ protected ContentObject excerptValue { get; set; }
+
+ [IgnoreDataMember]
+ public string excerpt
+ {
+ get
+ {
+ return excerptValue.rendered;
+ }
+ set
+ {
+ if (excerptValue == null)
+ excerptValue = new ContentObject();
+
+ excerptValue.rendered = value;
+ }
+ }
+
+ ///
+ /// The ID of the featured media for the object.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public int featured_media { get; set; }
+
+ ///
+ /// Whether or not comments are open on the object.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string comment_status { get; set; }
+
+ ///
+ /// Whether or not the object can be pinged.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string ping_status { get; set; }
+
+ ///
+ /// The order of the object in relation to other object of its type.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public int menu_order { get; set; }
+
+ ///
+ /// Meta fields.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public object meta { get; set; }
+
+ ///
+ /// The theme file to use to display the object.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string template { get; set; }
+
+ ///
+ /// Format json string on Serialize
+ ///
+ ///
+ ///
+ public static string FormatJsonS(string json)
+ {
+ int startIndex = json.IndexOf("{\"rendered\":");
+ int endIndex = 0;
+ string oldPart = string.Empty;
+ string newPart = string.Empty;
+
+ while (startIndex > 0)
+ {
+ endIndex = json.IndexOf("\"}", startIndex);
+
+ oldPart = json.Substring(startIndex, endIndex - startIndex + 2);
+ newPart = oldPart.Substring(12).TrimEnd('}');
+
+ json = json.Replace(oldPart, newPart);
+
+ startIndex = json.IndexOf("{\"rendered\":");
+ }
+
+ return json;
+ }
+ }
+}
diff --git a/WordPress/v2/PostRevisions.cs b/WordPress/v2/PostRevisions.cs
new file mode 100644
index 0000000..0a85ce9
--- /dev/null
+++ b/WordPress/v2/PostRevisions.cs
@@ -0,0 +1,176 @@
+using System;
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+using System.Text;
+
+namespace WooCommerce.NET.WordPress.v2
+{
+ [DataContract]
+ public class PostRevisions
+ {
+ public static string Endpoint { get { return "revisions"; } }
+
+ ///
+ /// The ID for the author of the object.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public int author { get; set; }
+
+ ///
+ /// The date the object was published, in the site's timezone.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string date { get; set; }
+
+ ///
+ /// The date the object was published, as GMT.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string date_gmt { get; set; }
+
+ ///
+ /// The globally unique identifier for the object.
+ ///
+ [DataMember(EmitDefaultValue = false, Name = "guid")]
+ protected ContentObject guidValue { get; set; }
+
+ [IgnoreDataMember]
+ public string guid
+ {
+ get
+ {
+ return guidValue.rendered;
+ }
+ set
+ {
+ if (guidValue == null)
+ guidValue = new ContentObject();
+
+ guidValue.rendered = value;
+ }
+ }
+
+ ///
+ /// Unique identifier for the object.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public int id { get; set; }
+
+ ///
+ /// The date the object was last modified, in the site's timezone.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string modified { get; set; }
+
+ ///
+ /// The date the object was last modified, as GMT.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string modified_gmt { get; set; }
+
+ ///
+ /// The ID for the parent of the object.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public int parent { get; set; }
+
+ ///
+ /// An alphanumeric identifier for the object unique to its type.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string slug { get; set; }
+
+ ///
+ /// The title for the object.
+ ///
+ [DataMember(EmitDefaultValue = false, Name = "title")]
+ protected ContentObject titleValue { get; set; }
+
+ [IgnoreDataMember]
+ public string title
+ {
+ get
+ {
+ return titleValue.rendered;
+ }
+ set
+ {
+ if (titleValue == null)
+ titleValue = new ContentObject();
+
+ titleValue.rendered = value;
+ }
+ }
+
+ ///
+ /// The content for the object.
+ ///
+ [DataMember(EmitDefaultValue = false, Name = "content")]
+ protected ContentObject contentValue { get; set; }
+
+ [IgnoreDataMember]
+ public string content
+ {
+ get
+ {
+ return contentValue.rendered;
+ }
+ set
+ {
+ if (contentValue == null)
+ contentValue = new ContentObject();
+
+ contentValue.rendered = value;
+ }
+ }
+
+ ///
+ /// The excerpt for the object.
+ ///
+ [DataMember(EmitDefaultValue = false, Name = "excerpt")]
+ protected ContentObject excerptValue { get; set; }
+
+ [IgnoreDataMember]
+ public string excerpt
+ {
+ get
+ {
+ return excerptValue.rendered;
+ }
+ set
+ {
+ if (excerptValue == null)
+ excerptValue = new ContentObject();
+
+ excerptValue.rendered = value;
+ }
+ }
+
+ ///
+ /// Format json string on Serialize
+ ///
+ ///
+ ///
+ public static string FormatJsonS(string json)
+ {
+ int startIndex = json.IndexOf("{\"rendered\":");
+ int endIndex = 0;
+ string oldPart = string.Empty;
+ string newPart = string.Empty;
+
+ while (startIndex > 0)
+ {
+ endIndex = json.IndexOf("\"}", startIndex);
+
+ oldPart = json.Substring(startIndex, endIndex - startIndex + 2);
+ newPart = oldPart.Substring(12).TrimEnd('}');
+
+ json = json.Replace(oldPart, newPart);
+
+ startIndex = json.IndexOf("{\"rendered\":");
+ }
+
+ return json;
+ }
+ }
+}
diff --git a/WordPress/v2/PostStatuses.cs b/WordPress/v2/PostStatuses.cs
new file mode 100644
index 0000000..5c47922
--- /dev/null
+++ b/WordPress/v2/PostStatuses.cs
@@ -0,0 +1,93 @@
+using System;
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+using System.Text;
+
+namespace WooCommerce.NET.WordPress.v2
+{
+ [DataContract]
+ public class PostStatuses
+ {
+ public static string Endpoint { get { return "statuses"; } }
+ ///
+ /// The title for the status.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string name { get; set; }
+
+ ///
+ /// Whether posts with this status should be private.
+ ///
+ [DataMember(EmitDefaultValue = false, Name = "private")]
+ public bool _private { get; set; }
+
+ ///
+ /// Whether posts with this status should be protected.
+ ///
+ [DataMember(EmitDefaultValue = false, Name = "protected")]
+ public bool _protected { get; set; }
+
+ ///
+ /// Whether posts of this status should be shown in the front end of the site.
+ ///
+ [DataMember(EmitDefaultValue = false, Name = "public")]
+ public bool _public { get; set; }
+
+ ///
+ /// Whether posts with this status should be publicly-queryable.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public bool queryable { get; set; }
+
+ ///
+ /// Whether to include posts in the edit listing for their post type.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public bool show_in_list { get; set; }
+
+ ///
+ /// An alphanumeric identifier for the status.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string slug { get; set; }
+
+ ///
+ /// Format json string on Deserialize
+ ///
+ ///
+ ///
+ public static string FormatJsonD(string json)
+ {
+ StringBuilder newJson = new StringBuilder();
+ newJson.Append('[');
+
+ int headIndex = json.IndexOf("\":{\"name\":\"");
+ int nextIndex = 0;
+ int quoteIndex = 0;
+
+ while (headIndex > 0)
+ {
+ nextIndex = json.IndexOf("\":{\"name\":\"", headIndex + 10);
+
+ if (nextIndex > 0)
+ {
+ quoteIndex = json.LastIndexOf("\"", nextIndex - 2);
+ newJson.Append(json.Substring(headIndex + 2, nextIndex - headIndex - (nextIndex - quoteIndex) - 3));
+ newJson.Append(',');
+
+ headIndex = json.IndexOf("\":{\"name\":\"", nextIndex);
+ }
+ else
+ {
+ string temp = json.Substring(headIndex + 2);
+ newJson.Append(temp.Substring(0, temp.Length - 1));
+ newJson.Append(']');
+
+ break;
+ }
+ }
+
+ return newJson.ToString();
+ }
+ }
+}
diff --git a/WordPress/v2/PostTypes.cs b/WordPress/v2/PostTypes.cs
new file mode 100644
index 0000000..cb95bd7
--- /dev/null
+++ b/WordPress/v2/PostTypes.cs
@@ -0,0 +1,105 @@
+using System;
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+using System.Text;
+
+namespace WooCommerce.NET.WordPress.v2
+{
+ [DataContract]
+ public class PostTypes
+ {
+ public static string Endpoint { get { return "types"; } }
+ ///
+ /// All capabilities used by the post type.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public object capabilities { get; set; }
+
+ ///
+ /// A human-readable description of the post type.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string description { get; set; }
+
+ ///
+ /// Whether or not the post type should have children.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public bool hierarchical { get; set; }
+
+ ///
+ /// Human-readable labels for the post type for various contexts.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public object labels { get; set; }
+
+ ///
+ /// The title for the post type.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string name { get; set; }
+
+ ///
+ /// An alphanumeric identifier for the post type.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string slug { get; set; }
+
+ ///
+ /// All features, supported by the post type.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public object supports { get; set; }
+
+ ///
+ /// Taxonomies associated with post type.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public List taxonomies { get; set; }
+
+ ///
+ /// REST base route for the post type.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string rest_base { get; set; }
+
+ ///
+ /// Format json string on Deserialize
+ ///
+ ///
+ ///
+ public static string FormatJsonD(string json)
+ {
+ StringBuilder newJson = new StringBuilder();
+ newJson.Append('[');
+
+ int headIndex = json.IndexOf("\":{\"description\":\"");
+ int nextIndex = 0;
+ int quoteIndex = 0;
+
+ while (headIndex > 0)
+ {
+ nextIndex = json.IndexOf("\":{\"description\":\"", headIndex + 10);
+
+ if (nextIndex > 0)
+ {
+ quoteIndex = json.LastIndexOf("\"", nextIndex - 2);
+ newJson.Append(json.Substring(headIndex + 2, nextIndex - headIndex - (nextIndex - quoteIndex) - 3));
+ newJson.Append(',');
+
+ headIndex = json.IndexOf("\":{\"description\":\"", nextIndex);
+ }
+ else
+ {
+ string temp = json.Substring(headIndex + 2);
+ newJson.Append(temp.Substring(0, temp.Length - 1));
+ newJson.Append(']');
+
+ break;
+ }
+ }
+
+ return newJson.ToString();
+ }
+ }
+}
diff --git a/WordPress/v2/Posts.cs b/WordPress/v2/Posts.cs
new file mode 100644
index 0000000..45270f1
--- /dev/null
+++ b/WordPress/v2/Posts.cs
@@ -0,0 +1,249 @@
+using System;
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+using System.Text;
+using WooCommerceNET.Base;
+
+namespace WooCommerce.NET.WordPress.v2
+{
+ [DataContract]
+ public class Posts
+ {
+ public static string Endpoint { get { return "posts"; } }
+
+ ///
+ /// The date the object was published, in the site's timezone.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string date { get; set; }
+
+ ///
+ /// The date the object was published, as GMT.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string date_gmt { get; set; }
+
+ ///
+ /// The globally unique identifier for the object.
+ ///
+ [DataMember(EmitDefaultValue = false, Name = "guid")]
+ protected ContentObject guidValue { get; set; }
+
+ [IgnoreDataMember]
+ public string guid
+ {
+ get
+ {
+ return guidValue.rendered;
+ }
+ set
+ {
+ if (guidValue == null)
+ guidValue = new ContentObject();
+
+ guidValue.rendered = value;
+ }
+ }
+
+ ///
+ /// Unique identifier for the object.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public int id { get; set; }
+
+ ///
+ /// URL to the object.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string link { get; set; }
+
+ ///
+ /// The date the object was last modified, in the site's timezone.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string modified { get; set; }
+
+ ///
+ /// The date the object was last modified, as GMT.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string modified_gmt { get; set; }
+
+ ///
+ /// An alphanumeric identifier for the object unique to its type.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string slug { get; set; }
+
+ ///
+ /// A named status for the object.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string status { get; set; }
+
+ ///
+ /// Type of Post for the object.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string type { get; set; }
+
+ ///
+ /// A password to protect access to the content and excerpt.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string password { get; set; }
+
+ ///
+ /// The title for the object.
+ ///
+ [DataMember(EmitDefaultValue = false, Name = "title")]
+ protected ContentObject titleValue { get; set; }
+
+ [IgnoreDataMember]
+ public string title
+ {
+ get
+ {
+ return titleValue.rendered;
+ }
+ set
+ {
+ if (titleValue == null)
+ titleValue = new ContentObject();
+
+ titleValue.rendered = value;
+ }
+ }
+
+ ///
+ /// The content for the object.
+ ///
+ [DataMember(EmitDefaultValue = false, Name = "content")]
+ protected ContentObject contentValue { get; set; }
+
+ [IgnoreDataMember]
+ public string content
+ {
+ get
+ {
+ return contentValue.rendered;
+ }
+ set
+ {
+ if (contentValue == null)
+ contentValue = new ContentObject();
+
+ contentValue.rendered = value;
+ }
+ }
+
+ ///
+ /// The ID for the author of the object.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public int author { get; set; }
+
+ ///
+ /// The excerpt for the object.
+ ///
+ [DataMember(EmitDefaultValue = false, Name = "excerpt")]
+ protected ContentObject excerptValue { get; set; }
+
+ [IgnoreDataMember]
+ public string excerpt
+ {
+ get
+ {
+ return excerptValue.rendered;
+ }
+ set
+ {
+ if (excerptValue == null)
+ excerptValue = new ContentObject();
+
+ excerptValue.rendered = value;
+ }
+ }
+
+ ///
+ /// The ID of the featured media for the object.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public int featured_media { get; set; }
+
+ ///
+ /// Whether or not comments are open on the object.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string comment_status { get; set; }
+
+ ///
+ /// Whether or not the object can be pinged.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string ping_status { get; set; }
+
+ ///
+ /// The format for the object.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string format { get; set; }
+
+ ///
+ /// Meta fields.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public object meta { get; set; }
+
+ ///
+ /// Whether or not the object should be treated as sticky.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public bool sticky { get; set; }
+
+ ///
+ /// The theme file to use to display the object.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string template { get; set; }
+
+ ///
+ /// The terms assigned to the object in the category taxonomy.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public List categories { get; set; }
+
+ ///
+ /// The terms assigned to the object in the post_tag taxonomy.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public List tags { get; set; }
+
+ ///
+ /// Format json string on Serialize
+ ///
+ ///
+ ///
+ public static string FormatJsonS(string json)
+ {
+ int startIndex = json.IndexOf("{\"rendered\":");
+ int endIndex = 0;
+ string oldPart = string.Empty;
+ string newPart = string.Empty;
+
+ while (startIndex > 0)
+ {
+ endIndex = json.IndexOf("\"}", startIndex);
+
+ oldPart = json.Substring(startIndex, endIndex - startIndex + 2);
+ newPart = oldPart.Substring(12).TrimEnd('}');
+
+ json = json.Replace(oldPart, newPart);
+
+ startIndex = json.IndexOf("{\"rendered\":");
+ }
+
+ return json;
+ }
+ }
+}
diff --git a/WordPress/v2/Settings.cs b/WordPress/v2/Settings.cs
new file mode 100644
index 0000000..30225a6
--- /dev/null
+++ b/WordPress/v2/Settings.cs
@@ -0,0 +1,90 @@
+using System;
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+using System.Text;
+
+namespace WooCommerce.NET.WordPress.v2
+{
+ [DataContract]
+ public class Settings
+ {
+ public static string Endpoint { get { return "settings"; } }
+ ///
+ /// Site title.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string title { get; set; }
+
+ ///
+ /// Site tagline.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string description { get; set; }
+
+ ///
+ /// A city in the same timezone as you.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string timezone { get; set; }
+
+ ///
+ /// A date format for all date strings.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string date_format { get; set; }
+
+ ///
+ /// A time format for all time strings.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string time_format { get; set; }
+
+ ///
+ /// A day number of the week that the week should start on.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public int start_of_week { get; set; }
+
+ ///
+ /// WordPress locale code.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string language { get; set; }
+
+ ///
+ /// Convert emoticons like :-) and :-P to graphics on display.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public bool use_smilies { get; set; }
+
+ ///
+ /// Default post category.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public int default_category { get; set; }
+
+ ///
+ /// Default post format.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string default_post_format { get; set; }
+
+ ///
+ /// Blog pages show at most.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public int posts_per_page { get; set; }
+
+ ///
+ /// Allow link notifications from other blogs (pingbacks and trackbacks) on new articles.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string default_ping_status { get; set; }
+
+ ///
+ /// Allow people to post comments on new articles.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string default_comment_status { get; set; }
+ }
+}
diff --git a/WordPress/v2/Tags.cs b/WordPress/v2/Tags.cs
new file mode 100644
index 0000000..1ed127d
--- /dev/null
+++ b/WordPress/v2/Tags.cs
@@ -0,0 +1,61 @@
+using System;
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+using System.Text;
+
+namespace WooCommerce.NET.WordPress.v2
+{
+ [DataContract]
+ public class Tags
+ {
+ public static string Endpoint { get { return "tags"; } }
+
+ ///
+ /// Unique identifier for the term.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public int id { get; set; }
+
+ ///
+ /// Number of published posts for the term.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public int count { get; set; }
+
+ ///
+ /// HTML description of the term.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string description { get; set; }
+
+ ///
+ /// URL of the term.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string link { get; set; }
+
+ ///
+ /// HTML title for the term.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string name { get; set; }
+
+ ///
+ /// An alphanumeric identifier for the term unique to its type.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string slug{ get; set; }
+
+ ///
+ /// Type attribution for the term.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string taxonomy { get; set; }
+
+ ///
+ /// Meta fields.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public object meta { get; set; }
+ }
+}
diff --git a/WordPress/v2/Taxonomies.cs b/WordPress/v2/Taxonomies.cs
new file mode 100644
index 0000000..dbe5a21
--- /dev/null
+++ b/WordPress/v2/Taxonomies.cs
@@ -0,0 +1,166 @@
+using System;
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+using System.Text;
+using WooCommerceNET.Base;
+
+namespace WooCommerce.NET.WordPress.v2
+{
+ [DataContract]
+ public class Taxonomies : JsonObject
+ {
+ public static string Endpoint { get { return "taxonomies"; } }
+ ///
+ /// All capabilities used by the taxonomy.
+ ///
+ [DataMember(EmitDefaultValue = false, Name = "capabilities")]
+ protected ContentObject capabilitiesValue { get; set; }
+
+
+ [IgnoreDataMember]
+ public string capabilities
+ {
+ get
+ {
+ return capabilitiesValue.rendered;
+ }
+ set
+ {
+ if (capabilitiesValue == null)
+ capabilitiesValue = new ContentObject();
+
+ capabilitiesValue.rendered = value;
+ }
+ }
+
+ ///
+ /// A human-readable description of the taxonomy.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string description { get; set; }
+
+ ///
+ /// Whether or not the taxonomy should have children.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public bool hierarchical { get; set; }
+
+ ///
+ /// Human-readable labels for the taxonomy for various contexts.
+ ///
+ [DataMember(EmitDefaultValue = false, Name = "labels")]
+ protected ContentObject labelsValue { get; set; }
+
+ [IgnoreDataMember]
+ public string labels
+ {
+ get
+ {
+ return labelsValue.rendered;
+ }
+ set
+ {
+ if (labelsValue == null)
+ labelsValue = new ContentObject();
+
+ labelsValue.rendered = value;
+ }
+ }
+
+ ///
+ /// The title for the taxonomy.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string name { get; set; }
+
+ ///
+ /// An alphanumeric identifier for the taxonomy.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string slug { get; set; }
+
+ ///
+ /// Whether or not the term cloud should be displayed.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public bool show_cloud { get; set; }
+
+ ///
+ /// Types associated with the taxonomy.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public List types { get; set; }
+
+ ///
+ /// REST base route for the taxonomy.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string rest_base { get; set; }
+
+ ///
+ /// Format json string on Serialize
+ ///
+ ///
+ ///
+ public static string FormatJsonS(string json)
+ {
+ int startIndex = json.IndexOf("{\"rendered\":");
+ int endIndex = 0;
+ string oldPart = string.Empty;
+ string newPart = string.Empty;
+
+ while (startIndex > 0)
+ {
+ endIndex = json.IndexOf("\"}", startIndex);
+
+ oldPart = json.Substring(startIndex, endIndex - startIndex + 2);
+ newPart = oldPart.Substring(12).TrimEnd('}');
+
+ json = json.Replace(oldPart, newPart);
+
+ startIndex = json.IndexOf("{\"rendered\":");
+ }
+
+ return json;
+ }
+
+ ///
+ /// Format json string on Deserialize
+ ///
+ ///
+ ///
+ public static string FormatJsonD(string json)
+ {
+ StringBuilder newJson = new StringBuilder();
+ newJson.Append('[');
+
+ int headIndex = json.IndexOf("\":{\"name\":\"");
+ int nextIndex = 0;
+ int quoteIndex = 0;
+
+ while (headIndex > 0)
+ {
+ nextIndex = json.IndexOf("\":{\"name\":\"", headIndex + 10);
+
+ if(nextIndex > 0)
+ {
+ quoteIndex = json.LastIndexOf("\"", nextIndex - 2);
+ newJson.Append(json.Substring(headIndex + 2, nextIndex - headIndex - (nextIndex - quoteIndex) - 3));
+ newJson.Append(',');
+
+ headIndex = json.IndexOf("\":{\"name\":\"", nextIndex);
+ }
+ else
+ {
+ string temp = json.Substring(headIndex + 2);
+ newJson.Append(temp.Substring(0, temp.Length - 1));
+ newJson.Append(']');
+
+ break;
+ }
+ }
+
+ return newJson.ToString();
+ }
+ }
+}
diff --git a/WordPress/v2/Users.cs b/WordPress/v2/Users.cs
new file mode 100644
index 0000000..7784229
--- /dev/null
+++ b/WordPress/v2/Users.cs
@@ -0,0 +1,127 @@
+using System;
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+using System.Text;
+
+namespace WooCommerce.NET.WordPress.v2
+{
+ [DataContract]
+ public class Users
+ {
+ public static string Endpoint { get { return "users"; } }
+
+ ///
+ /// Unique identifier for the user.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public int id { get; set; }
+
+ ///
+ /// Login name for the user.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string username { get; set; }
+
+ ///
+ /// Display name for the user.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string name { get; set; }
+
+ ///
+ /// First name for the user.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string first_name { get; set; }
+
+ ///
+ /// Last name for the user.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string last_name { get; set; }
+
+ ///
+ /// The email address for the user.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string email { get; set; }
+
+ ///
+ /// URL of the user.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string url { get; set; }
+
+ ///
+ /// Description of the user.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string description { get; set; }
+
+ ///
+ /// Author URL of the user.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string link { get; set; }
+
+ ///
+ /// Locale for the user.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string locale { get; set; }
+
+ ///
+ /// The nickname for the user.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string nickname { get; set; }
+
+ ///
+ /// An alphanumeric identifier for the user.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string slug { get; set; }
+
+ ///
+ /// Registration date for the user.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string registered_date { get; set; }
+
+ ///
+ /// Roles assigned to the user.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public List roles { get; set; }
+
+ ///
+ /// Password for the user (never included).
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public string password { get; set; }
+
+ ///
+ /// All capabilities assigned to the user.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public object capabilities { get; set; }
+
+ ///
+ /// Any extra capabilities assigned to the user.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public object extra_capabilities { get; set; }
+
+ ///
+ /// Avatar URLs for the user.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public object avatar_urls { get; set; }
+
+ ///
+ /// Meta fields.
+ ///
+ [DataMember(EmitDefaultValue = false)]
+ public List meta { get; set; }
+ }
+}
diff --git a/WordPress/v2/WPObject.cs b/WordPress/v2/WPObject.cs
new file mode 100644
index 0000000..e2d1caa
--- /dev/null
+++ b/WordPress/v2/WPObject.cs
@@ -0,0 +1,136 @@
+using System;
+using System.Collections.Generic;
+using System.Net.Http;
+using System.Runtime.Serialization;
+using System.Threading;
+using System.Threading.Tasks;
+using WooCommerceNET;
+using WooCommerceNET.Base;
+
+namespace WooCommerce.NET.WordPress.v2
+{
+ public class WPObject
+ where T1 : Posts where T2 : PostRevisions where T3 : Categories where T4 : Tags where T5 : Pages where T6 : Comments
+ where T7 : Taxonomies where T8 : Media where T9 : Users where T10 : PostTypes where T11 : PostStatuses where T12 : Settings
+ {
+
+ protected RestAPI API { get; set; }
+ public WPObject(RestAPI api)
+ {
+ API = api;
+
+ Post = new WPPostItem(api);
+ Categories = new WCItem(api);
+ Tags = new WCItem(api);
+ Pages = new WCItem(api);
+ Comments = new WCItem(api);
+ Taxonomies = new WCItem(api);
+ Media = new WPMediaItem(api);
+ Users = new WCItem(api);
+ PostTypes = new WCItem(api);
+ PostStatuses = new WCItem(api);
+ Settings = new WPSettingItem(api);
+ }
+
+ public WPPostItem Post { get; protected set; }
+
+ public WCItem Categories { get; protected set; }
+
+ public WCItem Tags { get; protected set; }
+
+ public WCItem Pages { get; protected set; }
+
+ public WCItem Comments { get; protected set; }
+
+ public WCItem Taxonomies { get; protected set; }
+
+ public WPMediaItem Media { get; protected set; }
+
+ public WCItem Users { get; protected set; }
+
+ public WCItem PostTypes { get; protected set; }
+
+ public WCItem PostStatuses { get; protected set; }
+
+ public WPSettingItem Settings { get; protected set; }
+
+ public class WPPostItem : WCItem
+ {
+ public WPPostItem(RestAPI api) : base(api)
+ {
+ API = api;
+
+ Revisions = new WCSubItem(api, APIEndpoint);
+ }
+
+ public WCSubItem Revisions { get; set; }
+ }
+
+ public class WPMediaItem : WCItem
+ {
+ public WPMediaItem(RestAPI api) : base(api)
+ {
+ API = api;
+ }
+
+ public async Task Add(string fileName, string filePath)
+ {
+ Dictionary ps = new Dictionary();
+ ps.Add("name", fileName);
+ ps.Add("path", filePath);
+
+ return API.DeserializeJSon(await API.PostRestful(APIEndpoint, "fileupload", ps).ConfigureAwait(false));
+ }
+ }
+
+ public class WPSettingItem : WCItem
+ {
+ public WPSettingItem(RestAPI api) : base(api)
+ {
+ API = api;
+ }
+
+ public async Task Get(Dictionary parms = null)
+ {
+ return API.DeserializeJSon(await API.GetRestful(APIEndpoint, parms).ConfigureAwait(false));
+ }
+ }
+ }
+
+ public class WPObject: WPObject
+ {
+ public WPObject(RestAPI api) : base(api)
+ {
+ }
+ }
+
+ public class Plugins
+ {
+ public static string Endpoint { get { return "plugins"; } }
+ }
+}
+
+namespace WooCommerce.NET.WordPress.v2.Extension
+{
+ public static class WPExtension
+ {
+ public static async Task WithCancellation(this Task task, CancellationToken cancellationToken)
+ {
+ var tcs = new TaskCompletionSource();
+ using (cancellationToken.Register(() => tcs.TrySetResult(true)))
+ if (task != await Task.WhenAny(task, tcs.Task))
+ throw new OperationCanceledException(cancellationToken);
+ return await task;
+ }
+
+ public static async Task WithCancellation(this Task task, CancellationToken cancellationToken)
+ {
+ var tcs = new TaskCompletionSource();
+ using (cancellationToken.Register(() => tcs.TrySetResult(true)))
+ if (task != await Task.WhenAny(task, tcs.Task))
+ throw new OperationCanceledException(cancellationToken);
+ await task;
+ }
+
+ }
+}
\ No newline at end of file