bitbucket -> github

master
gnieark 7 years ago
parent 803b36ed3d
commit eeac0740d2

@ -1,10 +1,38 @@
# Dotclear REST API
Plugin dotclear ouvrant une API REST/JSON
Plugin to serve a Rest/JSON API on Dotclear.
C'est en cours de développement et est loin d'être fini.
This is a work in progress. API definitions and specifications are not stables. Its will be more exhaustive.
Real time code repository is https://bitbucket.org/gnieark/dc-rest-api
Les spécifications swagger seront modifiées au fur et à mesure du développement de l'API.
Pour le moment elles sont basées sur la structure de la base de données et ne sont pas exhaustives.
A terme, elles seront basées plus sur les fonctions de dotclear.
# Install:
Make a zip of this repository and install it on your Dotclear Blog.
# License
Dotclear rest/json plugin.
Copyright (C) [Gnieark](https://blog-du-grouik.tinad.fr/)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
# Third-party code
## Dotclear
The content management system Dotclear http://dotclear.org/ licensed under
GNU GENERAL PUBLIC LICENSE Version 2, June 1991
## SwaggerUI
Documentation and the tool to test the API is a third party code integrated on this plugin:
Swagger-UI https://github.com/swagger-api/swagger-ui Licensed under the Apache License, Version 2.0

@ -4,6 +4,6 @@ if (!defined('DC_CONTEXT_ADMIN')) { return; }
$_menu['Blog']->addItem(__('Rest API'),
'plugin.php?p=rest',
urldecode(dcPage::getPF('rest/rest_api_256x256.png')),
urldecode(dcPage::getPF('rest/rest_api.png')),
preg_match('/plugin.php\?p=rest(&.*)?$/',$_SERVER['REQUEST_URI']),
$core->auth->check('contentadmin',$core->blog->id));

@ -7,4 +7,8 @@ $__autoload['RestQuery'] = dirname(__FILE__).'/inc/class.rest.query.php';
$__autoload['RestQueryGetBlogs'] = dirname(__FILE__).'/inc/class.rest.query.get.blogs.php';
$__autoload['RestQueryGetBlog'] = dirname(__FILE__).'/inc/class.rest.query.get.blog.php';
$__autoload['RestQueryGetSpecs'] = dirname(__FILE__).'/inc/class.rest.query.get.specs.php';
$__autoload['RestQueryPostBlogs'] = dirname(__FILE__).'/inc/class.rest.query.post.blogs.php';
$__autoload['RestQueryPostBlogs'] = dirname(__FILE__).'/inc/class.rest.query.post.blogs.php';
$__autoload['ResQueryPatchBlogs'] = dirname(__FILE__).'/inc/class.rest.query.patch.blogs.php';
$__autoload['ResQueryPutBlogs'] = dirname(__FILE__).'/inc/class.rest.query.put.blogs.php';
$__autoload['ResQueryDeleteBlogs'] = dirname(__FILE__).'/inc/class.rest.query.delete.blogs.php';
$__autoload['RestQueryGetBlogSettings'] = dirname(__FILE__).'/inc/class.rest.query.get.blog.settings.php';

@ -23,15 +23,15 @@ class rest extends dcUrlHandlers
}elseif($args == 'specs'){
$queryObj = new RestQueryGetSpecs();
break;
}elseif(preg_match('^blogs/(.+)$', $args )){
}elseif(preg_match('/^blogs\/(.*)$/', $args )){
///blogs/{blog-id}
$queryObj = new RestQueryGetBlog($args);
break;
}elseif(preg_match('/^(.*)\/settings$/', $args )){
$queryObj = new RestQueryGetBlogSettings($args);
break;
}
///blogs/{blog-id}
break;
case "POST":
if($args == 'blogs'){
@ -40,15 +40,25 @@ class rest extends dcUrlHandlers
break;
case "PUT":
if(preg_match('/^blogs\/(.*)$/', $args )){
$queryObj = new ResQueryPutBlogs($args,$body);
break;
}
break;
case "PATCH":
if(preg_match('/^blogs\/(.*)$/', $args )){
$queryObj = new ResQueryPatchBlogs($args,$body);
break;
}
break;
case "DELETE":
if(preg_match('/^blogs\/(.*)$/', $args )){
$queryObj = new ResQueryDeleteBlogs($args,$body);
break;
}
break;
default:
$queryObj = new RestQuery();
@ -101,7 +111,7 @@ class rest extends dcUrlHandlers
$core->auth = false;
}
$r = rest::restFactoryQuery($_SERVER['REQUEST_METHOD'],$args,file_get_contents('php://input'));
header($r->response_code);
header($r->get_full_code_header());
echo json_encode($r->response_message);
}

