Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 53 additions & 0 deletions WordPress/Classes/Networking/Remote Objects/RemoteTaxonomyPaging.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#import <Foundation/Foundation.h>

typedef NS_ENUM(NSUInteger, RemoteTaxonomyPagingResultsOrder) {
RemoteTaxonomyPagingOrderAscending = 0,
RemoteTaxonomyPagingOrderDescending
};

typedef NS_ENUM(NSUInteger, RemoteTaxonomyPagingResultsOrdering) {
/* Order the results by the name of the taxonomy.
*/
RemoteTaxonomyPagingResultsOrderingByName = 0,
/* Order the results by the number of posts associated with the taxonomy.
*/
RemoteTaxonomyPagingResultsOrderingByCount
};


/**
@class RemoteTaxonomyPaging
@brief A paging object for passing parameters to the API when requesting paged lists of taxonomies.
See each remote API for specifics regarding default values and limits.
WP.com/REST Jetpack: https://developer.wordpress.com/docs/api/1.1/get/sites/%24site/categories/
XML-RPC: https://codex.wordpress.org/XML-RPC_WordPress_API/Taxonomies
*/
@interface RemoteTaxonomyPaging : NSObject

/**
@brief The max number of taxonomies to return.
*/

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Documentation comments need the /** opener vs /*

@property (nonatomic, strong) NSNumber *number;

/**
@brief 0-indexed offset for paging.
*/
@property (nonatomic, strong) NSNumber *offset;

/**
@brief Return the Nth 1-indexed page of tags. Takes precedence over the offset parameter.
@attention Not supported in XML-RPC.
*/
@property (nonatomic, strong) NSNumber *page;

/**
@brief Return the taxonomies in ascending or descending order. Defaults YES via the API.
*/
@property (nonatomic, assign) RemoteTaxonomyPagingResultsOrder order;

/**
@brief Return the taxonomies ordering by name or associated count.
*/
@property (nonatomic, assign) RemoteTaxonomyPagingResultsOrdering orderBy;

@end
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#import "RemoteTaxonomyPaging.h"

@implementation RemoteTaxonomyPaging

@end
38 changes: 32 additions & 6 deletions WordPress/Classes/Networking/TaxonomyServiceRemote.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,52 @@

@class RemotePostCategory;
@class RemotePostTag;
@class RemoteTaxonomyPaging;

/*
Interface for requesting taxonomy such as tags and categories on a site.
/* Interface for requesting taxonomy such as tags and categories on a site.
*/
@protocol TaxonomyServiceRemote <NSObject>

/* Create a new category with the site.
*/
- (void)createCategory:(RemotePostCategory *)category
success:(void (^)(RemotePostCategory *category))success
failure:(void (^)(NSError *error))failure;

/* Fetch a list of categories associated with the site.
* Note: Requests no paging parameters via the API defaulting the response.
*/
- (void)getCategoriesWithSuccess:(void (^)(NSArray <RemotePostCategory *> *categories))success
failure:(void (^)(NSError *error))failure;

/* Create a new category with the site.
/* Fetch a list of categories associated with the site with paging.
*/
- (void)createCategory:(RemotePostCategory *)category
success:(void (^)(RemotePostCategory *category))success
failure:(void (^)(NSError *error))failure;
- (void)getCategoriesWithPaging:(RemoteTaxonomyPaging *)paging
success:(void (^)(NSArray <RemotePostCategory *> *categories))success
failure:(void (^)(NSError *error))failure;

/* Fetch a list of categories whose names or slugs match the provided search query. Case-insensitive.
*/
- (void)searchCategoriesWithName:(NSString *)nameQuery
success:(void (^)(NSArray <RemotePostCategory *> *categories))success
failure:(void (^)(NSError *error))failure;

/* Fetch a list of tags associated with the site.
* Note: Requests no paging parameters via the API defaulting the response.
*/
- (void)getTagsWithSuccess:(void (^)(NSArray <RemotePostTag *> *tags))success
failure:(void (^)(NSError *error))failure;

