JsonData 3.x

From Cloudrexx Development Wiki
Jump to: navigation, search

Introduction

JsonData is a gateway to adapters which are generating JSON encoded data.

Note: This documentation refers to version 3.x. For newer versions of Cloudrexx, please refer to Exposed methods.

Idea

All JSON data will be handled in a central processing controller (JsonData), so it is easy to e.g. add safety measures only in one controller.

Usage

JsonData is a way to expose methods to the outside world. This can be used for AJAX requests or callbacks. For API-like cases you should use the RESTful API.

The method JsonData->data() (and JsonData->jsondata() too) will return data in the following structure (data() as an associative array, jsondata() as JSON object):

array(
    'status' => 'success'|'error',
    'message' => $msg,
    ['data' => $data,]
);

Implement a JsonAdapter

Contrexx 3.0

A JsonAdapter must fulfill the following requirements:

  • The adapter is located in /core/Json/Adapter/{Component}/Json{Object}.php (e.g. /core/Json/Adapter/ContentManager/JsonNode.php)
  • The adapter is located in the namespace \Cx\Core\Json\Adapter\{Component} (e.g. \Cx\Core\Json\Adapter\ContentManager\JsonNode)
  • The adapter implements the interface \Cx\Core\Json\JsonAdapter
  • The adapters are listed in a static array: \Cx\Core\Json\JsonData::$adapter_classes

A JsonAdapter should fulfill the following requirements:

  • It returns an array which does not return JSON objects, JsonData will convert it recursively
    • If this is not so, the method \Cx\Core\Json\JsonData->data() will not return useful output

A JsonAdapter can use the following things:

  • Methods, which are not in the array (returned by getAccessibleMethods()) and which are not accessible via JsonData

Contrexx 3.1/3.2/4.0

A JsonAdapter is a controller of a Component that implements \Cx\Core\Json\JsonAdapter and is registered as a Controller exposed to JsonData.

Step 1: Create adapter

Create a new controller in the component's controller directory: <your_component_directory>/Controller/Json<object_name>Controller.php (i.e. /modules/DemoModule/Controller/JsonDemoModuleController.php)

The adapter (/controller) must fulfill the following requirements:

  • Adapter must be in same Namespace as its component (i.e. \Cx\Modules\DemoModule\Controller)
  • Adapter must implement the Interface \Cx\Core\Json\JsonAdapter
  • Adapter must extend Cx\Core\Core\Model\Entity\Controller
  • Methods that shall be accessible using the JsonData AJAX interface must be listed in the array that is returned by the method getAccessableMethods()
    • The return type of those methods (accessible by the JsonData AJAX interface) must be an Array

Check out the following JsonAdapter example (i.e. of file /modules/DemoModule/Controller/JsonDemoModuleController.php):

<?php

/**
 * JSON Adapter for DemoModule
 * @copyright   your company
 * @author      your name <your-email-address>
 * @package     contrexx
 * @subpackage  module_DemoModule
 */

namespace Cx\Modules\DemoModule\Controller;

/**
 * JSON Adapter for DemoModule
 * @copyright   your company
 * @author      your name <your-email-address>
 * @package     contrexx
 * @subpackage  module_DemoModule
 */
class JsonDemoModuleController extends \Cx\Core\Core\Model\Entity\Controller implements \Cx\Core\Json\JsonAdapter {
    
    /**
     * Returns the internal name used as identifier for this adapter
     * @return String Name of this adapter
     */
    public function getName() {
        return parent::getName();
    }
    
    /**
     * Returns an array of method names accessable from a JSON request
     * @return array List of method names
     */
    public function getAccessableMethods() {
        return array('getData');
    }

    /**
     * Returns all messages as string
     * @return String HTML encoded error messages
     */
    public function getMessagesAsString() {
        return '';
    }
    
    /**
     * Returns an array containing some data
     * @return array Array containing data
     */
    public function getData() {
        // add some data to $arrData that you would like to return through the JsonAdapter
        $arrData = array('data' => 'Hello World');
        return $arrData;
    }
}
Step 2: Register JsonAdapter

The JsonAdapter must be registered by the component's ComponentController using the method getControllersAccessableByJson(). Please keep in mind that every controller needs to be registered as a controller using getControllerClasses().

Check out the following example for a component's ComponentController (i.e. of file /modules/DemoModule/Controller/ComponentController.class.php):

<?php
/**
 * Main controller for DemoModule
 * 
 * @author your name <your-email-address>
 * @package contrexx
 * @subpackage module_DemoModule
 */

namespace Cx\Modules\DemoModule\Controller;

/**
 * Main controller for DemoModule
 * 
 * @author your name <your-email-address>
 * @package contrexx
 * @subpackage module_DemoModule
 */
class ComponentController extends \Cx\Core\Core\Model\Entity\SystemComponentController {

    public function getControllersClasses() {
        return array(
            'JsonDemoModule',
        );
    }

    public function getControllersAccessableByJson() {
        return array(
            'JsonDemoModuleController',
        );
    }
}

Return error-state and -message

  • To return an error state and an according message, the adapter has to throw a new Exception with the message as Exception message.

Get data from adapter

From JavaScript

Through JsonData AJAX Interface

The JsonData adapters (as implemented in section Implement a JsonAdapter) can be accessed using the following JavaScript code:

cx.ajax(
    "$nameOfJsonAdapter",
    "$methodNameOfJsonAdapter",
    {
        // normal jQuery.ajax() options
        data: {
            // additional parameters to pass to the JsonData's method
        },
        success: function(json) {
            // handle response
        }
    }
);
Variable Description Example
$nameOfJsonAdapter The name of the JsonData-Adapter. This must be the same value as the one that is returned by the method getName() of the JsonAdapter. DemoModule
$methodNameOfJsonAdapter The method name of the JsonData-Adapter that shall be called getData
Example for the JsonDemoModule adapter defined in above section Implement a JsonAdapter

Execute the following JavaScript code from within the Backend:

cx.ajax(
    "DemoModule",
    "getData",
    {
        // normal jQuery.ajax() options
        data: {
            // additional parameters to pass to the JsonData's method
        },
        success: function(json) {
            // handle response
        }
    }
);
Example using JsonNode adapter of Content Manager

The following code calls the method getPageTitlesTree() of the JsonNode adapter without parameters:

cx.ajax(
         "block", // Equal to the return value of getName()
         "getBlocks", // Equal to the method name
         {
             data: {
                 // more parameters, which should be available for the method to use
             },
             success: function(json) {
                 // handle response
             }
         }
);

Using endpoint directly

Json adapters can be accessed using the following endpoint:

/api/Data/Json/<adapterName>/<method>[<params>]

Get data via PHP

JSON

Never call adapters directly, use JsonData everytime!

The following code calls the method getPageTitlesTree() of the JsonNode adapter without parameters:

$jsonData =  new \Cx\Core\Json\JsonData();
$pageTitlesTree = $jsonData->jsondata('node', 'getPageTitlesTree', array(), false);

Array for further processing

If the data have to be processed further, an associative array can be get instead of a JSON object:

$jsonData =  new \Cx\Core\Json\JsonData();
$pageTitlesTree = $jsonData->data('node', 'getPageTitlesTree');

After the processing the array can be converted to a json (use JsonData!).

$jsonData->json($pageTitlesTree);

From command-line

Json adapters can be accessed using the following command:

./cx Data Json <adapterName> <method>[ <params>]

Security

This version of JsonData does not contain a security layer. JsonData does not handle permissions for the Frontend and neither for the Backend. Therefore, the adapters have to implement a security layer by themselves.