@ -56,10 +56,17 @@ paths:
$ref: '#/definitions/blog'
required: true
responses:
'200':
description: array containing the new blog's identifiant
schema:
$ref: '#/definitions/Ids'
'201':
description: 'Success, array containing the new blog''s identifiant'
schema:
type: object
properties:
code:
type: integer
blog_id:
type: integer
message:
type: string
default:
description: Unexpected error
schema:
@ -78,9 +85,7 @@ paths:
required: true
responses:
'200':
description: >-
array containing blog properties. This list of attributes is not
exhaustive.
description: 'Core blog properties. use {blog_id}/settings methods for more settings.'
schema:
$ref: '#/definitions/blogProperties'
'404':
@ -118,9 +123,7 @@ paths:
schema:
$ref: '#/definitions/Error'
put:
summary: >-
Overwrite blog Properties (if a parameter is not set, his value will be
erased by de default value)
summary: 'Overwrite blog Properties (if an optional parameter is not set, his value will be erased by the default value)'
parameters:
- name: x_dc_key
in: header
@ -135,7 +138,7 @@ paths:
description: This list of parameters is not exhaustive
required: true
schema:
$ref: '#/definitions/blogProperties'
$ref: '#/definitions/blogPropertiesPut'
responses:
'200':
description: array containing the edited blog's identifiant
@ -169,6 +172,28 @@ paths:
description: Unexpected error
schema:
$ref: '#/definitions/Error'
'/{blog_id}/settings':
get:
summary: 'Get the about:config'
description: Get all parameters
parameters:
- name: x_dc_key
in: header
type: string
required: true
- name: blog_id
in: path
type: string
required: true
responses:
'200':
description: OK
'404':
description: this blog id does not exists
default:
description: Unexpected error
schema:
$ref: '#/definitions/Error'
'/{blog-id}/posts':
get:
summary: Get list of posts
@ -194,9 +219,7 @@ paths:
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: 'Fields you want to get. If unset, fields are post_id, post_url, post_status, post_title, post_date'
responses:
'200':
description: list of posts
@ -222,9 +245,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
schema:
$ref: '#/definitions/new_dc_post'
responses:
@ -489,164 +510,34 @@ definitions:
id:
type: integer
description: New blog id
blogProperties:
blogPropertiesPut:
required:
- blog_id
- blog_name
- blog_url
- blog_desc
type: object
properties:
id:
type: string
name:
type: string
url:
type: string
description:
type: string
author:
type: string
allow_comments:
type: boolean
allow_trackbacks:
type: boolean
blog_timezone:
type: string
comment_preview_optional:
type: string
comments_nofollow:
type: boolean
comments_pub:
type: boolean
comments_ttl:
type: integer
copyright_notice:
type: string
csp_admin_default:
type: string
csp_admin_img:
type: string
csp_admin_on:
type: boolean
csp_admin_report_only:
type: boolean
csp_admin_script:
type: string
csp_admin_style:
type: string
date_format:
type: string
date_formats:
type: array
items:
type: string
format: string
editor:
type: string
enable_html_filter:
type: boolean
enable_xmlrpc:
type: boolean
import_feed_ip_regexp:
type: string
import_feed_no_private_ip:
type: boolean
import_feed_port_regexp:
type: string
import_feed_url_control:
type: boolean
inc_subcats:
type: boolean
jquery_migrate_mute:
type: boolean
jquery_version:
type: string
lang:
type: string
media_exclusion:
type: string
media_flash_fallback:
type: boolean
media_img_default_alignment:
type: string
media_img_default_legend:
type: string
media_img_default_link:
type: string
media_img_default_size:
type: string
media_img_m_size:
type: integer
media_img_no_date_alone:
type: string
media_img_s_size:
type: integer
media_img_t_size:
type: integer
media_img_title_pattern:
type: string
media_img_use_dto_first:
type: string
media_video_height:
type: integer
media_video_width:
type: integer
nb_comment_per_feed:
type: integer
nb_post_for_home:
type: integer
nb_post_per_feed:
type: integer
nb_post_per_page:
type: integer
no_search:
type: boolean
note_title_tag:
type: string
post_url_format:
type: string
prevents_clickjacking:
type: string
public_path:
type: string
public_url:
type: string
robots_policy:
blog_id:
type: string
short_feed_items:
type: boolean
simpleMenu:
type: array
items:
type: string
simpleMenu_active:
type: boolean
store_plugin_url:
blog_name:
type: string
store_theme_url:
blog_url:
type: string
theme:
blog_desc:
type: string
themes_path:
blogProperties:
type: object
properties:
blog_id:
type: string
themes_url:
blog_name:
type: string
time_format:
blog_url:
type: string
time_formats:
type: array
items:
type: string
tpl_allow_php:
type: boolean
tpl_use_cache:
type: boolean
trackbacks_pub:
type: boolean
trackbacks_ttl:
type: integer
url_scan:
blog_desc:
type: string
use_smilies:
type: boolean
wiki_comments:
type: boolean
new_dc_post:
type: object
required:

@ -1,5 +0,0 @@
<?php
?>
<h1>Hey</h1>

@ -1,93 +0,0 @@
<!-- HTML for static distribution bundle build -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Swagger UI</title>
<link href="https://fonts.googleapis.com/css?family=Open+Sans:400,700|Source+Code+Pro:300,600|Titillium+Web:400,600,700" rel="stylesheet">
<link rel="stylesheet" type="text/css" href="./swagger-ui.css" >
<link rel="icon" type="image/png" href="./favicon-32x32.png" sizes="32x32" />
<link rel="icon" type="image/png" href="./favicon-16x16.png" sizes="16x16" />
<style>
html
{
box-sizing: border-box;
overflow: -moz-scrollbars-vertical;
overflow-y: scroll;
}
*,
*:before,
*:after
{
box-sizing: inherit;
}
body {
margin:0;
background: #fafafa;
}
</style>
</head>
<body>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="position:absolute;width:0;height:0">
<defs>
<symbol viewBox="0 0 20 20" id="unlocked">
<path d="M15.8 8H14V5.6C14 2.703 12.665 1 10 1 7.334 1 6 2.703 6 5.6V6h2v-.801C8 3.754 8.797 3 10 3c1.203 0 2 .754 2 2.199V8H4c-.553 0-1 .646-1 1.199V17c0 .549.428 1.139.951 1.307l1.197.387C5.672 18.861 6.55 19 7.1 19h5.8c.549 0 1.428-.139 1.951-.307l1.196-.387c.524-.167.953-.757.953-1.306V9.199C17 8.646 16.352 8 15.8 8z"></path>
</symbol>
<symbol viewBox="0 0 20 20" id="locked">
<path d="M15.8 8H14V5.6C14 2.703 12.665 1 10 1 7.334 1 6 2.703 6 5.6V8H4c-.553 0-1 .646-1 1.199V17c0 .549.428 1.139.951 1.307l1.197.387C5.672 18.861 6.55 19 7.1 19h5.8c.549 0 1.428-.139 1.951-.307l1.196-.387c.524-.167.953-.757.953-1.306V9.199C17 8.646 16.352 8 15.8 8zM12 8H8V5.199C8 3.754 8.797 3 10 3c1.203 0 2 .754 2 2.199V8z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="close">
<path d="M14.348 14.849c-.469.469-1.229.469-1.697 0L10 11.819l-2.651 3.029c-.469.469-1.229.469-1.697 0-.469-.469-.469-1.229 0-1.697l2.758-3.15-2.759-3.152c-.469-.469-.469-1.228 0-1.697.469-.469 1.228-.469 1.697 0L10 8.183l2.651-3.031c.469-.469 1.228-.469 1.697 0 .469.469.469 1.229 0 1.697l-2.758 3.152 2.758 3.15c.469.469.469 1.229 0 1.698z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="large-arrow">
<path d="M13.25 10L6.109 2.58c-.268-.27-.268-.707 0-.979.268-.27.701-.27.969 0l7.83 7.908c.268.271.268.709 0 .979l-7.83 7.908c-.268.271-.701.27-.969 0-.268-.269-.268-.707 0-.979L13.25 10z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="large-arrow-down">
<path d="M17.418 6.109c.272-.268.709-.268.979 0s.271.701 0 .969l-7.908 7.83c-.27.268-.707.268-.979 0l-7.908-7.83c-.27-.268-.27-.701 0-.969.271-.268.709-.268.979 0L10 13.25l7.418-7.141z"/>
</symbol>
<symbol viewBox="0 0 24 24" id="jump-to">
<path d="M19 7v4H5.83l3.58-3.59L8 6l-6 6 6 6 1.41-1.41L5.83 13H21V7z"/>
</symbol>
<symbol viewBox="0 0 24 24" id="expand">
<path d="M10 18h4v-2h-4v2zM3 6v2h18V6H3zm3 7h12v-2H6v2z"/>
</symbol>
</defs>
</svg>
<div id="swagger-ui"></div>
<script src="./swagger-ui-bundle.js"> </script>
<script src="./swagger-ui-standalone-preset.js"> </script>
<script>
window.onload = function() {
// Build a system
const ui = SwaggerUIBundle({
url: "http://dotclear.localhost/dotclear/index.php?rest/specs",
dom_id: '#swagger-ui',
presets: [
SwaggerUIBundle.presets.apis,
SwaggerUIStandalonePreset
],
plugins: [
SwaggerUIBundle.plugins.DownloadUrl
],
layout: "StandaloneLayout"
})
window.ui = ui
}
</script>
</body>
</html>