/* Fetch a list of tags associated with the site with paging.
*/
- (void)getTagsWithPaging:(RemoteTaxonomyPaging *)paging
success:(void (^)(NSArray <RemotePostTag *> *tags))success
failure:(void (^)(NSError *error))failure;

/* Fetch a list of tags whose names or slugs match the provided search query. Case-insensitive.
*/
- (void)searchTagsWithName:(NSString *)nameQuery
success:(void (^)(NSArray <RemotePostTag *> *tags))success
failure:(void (^)(NSError *error))failure;

@end
222 changes: 178 additions & 44 deletions WordPress/Classes/Networking/TaxonomyServiceRemoteREST.m
Original file line number Diff line number Diff line change
Expand Up @@ -2,76 +2,167 @@
#import "WordPressComApi.h"
#import "RemotePostCategory.h"
#import "RemotePostTag.h"
#import "RemoteTaxonomyPaging.h"

static NSString * const TaxonomyRESTCategoryIdentifier = @"categories";
static NSString * const TaxonomyRESTTagIdentifier = @"tags";

static NSString * const TaxonomyRESTIDParameter = @"ID";
static NSString * const TaxonomyRESTNameParameter = @"name";
static NSString * const TaxonomyRESTSlugParameter = @"slug";
static NSString * const TaxonomyRESTParentParameter = @"parent";
static NSString * const TaxonomyRESTSearchParameter = @"search";
static NSString * const TaxonomyRESTOrderParameter = @"order";
static NSString * const TaxonomyRESTOrderByParameter = @"order_by";
static NSString * const TaxonomyRESTNumberParameter = @"number";
static NSString * const TaxonomyRESTOffsetParameter = @"offset";
static NSString * const TaxonomyRESTPageParameter = @"page";

@implementation TaxonomyServiceRemoteREST

#pragma mark - categories

