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