@ -1,4 +1,6 @@
<!DOCTYPE html>
<?php
if (!defined('DC_RC_PATH')) { return; }
?><!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">

@ -83,10 +83,21 @@
}
],
"responses": {
"200": {
"description": "array containing the new blog's identifiant",
"201": {
"description": "Success, array containing the new blog's identifiant",
"schema": {
"$ref": "#/definitions/Ids"
"type": "object",
"properties": {
"code": {
"type": "integer"
},
"blog_id": {
"type": "integer"
},
"message": {
"type": "string"
}
}
}
},
"default": {
@ -117,7 +128,7 @@
],
"responses": {
"200": {
"description": "array containing blog properties. This list of attributes is not exhaustive.",
"description": "Core blog properties. use {blog_id}/settings methods for more settings.",
"schema": {
"$ref": "#/definitions/blogProperties"
}
@ -177,7 +188,7 @@
}
},
"put": {
"summary": "Overwrite blog Properties (if a parameter is not set, his value will be erased by de default value)",
"summary": "Overwrite blog Properties (if an optional parameter is not set, his value will be erased by the default value)",
"parameters": [
{
"name": "x_dc_key",
@ -197,7 +208,7 @@
"description": "This list of parameters is not exhaustive",
"required": true,
"schema": {
"$ref": "#/definitions/blogProperties"
"$ref": "#/definitions/blogPropertiesPut"
}
}
],
@ -254,6 +265,40 @@
}
}
},
"/{blog_id}/settings": {
"get": {
"summary": "Get the about:config",
"description": "Get all parameters",
"parameters": [
{
"name": "x_dc_key",
"in": "header",
"type": "string",
"required": true
},
{
"name": "blog_id",
"in": "path",
"type": "string",
"required": true
}
],
"responses": {
"200": {
"description": "OK"
},
"404": {
"description": "this blog id does not exists"
},
"default": {
"description": "Unexpected error",
"schema": {
"$ref": "#/definitions/Error"
}
}
}
}
},
"/{blog-id}/posts": {
"get": {
"summary": "Get list of posts",
@ -741,240 +786,43 @@
}
}
},
"blogProperties": {
"blogPropertiesPut": {
"required": [
"blog_id",
"blog_name",
"blog_url",
"blog_desc"
],
"type": "object",
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"url": {
"type": "string"
},
"description": {
"type": "string"
},
"author": {
"type": "string"
},
"allow_comments": {
"type": "boolean"
},
"allow_trackbacks": {
"type": "boolean"
},
"blog_timezone": {
"type": "string"
},
"comment_preview_optional": {
"type": "string"
},
"comments_nofollow": {
"type": "boolean"
},
"comments_pub": {
"type": "boolean"
},
"comments_ttl": {
"type": "integer"
},
"copyright_notice": {
"type": "string"
},
"csp_admin_default": {
"type": "string"
},
"csp_admin_img": {
"type": "string"
},
"csp_admin_on": {
"type": "boolean"
},
"csp_admin_report_only": {
"type": "boolean"
},
"csp_admin_script": {
"type": "string"
},
"csp_admin_style": {
"type": "string"
},
"date_format": {
"type": "string"
},
"date_formats": {
"type": "array",
"items": {
"type": "string",
"format": "string"
}
},
"editor": {
"type": "string"
},
"enable_html_filter": {
"type": "boolean"
},
"enable_xmlrpc": {
"type": "boolean"
},
"import_feed_ip_regexp": {
"type": "string"
},
"import_feed_no_private_ip": {
"type": "boolean"
},
"import_feed_port_regexp": {
"type": "string"
},
"import_feed_url_control": {
"type": "boolean"
},
"inc_subcats": {
"type": "boolean"
},
"jquery_migrate_mute": {
"type": "boolean"
},
"jquery_version": {
"type": "string"
},
"lang": {
"type": "string"
},
"media_exclusion": {
"type": "string"
},
"media_flash_fallback": {
"type": "boolean"
},
"media_img_default_alignment": {
"type": "string"
},
"media_img_default_legend": {
"type": "string"
},
"media_img_default_link": {
"type": "string"
},
"media_img_default_size": {
"type": "string"
},
"media_img_m_size": {
"type": "integer"
},
"media_img_no_date_alone": {
"type": "string"
},
"media_img_s_size": {
"type": "integer"
},
"media_img_t_size": {
"type": "integer"
},
"media_img_title_pattern": {
"type": "string"
},
"media_img_use_dto_first": {
"type": "string"
},
"media_video_height": {
"type": "integer"
},
"media_video_width": {
"type": "integer"
},
"nb_comment_per_feed": {
"type": "integer"
},
"nb_post_for_home": {
"type": "integer"
},
"nb_post_per_feed": {
"type": "integer"
},
"nb_post_per_page": {
"type": "integer"
},
"no_search": {
"type": "boolean"
},
"note_title_tag": {
"type": "string"
},
"post_url_format": {
"type": "string"
},
"prevents_clickjacking": {
"type": "string"
},
"public_path": {
"type": "string"
},
"public_url": {
"type": "string"
},
"robots_policy": {
"blog_id": {
"type": "string"
},
"short_feed_items": {
"type": "boolean"
},
"simpleMenu": {
"type": "array",
"items": {
"type": "string"
}
},
"simpleMenu_active": {
"type": "boolean"
},
"store_plugin_url": {
"blog_name": {
"type": "string"
},
"store_theme_url": {
"blog_url": {
"type": "string"
},
"theme": {
"blog_desc": {
"type": "string"
},
"themes_path": {
}
}
},
"blogProperties": {
"type": "object",
"properties": {
"blog_id": {
"type": "string"
},
"themes_url": {
"blog_name": {
"type": "string"
},
"time_format": {
"blog_url": {
"type": "string"
},
"time_formats": {
"type": "array",
"items": {
"type": "string"
}
},
"tpl_allow_php": {
"type": "boolean"
},
"tpl_use_cache": {
"type": "boolean"
},
"trackbacks_pub": {
"type": "boolean"
},
"trackbacks_ttl": {
"type": "integer"
},
"url_scan": {
"blog_desc": {
"type": "string"
},
"use_smilies": {
"type": "boolean"
},
"wiki_comments": {
"type": "boolean"
}
}
},

@ -0,0 +1,52 @@
<?php
class ResQueryDeleteBlogs extends RestQuery
{
//$core->delBlog($blog_id);
public function __construct($args){
global $core;
$this->blog_id = substr($args,6);
$this->required_perms = 'admin';
//Is allowed?
if($this->is_allowed() === false){
//need To be authentified
$this->response_code = 403;
$this->response_message = array('code' => 403, 'error' => 'You need to be admin to patch a blog');
return;
}
//does the blog exists?
$core->blog = new dcBlog($core, $this->blog_id);
$blog_settings = new dcSettings($core,$this->blog_id);
if(!$core->blog->id){
$this->response_code = 404;
$this->response_message = array('code' => 404, 'error' => 'Resource '.$this -> blog_id.' not found');
return;
}
try{
$core->delBlog($this->blog_id);
$this->response_code = 201;
$this->response_message = array(
'code' => 200,
'message' => 'Successfully deleted blog '.$this->blog_id
);
}
catch (Exception $e)
{
$this->response_code = 500;
$this->response_message = array(
'code' => 500,
'message' => $e->getMessage()
);
}
}
}

@ -4,24 +4,50 @@
*/
class RestQueryGetBlog extends RestQuery
{
public function __construct(){
public function __construct($args)
{
global $core;
}
$this->blog_id = substr($args,6);
$this->required_perms = 'unauth';
if($this->is_allowed() === false){
//need To be authentified
$this->response_code = 403;
$this->response_message = array('code' => 403, 'error' => 'This API is not open without KEY');
return;
}
//instance
if($core->auth === false){
$core->auth = new dcAuth($core); //class dcBlog need it
$unauth = true;
if($core->blog->status == false){
//le blog n'est pas publié (et l'user n'est pas authentifié)
// on Sort en 404
$this->response_code = 404;
$this->response_message = array('code' => 404, 'error' => 'Resource '.$blog_id.' not found');
return;
}
}
$core->blog = new dcBlog($core, $this->blog_id);
$blog_settings = new dcSettings($core,$this->blog_id);
/*
* ça se complique niveau droits
*
* SI L'utilisateur n'est pas authentifié
* le blog est hors ligne
* -> 404
* l'API n'est pas publique
* -> refus
* l'API est publique
* -> OK, mais on ne retourne pas les infos techniques
* L'utilisateur est authentifié
* n'est pas admin (du blog en question)
* -> OK, mais on ne retourne pas les infos techniques
* est admin
* -> L'API retourne le maximum d'infos
*/
if(!$core->blog->id){
$this->response_code = 404;
$this->response_message = array('code' => 404, 'error' => 'Resource '.$this -> blog_id.' not found');
return;
}
$response = array(
'blog_id' => $core->blog->id,
'blog_status' => $core->blog->status,
'blog_name' => $core->blog->name,
'blog_desc' => $core->blog->desc,
'blog_url' => $core->blog->url
);
$this->response_code = 200;
$this->response_message = $response;
return;
}
}

@ -0,0 +1,48 @@
<?php
class RestQueryGetBlogSettings extends RestQuery
{
public function __construct($args)
{
global $core;
$this->blog_id = explode("/",$args)[0];
//check if user is allowed
$this->required_perms = 'admin';
if($this->is_allowed() === false){
$this->response_code = 403;
$this->response_message = array('code' => 403, 'error' => 'No enough privileges');
return;
}
$core->blog = new dcBlog($core, $this->blog_id);
$blog_settings = new dcSettings($core,$this->blog_id);
if(!$core->blog->id){
$this->response_code = 404;
$this->response_message = array('code' => 404, 'error' => 'Resource '.$this -> blog_id.' not found');
return;
}
try{
$settings = array();
foreach ($core->blog->settings->dumpNamespaces() as $ns => $namespace) {
foreach ($namespace->dumpSettings() as $k => $v) {
$settings[$ns][$k] = $v;
}
}
$this->response_code = 200;
$this->response_message = $settings;
}catch (Exception $e){
$this->response_code = 500;
$this->response_message = array(
'code' => 500,
'message' => $e->getMessage()
);
}
return;
}
}

@ -5,7 +5,7 @@ class RestQueryGetBlogs extends RestQuery
public function __construct(){
global $core;
$this->blog_id = false; //this method doesn't depend on a bolg_id
$this->blog_id = false; //this method doesn't depend on a blog_id
$this->required_perms = 'none'; //I want user have an account
if($this->is_allowed() === false){

@ -0,0 +1,74 @@
<?php
class ResQueryPatchBlogs extends RestQuery
{
public function __construct($args,$body)
{
global $core;
$this->blog_id = substr($args,6);
$this->required_perms = 'admin';
//Is allowed?
if($this->is_allowed() === false){
//need To be authentified
$this->response_code = 403;
$this->response_message = array('code' => 403, 'error' => 'You need to be admin to patch a blog');
return;
}
//Is JSON valid?
$inputArray = $this-> body_to_array($body);
if ($inputArray === false){
return;
}
//is it valid fields?
if(!$this->check_for_required_fields( $inputArray, array(),
array('blog_id','blog_url','blog_name','blog_desc','lang','blog_timezone','url_scan')) ){
return;
}
//does the blog exists?
$core->blog = new dcBlog($core, $this->blog_id);
$blog_settings = new dcSettings($core,$this->blog_id);
if(!$core->blog->id){
$this->response_code = 404;
$this->response_message = array('code' => 404, 'error' => 'Resource '.$this -> blog_id.' not found');
return;
}
$cur = $core->con->openCursor($core->prefix.'blog');
if(isset($inputArray['blog_id']))
$cur->blog_id = $inputArray['blog_id'];
else
$cur->blog_id = $core->blog->id;
if(isset($inputArray['blog_url']))
$cur->blog_url = preg_replace('/\?+$/','?', $inputArray['blog_url']);
else
$cur->blog_url = $core->blog->url;
if(isset($inputArray['blog_name']))
$cur->blog_name = $inputArray['blog_name'];
if(isset($inputArray['blog_desc']))
$cur->blog_desc = $inputArray['blog_desc'];
$core->updBlog($this->blog_id,$cur);
//$cur->blog_upddt = date('Y-m-d H:i:s');
//$cur->update("WHERE blog_id = '".$core->con->escape($id)."'");
$this -> response_code = 200;
$this -> response_message = array(
'code' => 200,
'message' => 'blog '.$this->blog_id.' Successfully updated'
);
return;
}
}

@ -1,9 +1,9 @@
<?php
class RestQuery{
public $response_code;
protected $response_code;
public $response_message; //array
public $blog_id;
protected $blog_id;
protected $required_perms = 'admin'; //must be changed by the childs class
/*
should be:
@ -22,7 +22,7 @@ class RestQuery{
public function __construct()
{
$this->response_code = RestQuery::get_full_code_header(400);
$this->response_code = 400;
$this->response_message = array(
"error" => "Unrecoknized method",
"code" => 400
@ -44,7 +44,7 @@ class RestQuery{
if(empty(array_diff($fieldsSetted,$fieldsRequired))){
return true;
}else{
$this->response_code = RestQuery::get_full_code_header(400);
$this->response_code = 400;
$this->response_message = array(
"error" => "Only and each of following parameters ".
implode(", ",$fieldsRequired)." are required",
@ -56,7 +56,7 @@ class RestQuery{
//check if all required fields are set
foreach($fieldsRequired as $key){
if(!isset($arrayToCheck[$key])){
$this->response_code = RestQuery::get_full_code_header(400);
$this->response_code = 400;
$this->response_message = array(
"error" => "field ".$key." is needed",
"code" => 400
@ -102,8 +102,6 @@ class RestQuery{
switch($this->required_perms){
case 'unauth':
//on verifie quand même que l'API est ouverte
if((!$core->blog->settings->rest->rest_is_open) && ($core->auth === false)){
return false;
@ -112,7 +110,7 @@ class RestQuery{
}
break;
//to do
case 'none':
//user must be valid
if($core->auth === false){
@ -147,7 +145,10 @@ class RestQuery{
break;
}
}
public function get_full_code_header($code){
public function get_full_code_header($code=''){
if($code == ''){
$code = $this->response_code;
}
static $codes = array(
100 =>"Continue",
101 =>"Switching Protocols",

@ -75,9 +75,10 @@ class RestQueryPostBlogs extends RestQuery
$core->callBehavior('adminAfterBlogCreate',$cur,$blog_id,$blog_settings);
//cool
$this->response_code = 200;
$this->response_code = 201;
$this->response_message = array(
'code' => 200,
'code' => 201,
'id' => $blog_id
'message' => 'Successfully created blog'.$blog_id
);

@ -0,0 +1,73 @@
<?php
class ResQueryPutBlogs extends RestQuery
{
public function __construct($args,$body)
{
global $core;
$this->blog_id = substr($args,6);
$this->required_perms = 'admin';
//Is allowed?
if($this->is_allowed() === false){
//need To be authentified
$this->response_code = 403;
$this->response_message = array('code' => 403, 'error' => 'You need to be admin to put a blog');
return;
}
//Is JSON valid?
$inputArray = $this-> body_to_array($body);
if ($inputArray === false){
return;
}
//is it valid fields?
if(!$this->check_for_required_fields( $inputArray, array('blog_id','blog_url','blog_name','blog_desc'), array())){
return;
}
//does the blog exists?
$core->blog = new dcBlog($core, $this->blog_id);
$blog_settings = new dcSettings($core,$this->blog_id);
if(!$core->blog->id){
$this->response_code = 404;
$this->response_message = array('code' => 404, 'error' => 'Resource '.$this -> blog_id.' not found');
return;
}
$cur = $core->con->openCursor($core->prefix.'blog');
if(isset($inputArray['blog_id']))
$cur->blog_id = $inputArray['blog_id'];
else
$cur->blog_id = $core->blog->id;
if(isset($inputArray['blog_url']))
$cur->blog_url = preg_replace('/\?+$/','?', $inputArray['blog_url']);
else
$cur->blog_url = $core->blog->url;
if(isset($inputArray['blog_name']))
$cur->blog_name = $inputArray['blog_name'];
if(isset($inputArray['blog_desc']))
$cur->blog_desc = $inputArray['blog_desc'];
$core->updBlog($this->blog_id,$cur);
//$cur->blog_upddt = date('Y-m-d H:i:s');
//$cur->update("WHERE blog_id = '".$core->con->escape($id)."'");
$this -> response_code = 200;
$this -> response_message = array(
'code' => 200,
'message' => 'blog '.$this->blog_id.' Successfully updated'
);
return;
}
}

@ -56,11 +56,11 @@ if(!empty($_POST['resetApiKey'])){
?>
<html>
<head>
<title>Rest API config</title>
<title><?php echo __('REST API configuration'); ?></title>
</head>
<body>
<h2>Documentation</h2>
<p><a href="<?php echo $core->blog->url."rest/documentation"; ?>">Go to the Swagger documentation</a></p>
<p><a href="<?php echo $core->blog->url."rest/documentation" . '">' . __('Documentation and test interface Swagger UI') .'</a></p>'; ?>
<h2><?php echo __('Your API key');?></h2>
<?php echo $apiKey-> get_dc_admin_form($core->auth->userID()); ?>
@ -76,10 +76,9 @@ if($core->auth->isSuperAdmin()):
</p>
<p>
<?php echo form::checkbox('open', 1, $openApi); ?>
<label class="classic" for="open">&nbsp;<?php echo __('API is open');?></label>
<label class="classic" for="open">&nbsp;<?php echo __('API is open without key');?></label>
</p>
<p class="info"><?php echo __("If checked, few methods as GET will be allowed to externals users without API key.
However, they won't be able to request for non public content."); ?></p>
<p class="info"><?php echo __("If checked, few methods as GET will be allowed to externals users without API key. However, they won't be able to request for non public content."); ?></p>
<?php echo $core->formNonce(); ?>
<p>
<?php echo form::checkbox('sendHeaders', 1, $sendHeaders); ?>

@ -4,5 +4,41 @@ msgstr "Activer l'API REST"
msgid "Your API key"
msgstr "Votre clef"
msgid "Your new key is"
msgstr "Votre nouvelle clef est"
msgid "API is open without key"
msgstr "L'API est ouverte sans authentification"
msgid "Rest API configuration"
msgstr "Configuration de l'API"
msgstr "Configuration de l'API"
msgid "If checked, few methods as GET will be allowed to externals users without API key. However, they won't be able to request for non public content."
msgstr "Si coché, Certaines méthodes seront accessibles sans authentification par clef (ni aucune autre authentification). Cependant, seules les actions et informations normalement accessibles sur le blog par les visiteurs non authentifiés sont concernés."
msgid "Send Coors headers"
msgstr "Insérer les Headers autorisant les requêtes cross domaine"
msgid "Save configuration"
msgstr "Enregistrer la configuration"
msgid "REST API configuration"
msgstr "Configurer l'API REST JSON"
msgid "Documentation and test interface Swagger UI"
msgstr "Documentation et interface de test de l'API via Swagger UI"
msgid "Your api key has already been created."
msgstr "Votre clef a déjà été générée"
msgid "Erase existing API key and generate a new one for"
msgstr "Réinitialiser la clef de "
msgid "No API key found."
msgstr "La clef de l'API n'a pas été initialisée"
msgid "Generate a API key for"
msgstr "Créer une clef pour"
msgid "Copy and paste it, You will cannot see it again."
msgstr "Copiez collez la. Cette clef ne pourra pas vous être refournie."

Before

Width:  |  Height:  |  Size: 675 B

After

Width:  |  Height:  |  Size: 675 B

Loading…
Cancel
Save