- (void)getCategoriesWithSuccess:(void (^)(NSArray <RemotePostCategory *> *))success
failure:(void (^)(NSError *))failure
{
NSString *path = [NSString stringWithFormat:@"sites/%@/categories?context=edit", self.siteID];
NSString *requestUrl = [self pathForEndpoint:path
withVersion:ServiceRemoteRESTApiVersion_1_1];

[self.api GET:requestUrl
parameters:nil
success:^(AFHTTPRequestOperation *operation, id responseObject) {
if (success) {
success([self remoteCategoriesWithJSONArray:[responseObject arrayForKey:@"categories"]]);
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
if (failure) {
failure(error);
}
}];
}

- (void)createCategory:(RemotePostCategory *)category
success:(void (^)(RemotePostCategory *))success
failure:(void (^)(NSError *))failure
{
NSParameterAssert(category.name.length > 0);
NSString *path = [NSString stringWithFormat:@"sites/%@/categories/new?context=edit", self.siteID];
NSString *requestUrl = [self pathForEndpoint:path
withVersion:ServiceRemoteRESTApiVersion_1_1];

NSMutableDictionary *parameters = [NSMutableDictionary dictionary];
parameters[@"name"] = category.name;
parameters[TaxonomyRESTNameParameter] = category.name;
if (category.parentID) {
parameters[@"parent"] = category.parentID;
parameters[TaxonomyRESTParentParameter] = category.parentID;
}

[self createTaxonomyWithType:TaxonomyRESTCategoryIdentifier
parameters:parameters
success:^(NSDictionary *taxonomyDictionary) {
RemotePostCategory *receivedCategory = [self remoteCategoryWithJSONDictionary:taxonomyDictionary];
if (success) {
success(receivedCategory);
}
} failure:failure];
}

- (void)getCategoriesWithSuccess:(void (^)(NSArray <RemotePostCategory *> *))success
failure:(void (^)(NSError *))failure
{
[self getCategoriesWithPaging:nil
success:success
failure:failure];
}

- (void)getCategoriesWithPaging:(RemoteTaxonomyPaging *)paging
success:(void (^)(NSArray <RemotePostCategory *> *categories))success
failure:(void (^)(NSError *error))failure
{
[self getTaxonomyWithType:TaxonomyRESTCategoryIdentifier
parameters:[self parametersForPaging:paging]
success:^(NSDictionary *responseObject) {
if (success) {
success([self remoteCategoriesWithJSONArray:[responseObject arrayForKey:TaxonomyRESTCategoryIdentifier]]);
}
} failure:failure];
}

- (void)searchCategoriesWithName:(NSString *)nameQuery
success:(void (^)(NSArray <RemotePostCategory *> *tags))success
failure:(void (^)(NSError *error))failure
{
NSParameterAssert(nameQuery.length > 0);
[self getTaxonomyWithType:TaxonomyRESTCategoryIdentifier
parameters:@{TaxonomyRESTSearchParameter: nameQuery}
success:^(NSDictionary *responseObject) {
if (success) {
success([self remoteCategoriesWithJSONArray:[responseObject arrayForKey:TaxonomyRESTCategoryIdentifier]]);
}
} failure:failure];
}

#pragma mark - tags

- (void)getTagsWithSuccess:(void (^)(NSArray <RemotePostTag *> *tags))success
failure:(void (^)(NSError *error))failure
{
[self getTagsWithPaging:nil
success:success
failure:failure];
}

- (void)getTagsWithPaging:(RemoteTaxonomyPaging *)paging
success:(void (^)(NSArray <RemotePostTag *> *tags))success
failure:(void (^)(NSError *error))failure
{
[self getTaxonomyWithType:TaxonomyRESTTagIdentifier
parameters:[self parametersForPaging:paging]
success:^(NSDictionary *responseObject) {
if (success) {
success([self remoteTagsWithJSONArray:[responseObject arrayForKey:TaxonomyRESTTagIdentifier]]);
}
} failure:failure];
}

- (void)searchTagsWithName:(NSString *)nameQuery
success:(void (^)(NSArray <RemotePostTag *> *tags))success
failure:(void (^)(NSError *error))failure
{
NSParameterAssert(nameQuery.length > 0);
[self getTaxonomyWithType:TaxonomyRESTTagIdentifier
parameters:@{TaxonomyRESTSearchParameter: nameQuery}
success:^(NSDictionary *responseObject) {
if (success) {
success([self remoteTagsWithJSONArray:[responseObject arrayForKey:TaxonomyRESTTagIdentifier]]);
}
} failure:failure];
}

#pragma mark - default methods

- (void)createTaxonomyWithType:(NSString *)typeIdentifier
parameters:(NSDictionary *)parameters
success:(void (^)(NSDictionary *taxonomyDictionary))success
failure:(void (^)(NSError *error))failure
{
NSString *path = [NSString stringWithFormat:@"sites/%@/%@/new?context=edit", self.siteID, typeIdentifier];
NSString *requestUrl = [self pathForEndpoint:path withVersion:ServiceRemoteRESTApiVersion_1_1];

[self.api POST:requestUrl
parameters:parameters
success:^(AFHTTPRequestOperation *operation, id responseObject) {
RemotePostCategory *receivedCategory = [self remoteCategoryWithJSONDictionary:responseObject];
success:^(AFHTTPRequestOperation * _Nonnull operation, id _Nonnull responseObject) {
NSAssert([responseObject isKindOfClass:[NSDictionary class]], @"responseObject should be a dictionary");
if (![responseObject isKindOfClass:[NSDictionary class]]) {
responseObject = nil;
}
if (success) {
success(receivedCategory);
success(responseObject);
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
} failure:^(AFHTTPRequestOperation * _Nullable operation, NSError * _Nonnull error) {
if (failure) {
failure(error);
}
}];
}

#pragma mark - tags

- (void)getTagsWithSuccess:(void (^)(NSArray <RemotePostTag *> *tags))success
failure:(void (^)(NSError *error))failure
- (void)getTaxonomyWithType:(NSString *)typeIdentifier
parameters:(id)parameters
success:(void (^)(NSDictionary *responseObject))success
failure:(void (^)(NSError *error))failure
{
NSString *path = [NSString stringWithFormat:@"sites/%@/tags?context=edit", self.siteID];
NSString *path = [NSString stringWithFormat:@"sites/%@/%@?context=edit", self.siteID, typeIdentifier];
NSString *requestUrl = [self pathForEndpoint:path
withVersion:ServiceRemoteRESTApiVersion_1_1];

[self.api GET:requestUrl
parameters:nil
success:^(AFHTTPRequestOperation *operation, id responseObject) {
parameters:parameters
success:^(AFHTTPRequestOperation * _Nonnull operation, id _Nonnull responseObject) {
NSAssert([responseObject isKindOfClass:[NSDictionary class]], @"responseObject should be a dictionary");
if (![responseObject isKindOfClass:[NSDictionary class]]) {
responseObject = nil;
}
if (success) {
success([self remoteTagsWithJSONArray:[responseObject arrayForKey:@"tags"]]);
success(responseObject);
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
} failure:^(AFHTTPRequestOperation * _Nullable operation, NSError * _Nonnull error) {
if (failure) {
failure(error);
}
Expand All @@ -89,10 +180,14 @@ - (void)getTagsWithSuccess:(void (^)(NSArray <RemotePostTag *> *tags))success

- (RemotePostCategory *)remoteCategoryWithJSONDictionary:(NSDictionary *)jsonCategory
{
if (!jsonCategory) {
return nil;
}

RemotePostCategory *category = [RemotePostCategory new];
category.categoryID = [jsonCategory numberForKey:@"ID"];
category.name = [jsonCategory stringForKey:@"name"];
category.parentID = [jsonCategory numberForKey:@"parent"];
category.categoryID = [jsonCategory numberForKey:TaxonomyRESTIDParameter];
category.name = [jsonCategory stringForKey:TaxonomyRESTNameParameter];
category.parentID = [jsonCategory numberForKey:TaxonomyRESTParentParameter];
return category;
}

Expand All @@ -105,11 +200,50 @@ - (RemotePostCategory *)remoteCategoryWithJSONDictionary:(NSDictionary *)jsonCat

- (RemotePostTag *)remoteTagWithJSONDictionary:(NSDictionary *)jsonTag
{
if (!jsonTag) {
return nil;
}

RemotePostTag *tag = [RemotePostTag new];
tag.tagID = [jsonTag numberForKey:@"ID"];
tag.name = [jsonTag stringForKey:@"name"];
tag.slug = [jsonTag stringForKey:@"slug"];
tag.tagID = [jsonTag numberForKey:TaxonomyRESTIDParameter];
tag.name = [jsonTag stringForKey:TaxonomyRESTNameParameter];
tag.slug = [jsonTag stringForKey:TaxonomyRESTSlugParameter];
return tag;
}

- (NSDictionary *)parametersForPaging:(RemoteTaxonomyPaging *)paging
{
if (!paging) {
return nil;
}

NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];

if (paging.number) {
[dictionary setObject:paging.number forKey:TaxonomyRESTNumberParameter];
}

if (paging.offset) {
[dictionary setObject:paging.offset forKey:TaxonomyRESTOffsetParameter];
}

if (paging.page) {
[dictionary setObject:paging.page forKey:TaxonomyRESTPageParameter];
}

if (paging.order == RemoteTaxonomyPagingOrderAscending) {
[dictionary setObject:@"ASC" forKey:TaxonomyRESTOrderParameter];
} else if (paging.order == RemoteTaxonomyPagingOrderDescending) {
[dictionary setObject:@"DESC" forKey:TaxonomyRESTOrderParameter];
}

if (paging.orderBy == RemoteTaxonomyPagingResultsOrderingByName) {
[dictionary setObject:@"name" forKey:TaxonomyRESTOrderByParameter];
} else if (paging.orderBy == RemoteTaxonomyPagingResultsOrderingByCount) {
[dictionary setObject:@"count" forKey:TaxonomyRESTOrderByParameter];
}

return dictionary.count ? dictionary : nil;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe constants for order_by, order, etc.

}

@end
Loading