bitbucket -> github

master
Gnieark 7 years ago
parent 9cfdde525f
commit e78c32b69e

@ -10,6 +10,13 @@ Real time code repository is https://bitbucket.org/gnieark/dc-rest-api
Make a zip of this repository and install it on your Dotclear Blog.
# Known bugs
If your dotclear use the query_strings URLS and there are some filters in query...
So URL is somthing like index.php?rest/{something}/{someting}?filter1=value1
The integrated Swaggers API fails to generate the correct URL. However API Works.
# License
Dotclear rest/json plugin.

@ -15,7 +15,7 @@ $this->registerModule(
/* Name */ "rest",
/* Description*/ "A JSON/REST API for Dotclear",
/* Author */ "Gnieark (hope some others contributors)",
/* Version */ '0.0.1',
/* Version */ '0.0.2',
array(
'permissions' => 'usage,contentadmin',
'type' => 'plugin',

@ -15,3 +15,9 @@ $__autoload['ResQueryDeleteBlogs'] = dirname(__FILE__).'/inc/class.rest.query.de
$__autoload['RestQueryGetBlogSettings'] = dirname(__FILE__).'/inc/class.rest.query.get.blog.settings.php';
$__autoload['RestQueryPostBlogSettings'] = dirname(__FILE__).'/inc/class.rest.query.post.blog.settings.php';
$__autoload['RestQueryDeleteBlogSettings'] = dirname(__FILE__).'/inc/class.rest.query.delete.blog.settings.php';
$__autoload['RestQueryGetPosts'] = dirname(__FILE__).'/inc/class.rest.query.get.posts.php';
$__autoload['RestQueryGetPost'] = dirname(__FILE__).'/inc/class.rest.query.get.post.php';
$__autoload['RestQueryPostPost'] = dirname(__FILE__).'/inc/class.rest.query.post.post.php';
$__autoload['RestQueryPostCategories'] = dirname(__FILE__).'/inc/class.rest.query.post.categories.php';
$__autoload['RestQueryPostMetas'] = dirname(__FILE__).'/inc/class.rest.query.post.metas.php';

@ -17,33 +17,33 @@ class rest extends dcUrlHandlers
//définir la methode API (pas HTML) appelée
switch($httpMethod){
case "GET":
if($args == 'blogs'){
if($args == 'blogs')
return new RestQueryGetBlogs();
break;
}elseif($args == 'specs'){
elseif($args == 'specs')
return new RestQueryGetSpecs();
break;
}elseif(preg_match('/^blogs\/(.*)$/', $args )){
///blogs/{blog-id}
elseif(preg_match('/^blogs\/(.*)$/', $args ))
return new RestQueryGetBlog($args);
break;
}elseif(preg_match('/^(.*)\/settings$/', $args )){
elseif(preg_match('/^(.*)\/settings$/', $args ))
return new RestQueryGetBlogSettings($args);
break;
}elseif(preg_match('/^(.*)\/settings\/(.*)$/', $args )){
elseif(preg_match('/^(.*)\/settings\/(.*)$/', $args ))
return new RestQueryGetBlogSettings($args);
break;
}
elseif(preg_match('/^(.*)\/posts$/', $args ))
return new RestQueryGetPosts($args);
elseif(preg_match('/^(.*)\/post\/(.*)$/', $args ))
return new RestQueryGetPost($args);
break;
case "POST":
if($args == 'blogs'){
if($args == 'blogs')
return new RestQueryPostBlogs($body);
}elseif(preg_match('/^(.*)\/settings\/(.*)$/', $args )){
elseif(preg_match('/^(.*)\/settings\/(.*)$/', $args ))
return new RestQueryPostBlogSettings($args,$body);
break;
}
elseif(preg_match('/^(.*)\/post$/', $args ))
return new RestQueryPostPost($args,$body);
elseif(preg_match('/^(.*)\/categories$/', $args ))
return new RestQueryPostCategories($args,$body);
elseif(preg_match('/^(.*)\/metas$/', $args ))
return new RestQueryPostMetas($args,$body);
break;
case "PUT":
if(preg_match('/^blogs\/(.*)$/', $args )){

@ -224,8 +224,8 @@ paths:
schema:
$ref: '#/definitions/Error'
post:
summary: Create a new namespace and or a new setting'
description: "Let body empty if you just want to create a namespace without setting."
summary: Create or edit a new namespace and or a new setting'
description: "Let body empty if you just want to create a namespace without setting. Note that if the setting already exists, it will be erased. So, PUT and PATCH methods are useless."
parameters:
- name: x_dc_key
in: header
@ -295,20 +295,59 @@ paths:
in: path
type: string
required: true
- name: filters
- name: limit-start
in: query
description: sql like filters
type: array
items:
type: string
required: false
- name: fields
type: integer
- name: limit-count
in: query
type: array
items:
type: string
type: integer
required: false
- name: cat_id
in: query
type: string
required: false
description: 'Fields you want to get. If unset, fields are post_id, post_url, post_status, post_title, post_date'
- name: post_status
type: string
in: query
required: false
- name: password
type: string
in: query
required: false
- name: post_selected
type: boolean
in: query
required: false
- name: post_open_comment
type: boolean
in: query
required: false
- name: post_open_tb
type: boolean
in: query
required: false
- name: post_month
type: string
in: query
required: false
- name: post_year
type: string
in: query
required: false
- name: post_lang
type: string
in: query
required: false
- name: post_format
type: string
in: query
required: false
- name: sortby
type: string
in: query
required: false
description: If many, separate them by a comma
responses:
'200':
description: list of posts
@ -321,6 +360,7 @@ paths:
description: Unexpected error
schema:
$ref: '#/definitions/Error'
'/{blog-id}/post':
post:
summary: Create a new post
parameters:
@ -334,7 +374,7 @@ paths:
required: true
- name: properties
in: body
description: Some non required fields you don't define will be set (default value) by the API
description: Some non required fields you don't define will be set (default value) by the API. You can post many posts once by putting them on an array like [{'post_title':'blah',...},{'post_title':'bluh',...}]
schema:
$ref: '#/definitions/new_dc_post'
responses:
@ -346,7 +386,7 @@ paths:
description: Unexpected error
schema:
$ref: '#/definitions/Error'
'/{blog-id}/posts/{post-id}':
'/{blog-id}/post/{post-id}':
get:
summary: Get a post entry
parameters:
@ -362,13 +402,6 @@ paths:
in: path
type: string
required: true
- name: filters
in: query
description: sql like filters
type: array
items:
type: string
required: false
- name: fields
in: query
type: array
@ -386,7 +419,7 @@ paths:
schema:
$ref: '#/definitions/Error'
patch:
summary: Update part of a post entry's properties
summary: Not yet developed Update part of a post entry's properties
parameters:
- name: x_dc_key
in: header
@ -416,7 +449,7 @@ paths:
schema:
$ref: '#/definitions/Error'
put:
summary: Update full blog properties. Unsetted parameters will be erased
summary: Not yet developed Update full blog properties. Unsetted parameters will be erased
parameters:
- name: x_dc_key
in: header
@ -446,7 +479,7 @@ paths:
schema:
$ref: '#/definitions/Error'
delete:
summary: Delete the post
summary: Not yet developed Delete the post
parameters:
- name: x_dc_key
in: header
@ -471,9 +504,68 @@ paths:
description: Unexpected error
schema:
$ref: '#/definitions/Error'
'/{blog-id}/metas':
post:
summary: Create a new Postr meta
parameters:
- name: x_dc_key
in: header
type: string
required: false
- name: blog-id
in: path
type: string
required: true
- name: properties
in: body
schema:
$ref: '#/definitions/new_meta'
responses:
'200':
description: New meta id
schema:
title: categories
type: array
items:
$ref: '#/definitions/category'
default:
description: Unexpected error
schema:
$ref: '#/definitions/Error'
'/{blog-id}/{post-id}/metas':
get:
summary: get metas for a post
parameters:
- name: x_dc_key
in: header
type: string
required: false
- name: blog-id
in: path
type: string
required: true
- name: post-id
in: path
type: integer
required: true
responses:
'200':
description: New meta id
schema:
title: categories
type: array
items:
$ref: '#/definitions/metas'
default:
description: Unexpected error
schema:
$ref: '#/definitions/Error'
'/{blog-id}/categories':
get:
summary: Get list of available categories
summary: Not yet developed Get list of available categories
parameters:
- name: x_dc_key
in: header
@ -521,7 +613,7 @@ paths:
$ref: '#/definitions/Error'
'/{blog-id}/categories/{cat-id}':
get:
summary: get one category properties
summary: Not yet developed get one category properties
parameters:
- name: x_dc_key
in: header
@ -545,7 +637,7 @@ paths:
schema:
$ref: '#/definitions/Error'
patch:
summary: Update some attributes
summary: Not yet developed Update some attributes
parameters:
- name: blog-id
in: path
@ -633,7 +725,19 @@ definitions:
type: string
blog_desc:
type: string
new_meta:
required:
- meta_id
- meta_type
- post_id
type: object
properties:
meta_id:
type: string
meta_type:
type: string
post_id:
type: integer
blogProperties:
type: object
properties:
@ -648,126 +752,151 @@ definitions:
new_dc_post:
type: object
required:
- post_format
- post_status
- post_content
- post_title
properties:
cat_id:
post_title:
type: string
post_dt:
post_format:
type: string
post_tz:
description: generally 'xhtml' or 'wiki'. If you put another value, not managed by Dotclear or a plugin, Fill in the post_content_xhtml field.
post_content:
type: string
post_creadt:
description: The content on WhatYouWant format
post_content_xhtml:
type: string
post_upddt:
description: If post_format is wiki or xhtml and not set, It will be generated from post_content
post_status:
type: string
post_password:
enum:
- Pending
- Scheduled
- Unpublished
- Published
cat_id:
type: integer
new_cat_id:
type: string
description: If creating a new category, this is the only required cat_ field. If given cat_id must not be given
new_cat_parent_id:
type: integer
description: Only if new_cat_id is given
new_cat_desc:
type: string
post_type:
description: the new category description.
new_cat_url:
type: string
post_format:
description: the new category url
post_dt:
type: string
description: \'YY-MM-dd hh:mm:ss\' If not set, Current dateTime will be used.
post_password:
type: string
description: Don\'t set that value if your new post won\'t be protected
post_url:
type: string
description: If not set, will be created using the date and the post_titlke
post_lang:
type: string
post_title:
type: string
description: If not set, User lang will be used
post_excerpt:
type: string
post_excerpt_xhtml:
type: string
post_content:
type: string
post_content_xhtml:
type: string
description: If post_format is wiki or xhtml, It will be generated from post_excerpt
post_notes:
type: string
post_meta:
type: string
post_words:
type: string
post_status:
type: string
enum:
- Pending
- Scheduled
- Unpublished
- Published
post_selected:
type: boolean
post_position:
type: string
post_open_comment:
type: boolean
post_open_tb:
type: boolean
post_tags:
type: array
description: post tags
dc_post:
type: object
properties:
post_id:
type: string
blog_id:
post_title:
type: string
user_id:
post_format:
type: string
cat_id:
description: generally 'xhtml' or 'wiki'. If you put another value, not managed by Dotclear or a plugin, Fill in the post_content_xhtml field.
post_content:
type: string
post_dt:
description: The content on WhatYouWant format
post_content_xhtml:
type: string
post_tz:
description: If post_format is wiki or xhtml and not set, It will be generated from post_content
post_status:
type: string
post_creadt:
enum:
- Pending
- Scheduled
- Unpublished
- Published
cat_id:
type: integer
new_cat_id:
type: string
post_upddt:
description: If creating a new category, this is the only required cat_ field. If given cat_id must not be given
new_cat_parent_id:
type: integer
description: Only if new_cat_id is given
new_cat_desc:
type: string
post_password:
description: the new category description.
new_cat_url:
type: string
post_type:
description: the new category url
post_dt:
type: string
post_format:
description: \'YY-MM-dd hh:mm:ss\' If not set, Current dateTime will be used.
post_password:
type: string
description: Don\'t set that value if your new post won\'t be protected
post_url:
type: string
description: If not set, will be created using the date and the post_titlke
post_lang:
type: string
post_title:
type: string
description: If not set, User lang will be used
post_excerpt:
type: string
post_excerpt_xhtml:
type: string
post_content:
type: string
post_content_xhtml:
type: string
description: If post_format is wiki or xhtml, It will be generated from post_excerpt
post_notes:
type: string
post_meta:
type: string
post_words:
type: string
post_status:
type: string
enum:
- Pending
- Scheduled
- Unpublished
- Published
post_selected:
type: boolean
post_position:
type: string
post_open_comment:
type: boolean
post_open_tb:
type: boolean
post_tags:
type: array
description: post tags
nb_comment:
type: integer
nb_trackback:
type: integer
post_firstpub:
type: string
metas:
type: array
items:
type: object
metas:
type: array
items:
type: object
category:
type: object
properties:
@ -781,6 +910,8 @@ definitions:
type: string
cat_position:
type: integer
cat_parent_id:
type: integer
temporary:
type: boolean
new_category:
@ -794,6 +925,8 @@ definitions:
type: string
cat_desc:
type: string
cat_parent_id:
type: integer
cat_position:
type: integer
temporary:
@ -807,4 +940,4 @@ definitions:
message:
type: string
fields:
type: string
type: string

Before

Width:  |  Height:  |  Size: 445 B

After

Width:  |  Height:  |  Size: 445 B

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

@ -339,8 +339,8 @@
}
},
"post": {
"summary": "Create a new namespace and or a new setting'",
"description": "Let body empty if you just want to create a namespace without setting.",
"summary": "Create or edit a new namespace and or a new setting'",
"description": "Let body empty if you just want to create a namespace without setting. Note that if the setting already exists, it will be erased. So, PUT and PATCH methods are useless.",
"parameters": [
{
"name": "x_dc_key",
@ -445,24 +445,83 @@
"required": true
},
{
"name": "filters",
"name": "limit-start",
"in": "query",
"description": "sql like filters",
"type": "array",
"items": {
"type": "string"
},
"required": false,
"type": "integer"
},
{
"name": "limit-count",
"in": "query",
"type": "integer",
"required": false
},
{
"name": "fields",
"name": "cat_id",
"in": "query",
"type": "string",
"required": false
},
{
"name": "post_status",
"type": "string",
"in": "query",
"required": false
},
{
"name": "password",
"type": "string",
"in": "query",
"required": false
},
{
"name": "post_selected",
"type": "boolean",
"in": "query",
"required": false
},
{
"name": "post_open_comment",
"type": "boolean",
"in": "query",
"required": false
},
{
"name": "post_open_tb",
"type": "boolean",
"in": "query",
"required": false
},
{
"name": "post_month",
"type": "string",
"in": "query",
"required": false
},
{
"name": "post_year",
"type": "string",
"in": "query",
"required": false
},
{
"name": "post_lang",
"type": "string",
"in": "query",
"required": false
},
{
"name": "post_format",
"type": "string",
"in": "query",
"required": false
},
{
"name": "sortby",
"type": "string",
"in": "query",
"type": "array",
"items": {
"type": "string"
},
"required": false,
"description": "Fields you want to get. If unset, fields are post_id, post_url, post_status, post_title, post_date"
"description": "If many, separate them by a comma"
}
],
"responses": {
@ -483,7 +542,9 @@
}
}
}
},
}
},
"/{blog-id}/post": {
"post": {
"summary": "Create a new post",
"parameters": [
@ -502,7 +563,7 @@
{
"name": "properties",
"in": "body",
"description": "Some non required fields you don't define will be set (default value) by the API",
"description": "Some non required fields you don't define will be set (default value) by the API. You can post many posts once by putting them on an array like [{'post_title':'blah',...},{'post_title':'bluh',...}]",
"schema": {
"$ref": "#/definitions/new_dc_post"
}
@ -524,7 +585,7 @@
}
}
},
"/{blog-id}/posts/{post-id}": {
"/{blog-id}/post/{post-id}": {
"get": {
"summary": "Get a post entry",
"parameters": [
@ -546,16 +607,6 @@
"type": "string",
"required": true
},
{
"name": "filters",
"in": "query",
"description": "sql like filters",
"type": "array",
"items": {
"type": "string"
},
"required": false
},
{
"name": "fields",
"in": "query",
@ -583,7 +634,7 @@
}
},
"patch": {
"summary": "Update part of a post entry's properties",
"summary": "Not yet developed Update part of a post entry's properties",
"parameters": [
{
"name": "x_dc_key",
@ -630,7 +681,7 @@
}
},
"put": {
"summary": "Update full blog properties. Unsetted parameters will be erased",
"summary": "Not yet developed Update full blog properties. Unsetted parameters will be erased",
"parameters": [
{
"name": "x_dc_key",
@ -677,7 +728,7 @@
}
},
"delete": {
"summary": "Delete the post",
"summary": "Not yet developed Delete the post",
"parameters": [
{
"name": "x_dc_key",
@ -717,9 +768,96 @@
}
}
},
"/{blog-id}/metas": {
"post": {
"summary": "Create a new Postr meta",
"parameters": [
{
"name": "x_dc_key",
"in": "header",
"type": "string",
"required": false
},
{
"name": "blog-id",
"in": "path",
"type": "string",
"required": true
},
{
"name": "properties",
"in": "body",
"schema": {
"$ref": "#/definitions/new_meta"
}
}
],
"responses": {
"200": {
"description": "New meta id",
"schema": {
"title": "categories",
"type": "array",
"items": {
"$ref": "#/definitions/category"
}
}
},
"default": {
"description": "Unexpected error",
"schema": {
"$ref": "#/definitions/Error"
}
}
}
}
},
"/{blog-id}/{post-id}/metas": {
"get": {
"summary": "get metas for a post",
"parameters": [
{
"name": "x_dc_key",
"in": "header",
"type": "string",
"required": false
},
{
"name": "blog-id",
"in": "path",
"type": "string",
"required": true
},
{
"name": "post-id",
"in": "path",
"type": "integer",
"required": true
}
],
"responses": {
"200": {
"description": "New meta id",
"schema": {
"title": "categories",
"type": "array",
"items": {
"$ref": "#/definitions/metas"
}
}
},
"default": {
"description": "Unexpected error",
"schema": {
"$ref": "#/definitions/Error"
}
}
}
}
},
"/{blog-id}/categories": {
"get": {
"summary": "Get list of available categories",
"summary": "Not yet developed Get list of available categories",
"parameters": [
{
"name": "x_dc_key",
@ -794,7 +932,7 @@
},
"/{blog-id}/categories/{cat-id}": {
"get": {
"summary": "get one category properties",
"summary": "Not yet developed get one category properties",
"parameters": [
{
"name": "x_dc_key",
@ -831,7 +969,7 @@
}
},
"patch": {
"summary": "Update some attributes",
"summary": "Not yet developed Update some attributes",
"parameters": [
{
"name": "blog-id",
@ -964,6 +1102,25 @@
}
}
},
"new_meta": {
"required": [
"meta_id",
"meta_type",
"post_id"
],
"type": "object",
"properties": {
"meta_id": {
"type": "string"
},
"meta_type": {
"type": "string"
},
"post_id": {
"type": "integer"
}
}
},
"blogProperties": {
"type": "object",
"properties": {
@ -984,84 +1141,93 @@
"new_dc_post": {
"type": "object",
"required": [
"post_format",
"post_status",
"post_content",
"post_title"
],
"properties": {
"cat_id": {
"post_title": {
"type": "string"
},
"post_dt": {
"type": "string"
"post_format": {
"type": "string",
"description": "generally 'xhtml' or 'wiki'. If you put another value, not managed by Dotclear or a plugin, Fill in the post_content_xhtml field."
},
"post_tz": {
"type": "string"
"post_content": {
"type": "string",
"description": "The content on WhatYouWant format"
},
"post_creadt": {
"type": "string"
"post_content_xhtml": {
"type": "string",
"description": "If post_format is wiki or xhtml and not set, It will be generated from post_content"
},
"post_upddt": {
"type": "string"
"post_status": {
"type": "string",
"enum": [
"Pending",
"Scheduled",
"Unpublished",
"Published"
]
},
"post_password": {
"type": "string"
"cat_id": {
"type": "integer"
},
"post_type": {
"type": "string"
"new_cat_id": {
"type": "string",
"description": "If creating a new category, this is the only required cat_ field. If given cat_id must not be given"
},
"post_format": {
"type": "string"
"new_cat_parent_id": {
"type": "integer",
"description": "Only if new_cat_id is given"
},
"new_cat_desc": {
"type": "string",
"description": "the new category description."
},
"new_cat_url": {
"type": "string",
"description": "the new category url"
},
"post_dt": {
"type": "string",
"description": "\\'YY-MM-dd hh:mm:ss\\' If not set, Current dateTime will be used."
},
"post_password": {
"type": "string",
"description": "Don\\'t set that value if your new post won\\'t be protected"
},
"post_url": {
"type": "string"
"type": "string",
"description": "If not set, will be created using the date and the post_titlke"
},
"post_lang": {
"type": "string"
},
"post_title": {
"type": "string"
"type": "string",
"description": "If not set, User lang will be used"
},
"post_excerpt": {
"type": "string"
},
"post_excerpt_xhtml": {
"type": "string"
},
"post_content": {
"type": "string"
},
"post_content_xhtml": {
"type": "string"
"type": "string",
"description": "If post_format is wiki or xhtml, It will be generated from post_excerpt"
},
"post_notes": {
"type": "string"
},
"post_meta": {
"type": "string"
},
"post_words": {
"type": "string"
},
"post_status": {
"type": "string",
"enum": [
"Pending",
"Scheduled",
"Unpublished",
"Published"
]
},
"post_selected": {
"type": "boolean"
},
"post_position": {
"type": "string"
},
"post_open_comment": {
"type": "boolean"
},
"post_open_tb": {
"type": "boolean"
},
"post_tags": {
"type": "array",
"description": "post tags"
}
}
},
@ -1071,87 +1237,88 @@
"post_id": {
"type": "string"
},
"blog_id": {
"post_title": {
"type": "string"
},
"user_id": {
"type": "string"
"post_format": {
"type": "string",
"description": "generally 'xhtml' or 'wiki'. If you put another value, not managed by Dotclear or a plugin, Fill in the post_content_xhtml field."
},
"cat_id": {
"type": "string"
"post_content": {
"type": "string",
"description": "The content on WhatYouWant format"
},
"post_dt": {
"type": "string"
"post_content_xhtml": {
"type": "string",
"description": "If post_format is wiki or xhtml and not set, It will be generated from post_content"
},
"post_tz": {
"type": "string"
"post_status": {
"type": "string",
"enum": [
"Pending",
"Scheduled",
"Unpublished",
"Published"
]
},
"post_creadt": {
"type": "string"
"cat_id": {
"type": "integer"
},
"post_upddt": {
"type": "string"
"new_cat_id": {
"type": "string",
"description": "If creating a new category, this is the only required cat_ field. If given cat_id must not be given"
},
"post_password": {
"type": "string"
"new_cat_parent_id": {
"type": "integer",
"description": "Only if new_cat_id is given"
},
"post_type": {
"type": "string"
"new_cat_desc": {
"type": "string",
"description": "the new category description."
},
"post_format": {
"type": "string"
"new_cat_url": {
"type": "string",
"description": "the new category url"
},
"post_dt": {
"type": "string",
"description": "\\'YY-MM-dd hh:mm:ss\\' If not set, Current dateTime will be used."
},
"post_password": {
"type": "string",
"description": "Don\\'t set that value if your new post won\\'t be protected"
},
"post_url": {
"type": "string"
"type": "string",
"description": "If not set, will be created using the date and the post_titlke"
},
"post_lang": {
"type": "string"
},
"post_title": {
"type": "string"
"type": "string",
"description": "If not set, User lang will be used"
},
"post_excerpt": {
"type": "string"
},
"post_excerpt_xhtml": {
"type": "string"
},
"post_content": {
"type": "string"
},
"post_content_xhtml": {
"type": "string"
"type": "string",
"description": "If post_format is wiki or xhtml, It will be generated from post_excerpt"
},
"post_notes": {
"type": "string"
},
"post_meta": {
"type": "string"
},
"post_words": {
"type": "string"
},
"post_status": {
"type": "string",
"enum": [
"Pending",
"Scheduled",
"Unpublished",
"Published"
]
},
"post_selected": {
"type": "boolean"
},
"post_position": {
"type": "string"
},
"post_open_comment": {
"type": "boolean"
},
"post_open_tb": {
"type": "boolean"
},
"post_tags": {
"type": "array",
"description": "post tags"
},
"nb_comment": {
"type": "integer"
},
@ -1160,9 +1327,21 @@
},
"post_firstpub": {
"type": "string"
},
"metas": {
"type": "array",
"items": {
"type": "object"
}
}
}
},
"metas": {
"type": "array",
"items": {
"type": "object"
}
},
"category": {
"type": "object",
"properties": {
@ -1181,6 +1360,9 @@
"cat_position": {
"type": "integer"
},
"cat_parent_id": {
"type": "integer"
},
"temporary": {
"type": "boolean"
}
@ -1201,6 +1383,9 @@
"cat_desc": {
"type": "string"
},
"cat_parent_id": {
"type": "integer"
},
"cat_position": {
"type": "integer"
},

@ -1,5 +1,5 @@
<?php
class restDcNameSpace extends dcSettings
class restDcNameSpace extends dcNamespace
{
//this function is private on the parent class
public function settingExists($id,$global=false)

@ -0,0 +1,52 @@
<?php
class RestQueryGetPost extends RestQuery
{
public function __construct($args){
global $core;
$explodedArgs = explode("/",$args);
$this->blog_id = $explodedArgs[0];
$post_id = $explodedArgs[2];
$post = $core->blog->getPosts(array('post_id' => $post_id));
if ($post->isEmpty()) {
$this->response_code = 404;
$this->response_message = array(
'code' => 404,
'error' => 'POST '.$post_id.' does not exists'
);
return;
}
$fieldsKeys= $post->columns();
$postArr = array();
foreach($fieldsKeys as $key){
$postArr[$key] = $post -> $key;
}
//les metas
//getMetadata($params);
$metas = array();
$rs = $core->meta->getMetadata(array('post_id' => $post_id));
//('meta_id' => $meta_id, 'meta_type' => $meta_type, 'post_id' => $post_id);
while($rs->fetch()){
$metas[] = array(
'meta_id' => $rs->meta_id,
'meta_type' => $rs->meta_type
);
}
$postArr['metas'] = $metas;
$this -> response_message = $postArr;
$this -> response_code = 200;
}
}

@ -0,0 +1,101 @@
<?php
class RestQueryGetPosts extends RestQuery
{
//curl -X GET "http://dotclear.localhost/dotclear/index.php?rest/default/posts" -H "accept: application/json" -H "x_dc_key: 1zhoGXv9PA0lvPNG81GUlCNfqT45gVuV"
public function __construct($args)
{
global $core;
$explodedArgs = explode("/",$args);
$this->blog_id = $explodedArgs[0];
$this->required_perms = 'unauth'; //les niveaux d'acces aux contenus sont
//gérés dans la function $core->blog->getPosts($params)
if($core->auth === false){
$core->auth = new restAuth($core); //class dcBlog need it
$unauth = true;
}
$core->blog = new dcBlog($core, $this->blog_id);
$blog_settings = new dcSettings($core,$this->blog_id);
if($this->is_allowed() === false){
return;
}
$params['where'] = '';
if((isset($_GET['limit-start'])) && (isset($_GET['limit-count']))){
$params['limit'] = array($_GET['limit-start'],$_GET['limit-count']);
}elseif((isset($_GET['limit-start'])) xor (isset($_GET['limit-count']))){
$this->response_code = 400;
$this->response_message = array(
'code' => 400,
'message' => 'If you set limits both of limit-start and limit-cout must be setted'
);
return;
}
if(isset($_GET['cat_id'])){
$params['cat_id'] = $_GET['cat_id'];
}
if(isset($_GET['post_status'])){
$params['post_status'] = $_GET['post_status'];
}
if(isset($_GET['password'])){
$params['where'] .= ' AND post_password IS '.($_GET['password'] ? 'NOT ' : '').'NULL ';
}
if(isset($_GET['post_selected'])){
$params['post_selected'] = $_GET['post_selected']; //to do, vérifier, si c'est pris correctement comment un boolean
}
if(isset($_GET['post_open_comment'])){
$params['where'] .= " AND post_open_comment = '".$_GET['post_open_comment']."' ";
}
if(isset($_GET['post_open_tb'])){
$params['where'] .= " AND post_open_tb = '".$_GET['post_open_tb']."' ";
}
//date
if((isset($_GET['post_month'])) && (isset ($_GET['post_year']))){
$params['post_month'] = $_GET['post_month'];
$params['post_year'] = $_GET['post_year'];
}elseif((isset($_GET['post_month'])) xor (isset ($_GET['post_year']))){
$this -> response_code = 400;
$this -> response_message = array(
'code' => 400,
'message' => 'If you set date parameters both of post_month and post_year must be setted'
);
return;
}
if(isset($_GET['format'])){
$params['where'] .= " AND post_format = '".$_GET['format']."' ";
}
if(isset($_GET['sortby'])){
$params['order'] = $_GET['sortby'];
}
$rs = $core->blog->getPosts($params);
$fieldsKeys= $rs->columns();
$response = array();
while ($rs->fetch()) {
$post = array();
foreach($fieldsKeys as $key){
$post[$key] = $rs->$key;
}
$response[] = $post;
}
$this -> response_code = 200;
$this -> response_message = $response;
}
}

@ -0,0 +1,7 @@
<?php
class RestQueryGetPostsById extends RestQuery
{
}

@ -7,18 +7,19 @@ class RestQuery{
protected $required_perms = 'admin'; //must be changed by the childs class
/*
should be:
'admin'
'usage'
'publish'
'delete'
'contentadmin'
'categories'
'media'
'media_admin'
'none' //must be have an account (without any rights)
'admin' administrateur
'usage' gérer ses propres billets et commentaires
'publish' publier des billets et des commentaires
'delete' supprimer des billets et des commentaires
'contentadmin' gérer tous les billets et commentaires
'categories' gérer les catégories
'media' gérer ses propres médias
'media_admin' gérer tous les médias
'none' //must have an account (without any rights)
'unauth' //Open to the world
*/
public function __construct()
{
@ -68,6 +69,7 @@ class RestQuery{
//check if a field is not in required and in fieldsOptionals
foreach($fieldsSetted as $keyToTest){
if((!in_array($keyToTest,$fieldsRequired)) && (!in_array($keyToTest,$fieldsOptionals))){
$this->response_code = 400;
$this->response_message = array(
"error" => "Unwanted field '".$keyToTest."'",
"code" => 400
@ -147,6 +149,51 @@ class RestQuery{
return false;
}
}
/*
* Quand l'API permet à la fois une structure
* {
* key1 : value1,
* key2 : value2
* }
*
* et une structure avec plusieurs enregistrements
* [
* {
* key1 : value1.1,
* key2 : value2.1
* },
* {
* key1 : value1.2,
* key2 : value2.2
* }
*]
*
* Cette function permet de tester quelle structure a un array, et retourne un array sous la deuxième
* structure
*
* IN: $arr L'array à tester
* $keyToTest: string Un nom de clef obligatoire qui servira à tester le type de structrure
*/
public function arrayOfObjetsOrNot($arr,$keyToTest){
try{
if(isset($arr[$keyToTest])){
return array($arr);
}elseif(isset($arr[0][$keyToTest])){
return $arr;
}
}catch (Exception $e){
//parfois ça déconne
if(isset($arr[0][$keyToTest])){
return $arr;
}
}
return false;
}
public function get_full_code_header($code=''){
if($code == ''){
$code = $this->response_code;

@ -0,0 +1,103 @@
<?php
class RestQueryPostCategories extends RestQuery
{
/**
* IN $params array with keys
* OUT integer, the new category id
*/
public function createCategory($params){
global $core;
if(!isset($params['cat_title'])){
return false;
}
try
{
$cur = $core->con->openCursor($core->prefix.'category');
$cur->cat_title = $params['cat_title'];
if (isset($params['cat_desc'])) {
$cur->cat_desc = $params['cat_desc'];
}
if (isset($params['cat_url'])) {
$cur->cat_url = $params['cat_url'];
}else{
$cur->cat_url = '';
}
if(isset($params['cat_parent_id'])){
$cat_parent_id = $params['cat_parent_id'];
}else{
$cat_parent_id = null;
}
# --BEHAVIOR-- adminBeforeCategoryCreate
$core->callBehavior('adminBeforeCategoryCreate',$cur);
$id = $core->blog->addCategory($cur,(integer)$cat_parent_id);
# --BEHAVIOR-- adminAfterCategoryCreate
$core->callBehavior('adminAfterCategoryCreate',$cur,$id);
return $id;
}catch (Exception $e) {
return false;
}
}
public function __construct($args,$body){
global $core;
$explodedArgs = explode("/",$args);
$this->blog_id = $explodedArgs[0];
$this->required_perms = 'none'; //To do
if($core->auth === false){
$core->auth = new restAuth($core); //class dcBlog need it
$unauth = true;
}
$core->blog = new dcBlog($core, $this->blog_id);
$blog_settings = new dcSettings($core,$this->blog_id);
if($this->is_allowed() === false){
return;
}
$clientQueryArr = json_decode($body, true);
if(empty($clientQueryArr)){
$this->response_code = 400;
$this->response_message = array(
'error' => 'Can\'t parse input JSON'.$body,
'code' => 400
);
return;
}
if(!$this->check_for_required_fields(
$clientQueryArr,
array('cat_title'), //required fields
array('cat_url','cat_desc','cat_parent_id','cat_position','temporary') //facultatives fields
)){
return;
}
$id = $this->createCategory($clientQueryArr);
if($id === false){
$this->response_code = 500;
$this->response_message = array(
"error" => "Something is wrong",
"code" => 500
);
}else{
$this->response_code = 200;
$this->response_message = array(
"message" => "Successfully create category",
"id" => $id
);
}
}
}

@ -0,0 +1,89 @@
<?php
/*
*Methode permettant de créer des métas (dont les tags)
*/
class RestQueryPostMetas extends RestQuery
{
/*
* Add a meta
* if already exists, do nothing, does not generate warnings
*/
public function add_meta($meta_id,$meta_type,$post_id){
global $core;
//check if meta already exists
$params = array('meta_id' => $meta_id, 'meta_type' => $meta_type, 'post_id' => $post_id);
$rs = $core->meta->getMetadata($params, false);
if($rs->fetch()){
return $rs->meta_id; //the meta already exists
}elseif($core->meta->setPostMeta($post_id,$meta_type,$meta_id) === false){
return false;
}else{
return $meta_id;
}
}
public function __construct($args,$body)
{
global $core;
$explodedArgs = explode("/",$args);
$this->blog_id = $explodedArgs[0];
$this->required_perms = 'none'; //To do
if($core->auth === false){
$core->auth = new restAuth($core);
$unauth = true;
}
$core->blog = new dcBlog($core, $this->blog_id);
$blog_settings = new dcSettings($core,$this->blog_id);
if($this->is_allowed() === false){
return;
}
$clientQueryArr = json_decode($body, true);
$createdIds = array();
$clientQueryArr = $this->arrayOfObjetsOrNot($clientQueryArr,'meta_id');
foreach($clientQueryArr as $query){
//check for needed fields
if(!$this->check_for_required_fields($query,
array('meta_id','meta_type','post_id'), //required fields
array() //facultatives fields
)){
return;
}
$id = $this -> add_meta($query['meta_id'],$query['meta_type'],$query['post_id']);
if($id === false){
$this->response_code = 500;
$this->response_message = array("code" => 500,
"message" => "An error occured while setting meta ".$query['meta_id']);
return;
}
$createdIds[] = $id;
}
$this->response_code = 201;
if(count($createdIds) == 1){
$this->response_message = array(
"code" => 200,
"message" => "Successfully insert meta",
"id" => $createdIds[0]
);
}else{
$this->response_message = array(
"code" => 200,
"message" => "Successfully insert metas",
"id" => $createdIds
);
}
return;
}
}

@ -0,0 +1,205 @@
<?php
class RestQueryPostPost extends RestQuery{
public function __construct($args,$body){
global $core;
$explodedArgs = explode("/",$args);
$this->blog_id = $explodedArgs[0];
$this->required_perms = 'none'; //To do
if($core->auth === false){
$core->auth = new restAuth($core); //class dcBlog need it
$unauth = true;
}
$core->blog = new dcBlog($core, $this->blog_id);
$blog_settings = new dcSettings($core,$this->blog_id);
if($this->is_allowed() === false){
return;
}
$clientQueryArr = json_decode($body, true);
if(empty($clientQueryArr)){
$this->response_code = 400;
$this->response_message = array(
'error' => 'Can\'t parse input JSON'.$body,
'code' => 400
);
return;
}
//
//tester si plusieurs posts
$allPosts = $this->arrayOfObjetsOrNot($clientQueryArr,'post_title');
//is it valid fields?
foreach($allPosts as $p){
if(!$this->check_for_required_fields(
$p,
array('post_title','post_format','post_content','post_status'), //required fields
array('cat_id','new_cat_id','new_cat_parent','post_dt','post_password',
'post_lang','post_excerpt','post_excerpt_xhtml','post_content_xhtml',
'post_notes','post_selected','post_open_comment','post_open_tb','post_url','post_tags') //facultatives fields
)){
return;
}
}
$createdIds = array();
//end of checks; lets submit new posts
foreach($allPosts as $p){
//gestion de la categorie
if(isset($p['new_cat_id'])){
$params = array();
$params['cat_title'] = $p['new_cat_id'];
if(isset($p['new_cat_parent_id']))
$params['cat_parent_id'] = $p['new_cat_parent_id'];
if(isset($p['new_cat_url']))
$params['cat_url'] = $p['new_cat_url'];
if(isset($p['new_cat_desc']))
$params['cat_desc'] = $p['new_cat_desc'];
$cat_id = RestQueryPostCategories::createCategory($params);
if($cat_id === false){
$this->response_message = 400;
$this->response_message = array(
"error" => "ERROR when creating the new category.",
"code" => 400
);
return;
}
}elseif(isset($p['cat_id'])){
$cat_id = $core->con->escape($p['cat_id']);
}else{
$cat_id = null;
}
$cur = $core->con->openCursor($core->prefix.'post');
$cur->post_title = $core->con->escape($p['post_title']);
$cur->cat_id = $cat_id;
if(isset($p['post_dt']))
$cur->post_dt = $core->con->escape($p['post_dt']);
else
$cur->post_dt = '';
$cur->post_format = $core->con->escape($p['post_format']); //mandatory field
if(isset($p['post_password']))
$cur->post_password = $core->con->escape($p['post_password']);
else
$cur->post_password = null;
if(isset($p['post_lang']))
$cur->post_lang = $core->con->escape($p['post_lang']);
else
$cur->post_lang = '';
$cur->post_title = $core->con->escape($p['post_title']); //mandatory field
if(isset($p['post_excerpt']))
$cur->post_excerpt = $core->con->escape($p['post_excerpt']);
else
$cur->post_excerpt = '';
if(isset($p['post_excerpt_xhtml'])){
$cur->post_excerpt_xhtml = $core->con->escape($p['post_excerpt_xhtml']);
}elseif(($p['post_format'] == 'wiki') && (isset($p['post_excerpt']))) {
$cur->post_excerpt_xhtml = $core->wikiTransform($p['post_excerpt']);
}elseif(($p['post_format'] <> 'wiki') && (!isset($p['post_excerpt']))){
$this->response_message = 400;
$this->response_message = array(
"error" => "ERROR. If not wiki format, give me post_exerpt_xhtml please.",
"code" => 400
);
return;
}
$cur->post_content = $p['post_content']; //mandatory field
if($p['post_format'] == 'xhtml'){
$cur->post_content_xhtml = $core->con->escape($p['post_content']);
}elseif(isset($p['post_content_xhtml'])){
$cur->post_content_xhtml = $core->con->escape($p['post_content_xhtml']);
}elseif($p['post_format'] == 'wiki'){
//convertir le format wiki en html
$cur->post_content_xhtml = $core->wikiTransform($p['post_content']);
}else{
//sortir en erreur
$this->response_code = 400;
$this->response_message = array(
"error" => "ERROR. If not wiki format, give me post_content_xhtml please.",
"code" => 400
);
return;
}
//$cur->post_notes = $post_notes; TO DO
$cur->post_status = $core->con->escape($p['post_status']); //mandatory field
if(isset($p['post_selected']))
$cur->post_selected = (integer) $core->con->escape($p['post_selected']);
else
$cur->post_selected = 0;
if(isset($p['post_open_comment']))
$cur->post_open_comment = (integer)$core->con->escape($p['post_open_comment']);
else
$cur->post_open_comment = 0;
if(isset($p['post_open_tb']))
$cur->post_open_tb = (integer) $core->con->escape($p['post_open_tb']);
else
$cur->post_open_tb = 0;
if(isset($p['post_notes']))
$cur->post_notes = $core->con->escape($p['post_notes']);
$cur->user_id = $core->auth->userID();
try {
# --BEHAVIOR-- adminBeforePostCreate
$core->callBehavior('adminBeforePostCreate',$cur);
$return_id = $core->blog->addPost($cur);
$createdIds[] = $return_id;
# --BEHAVIOR-- adminAfterPostCreate
$core->callBehavior('adminAfterPostCreate',$cur,$return_id);
//les eventuels tags
if(isset($p['post_tags'])){
foreach($p['post_tags'] as $tag){
RestQueryPostMetas::add_meta($tag,'tag',$return_id);
}
}
} catch (Exception $e) {
$this->response_code = 500;
$this->response_message = array(
"code" => 500,
"message" => $e->getMessage(),
);
return;
}
}
$this->response_code = 200;
if(count($createdIds) == 1){
$id = (integer)$createdIds[0];
}else{
$id = $createdIds;
}
$this->response_message = array(
"message" => "Successfully create post(s)",
"id" => $id);
}
}

Before

Width:  |  Height:  |  Size: 675 B

After

Width:  |  Height:  |  Size: 675 B

@ -1,8 +1,8 @@
<?php
$api_key = '1zhoGXv9PA0lvPNG81GUlCNfqT45gVuV'; //super admin api_key, change it by your
$api_url = 'http://dotclear.localhost/dotclear/index.php?rest'; //my local dev platform
$api_key = 'tn0GHPOxbK3hbJAygRPihJHqPKvhC2vw'; //super admin api_key, change it by your
$api_url = 'http://dotclear.localhost/rest'; //my local dev platform, change it by your
//testUser key DVsmYPmW6jvfk4kgak1krvbxcl1nGXMJ
function check_json_content($content,$aKeyToCheck){
@ -313,7 +313,7 @@ $allTests = array(
//delete the settings
array(
'title' => 'DELETE /%blog_id%/settings/test/test2 without key error',
'title' => 'DELETE /%blog_id%/settings/test/test2 with key error',
'url' => $api_url.'/%blog_id%/settings/test/test2',
'method' => 'DELETE',
'expectedResponseCode' => '403',
@ -322,6 +322,16 @@ $allTests = array(
'x_dc_key' => 'lkjmlhkjb:b:kjb',
'saveAs' => ''
),
array(
'title' => 'DELETE /%blog_id%/settings/test/tsdfLJKt2 with name error',
'url' => $api_url.'/%blog_id%/settings/test/tsdfLJKt2',
'method' => 'DELETE',
'expectedResponseCode' => '404',
'expectedKeyOnResponse' => 'code',
'body' => '',
'x_dc_key' => $api_key,
'saveAs' => ''
),
array(
'title' => 'DELETE /%blog_id%/settings/test/test2 without error',
@ -334,7 +344,181 @@ $allTests = array(
'saveAs' => ''
),
//create a POST
array(
'title' => 'Create a post /%blog_id%/post',
'url' => $api_url.'/%blog_id%/post',
'method' => 'POST',
'expectedResponseCode' => '200',
'expectedKeyOnResponse' => 'id',
'body' => json_encode(array(
"post_title" => "New Post",
"post_format"=> "wiki",
"post_content"=> "!!!Pouette \n hey",
"post_content_xhtml"=> "string",
"post_status"=> "Pending",
"post_tags" => array('plip','plap')
)),
'x_dc_key' => $api_key,
'saveAs' => 'post_id'
),
//plusieurs billets d'un coup
array(
'title' => 'Create many post /%blog_id%/post',
'url' => $api_url.'/%blog_id%/post',
'method' => 'POST',
'expectedResponseCode' => '200',
'expectedKeyOnResponse' => 'message',
'body' => json_encode(array(
array(
"post_title" => "New Post2",
"post_format"=> "wiki",
"post_content"=> "!!!Pouette \n hey",
"post_content_xhtml"=> "string",
"post_status"=> "Pending",
),
array(
"post_title" => "New Post3",
"post_format"=> "wiki",
"post_content"=> "!!!Pouette \n\n!!hey\n heu...",
"post_content_xhtml"=> "string",
"post_status"=> "Pending",
)
)),
'x_dc_key' => $api_key,
'saveAs' => ''
),
//create a post with a new category
array(
'title' => 'Create a post /%blog_id%/post with a new cat',
'url' => $api_url.'/%blog_id%/post',
'method' => 'POST',
'expectedResponseCode' => '200',
'expectedKeyOnResponse' => 'message',
'body' => json_encode(array(
"post_title" => "New Post4",
"post_format"=> "wiki",
"post_content"=> "!!!Pouette \n hey",
"post_content_xhtml"=> "string",
"post_status"=> "Pending",
"new_cat_id"=> "TestingCat",
)),
'x_dc_key' => $api_key,
'saveAs' => ''
),
//create a post with an existing category
array(
'title' => 'Create a post /%blog_id%/post with an existing cat',
'url' => $api_url.'/%blog_id%/post',
'method' => 'POST',
'expectedResponseCode' => '200',
'expectedKeyOnResponse' => 'message',
'body' => json_encode(array(
"post_title" => "New Post5",
"post_format"=> "wiki",
"post_content"=> "!!!Pouette \n hey",
"post_content_xhtml"=> "string",
"post_status"=> "Pending",
"cat_id"=> 1,
)),
'x_dc_key' => $api_key,
'saveAs' => ''
),
//create a post with a new sub category
array(
'title' => 'Create a post /%blog_id%/post',
'url' => $api_url.'/%blog_id%/post',
'method' => 'POST',
'expectedResponseCode' => '200',
'expectedKeyOnResponse' => 'message',
'body' => json_encode(array(
"post_title" => "New Post6",
"post_format"=> "wiki",
"post_content"=> "!!!Pouette \n hey",
"post_content_xhtml"=> "string",
"post_status"=> "Pending",
"new_cat_parent" => 1,
"new_cat_id"=> "Testing sub Cat",
)),
'x_dc_key' => $api_key,
'saveAs' => ''
),
array(
'title' => 'Create a post /%blog_id%/post with all parameters',
'url' => $api_url.'/%blog_id%/post',
'method' => 'POST',
'expectedResponseCode' => '200',
'expectedKeyOnResponse' => 'message',
'body' => json_encode(array(
"post_title" => "New Post6",
"post_format"=> "wiki",
"post_content"=> "!!!Pouette \n hey",
"post_content_xhtml"=> "string",
"post_status"=> "Pending",
"new_cat_parent" => 1,
"new_cat_id"=> "Testing sub Cat 2",
"post_dt" => '2013-04-19 05:06:07',
"post_password" => 'toto',
"post_url" => "newPost",
"post_lang" => "de",
"post_excerpt" => "blahblah",
"post_notes" => "heu...",
"post_selected" => true,
"post_open_comment" => true,
"post_open_tb" => true,
)),
'x_dc_key' => $api_key,
'saveAs' => ''
),
//Créer une méta (un tag)
array(
"title" => 'Create a post meta /%blog_id%/metas',
'url' => $api_url.'/%blog_id%/metas',
'method' => 'POST',
'expectedResponseCode' => '201',
'expectedKeyOnResponse' => 'id',
'body' => '{ "meta_id": "lol", "meta_type": "tag", "post_id": %post_id% }',
'x_dc_key' => $api_key,
'saveAs' => ''
),
/*
"post_title": "string",
"post_format": "string",
"post_content": "string",
"post_content_xhtml": "string",
"post_status": "Pending",
"cat_id": 0,
"new_cat_id": "string",
"new_cat_parent_id": 0,
"new_cat_desc": "string",
"new_cat_url": "string",
"post_dt": "string",
"post_password": "string",
"post_url": "string",
"post_lang": "string",
"post_excerpt": "string",
"post_excerpt_xhtml": "string",
"post_notes": "string",
"post_selected": true,
"post_open_comment": true,
"post_open_tb": true,
"post_words": [
null
]
*/
/*
,
//remove blog test
array(
'title' => 'Blogs /blogs/%blog_id% with good api_key',
@ -347,19 +531,21 @@ $allTests = array(
'saveAs' => ''
),
*/
);
$saveIds = array();
foreach($allTests as $oneTest){
//replaces
foreach($oneTest as $key => $value){
foreach($saveIds as $find => $replace){
$oneTest[$key] = str_replace('%'.$find.'%', $replace, $value);
$value = $oneTest[$key] = str_replace('%'.$find.'%', $replace, (string)$value);
}
}
echo "\nTesting ".$oneTest['title']." ".$oneTest['url']." method ". $oneTest['method'];
$t = test(
$oneTest['url'],

Loading…
Cancel
Save