Adding Rest Api Service Support

Rest Service on plugins
-----------------------

1. enable service

add the following line in plugin __constructor main class
$this->enableRestService(true);

2. Create the sources directory structure by example:
if you plugin is named myPlugin

myPlugin
    |--src
        |--Services
             |--Api
                 |--MyPlugin
                      |--Test.php

Where Test.php is a Restler class
This commit is contained in:
Erik Amaru Ortiz
2013-12-03 17:10:18 -04:00
parent 47e4cc0ef1
commit b25efdd866
11 changed files with 203 additions and 113 deletions

View File

@@ -66,7 +66,7 @@ class Bootstrap
return;
}
public function registerDir($name, $dir)
public static function registerDir($name, $dir)
{
BootStrap::$includePaths[$name] = $dir;
}
@@ -1108,19 +1108,16 @@ class Bootstrap
*/
$pmOauthClientId = 'x-pm-local-client';
// load Api class
G::loadClass('api');
// Load Api ini file for Rest Service
/*
* Load Api ini file for Rest Service
*/
$apiIniConf = array();
if (file_exists($apiIniFile)) {
$apiIniConf = self::parseIniFile($apiIniFile);
}
// Setting current workspace to Api class
\ProcessMaker\Api::setWorkspace(SYS_SYS);
\ProcessMaker\Services\Api::setWorkspace(SYS_SYS);
// TODO remove this setting on the future, it is not needed, but if it is not present is throwing a warning
Luracast\Restler\Format\HtmlFormat::$viewPath = $servicesDir . 'oauth2/views';
@@ -1144,33 +1141,56 @@ class Bootstrap
$rest->setOverridingFormats('HtmlFormat', 'JsonFormat', 'UploadFormat');
// Override $_SERVER['REQUEST_URI'] to Restler handles the current url correctly
$_SERVER['REQUEST_URI'] = $uri;
// scan all api directory to find api classes
$classesList = Bootstrap::rglob('*', 0, $apiDir);
$isPluginRequest = strpos($uri, '/plugin-') !== false ? true : false;
foreach ($classesList as $classFile) {
if (pathinfo($classFile, PATHINFO_EXTENSION) === 'php') {
$namespace = '\\Services\\' . str_replace(
DIRECTORY_SEPARATOR,
'\\',
str_replace('.php', '', str_replace($servicesDir, '', $classFile))
);
//var_dump($namespace);
$rest->addAPIClass($namespace);
}
if ($isPluginRequest) {
$tmp = explode('/', $uri);
array_shift($tmp);
$tmp = array_shift($tmp);
$tmp = explode('-', $tmp);
$pluginName = $tmp[1];
$uri = str_replace('/plugin-'.$pluginName, '', $uri);
}
// adding aliases for Restler
if (array_key_exists('alias', $apiIniConf)) {
//print_r($apiIniConf['alias']); die;
foreach ($apiIniConf['alias'] as $alias => $aliasData) {
if (is_array($aliasData)) {
foreach ($aliasData as $label => $namespace) {
$namespace = '\\' . ltrim($namespace, '\\');
//var_dump($namespace, $alias);
$rest->addAPIClass($namespace, $alias);
$_SERVER['REQUEST_URI'] = $uri;
if (! $isPluginRequest) { // if it is not a request for a plugin endpoint
// scan all api directory to find api classes
$classesList = Bootstrap::rglob('*', 0, $apiDir);
foreach ($classesList as $classFile) {
if (pathinfo($classFile, PATHINFO_EXTENSION) === 'php') {
$namespace = '\\Services\\' . str_replace(
DIRECTORY_SEPARATOR,
'\\',
str_replace('.php', '', str_replace($servicesDir, '', $classFile))
);
//var_dump($namespace);
$rest->addAPIClass($namespace);
}
}
// adding aliases for Restler
if (array_key_exists('alias', $apiIniConf)) {
foreach ($apiIniConf['alias'] as $alias => $aliasData) {
if (is_array($aliasData)) {
foreach ($aliasData as $label => $namespace) {
$namespace = '\\' . ltrim($namespace, '\\');
$rest->addAPIClass($namespace, $alias);
}
}
}
}
} else {
// hook to get rest api classes from plugins
if (class_exists('PMPluginRegistry')) {
$pluginRegistry = & PMPluginRegistry::getSingleton();
$plugins = $pluginRegistry->getRegisteredRestServices();
if (is_array($plugins) && array_key_exists($pluginName, $plugins)) {
foreach ($plugins[$pluginName] as $class) {
$rest->addAPIClass($class['namespace']);
}
}
}

View File

@@ -341,10 +341,10 @@ class PMPlugin
* @param array/string $pluginJsFile
* @return void
*/
function registerRestService($classname, $path = '')
function registerRestService()
{
$oPluginRegistry =& PMPluginRegistry::getSingleton();
$oPluginRegistry->registerRestService($this->sNamespace, $classname, $path);
$oPluginRegistry->registerRestService($this->sNamespace);
}
/**
@@ -360,6 +360,12 @@ class PMPlugin
$oPluginRegistry =& PMPluginRegistry::getSingleton();
$oPluginRegistry->unregisterRestService($this->sNamespace, $classname, $path);
}
function enableRestService($enable)
{
$oPluginRegistry =& PMPluginRegistry::getSingleton();
$oPluginRegistry->enableRestService($this->sNamespace, $enable);
}
}
class menuDetail

View File

@@ -108,6 +108,8 @@ class PMPluginRegistry
*/
private $_restServices = array ();
private $_restServiceEnabled = array();
private static $instance = null;
/**
@@ -240,6 +242,27 @@ class PMPluginRegistry
if (method_exists( $oPlugin, 'enable' )) {
$oPlugin->enable();
}
/*
* 1. register <plugin-dir>/src directory for autoloading
* 2. verify if rest service is enabled
* 3. register rest service directory
*/
$pluginSrcDir = PATH_PLUGINS . $detail->sNamespace . PATH_SEP . 'src';
if (is_dir($pluginSrcDir)) {
Bootstrap::registerDir($detail->sNamespace.'/src', $pluginSrcDir);
}
if (array_key_exists($detail->sNamespace, $this->_restServiceEnabled)
&& $this->_restServiceEnabled[$detail->sNamespace] == true
) {
$oPlugin->registerRestService();
ProcessMaker\Util\Logger::log("plugin ".$detail->sNamespace." -> rest enabled");
} else {
ProcessMaker\Util\Logger::log("plugin ".$detail->sNamespace." -> rest not enabled");
}
return true;
}
}
@@ -1339,27 +1362,39 @@ class PMPluginRegistry
* @param string $path (optional) the class file path, if it is not set the system will try resolve the
* file path from its classname.
*/
public function registerRestService ($sNamespace, $classname, $path = '')
public function registerRestService($sNamespace)
{
$restService = new StdClass();
$restService->sNamespace = $sNamespace;
$restService->classname = $classname;
$baseSrcPluginPath = PATH_PLUGINS . $sNamespace . PATH_SEP . "src";
$apiPath = PATH_SEP . "Services" . PATH_SEP . "Api" . PATH_SEP . ucfirst($sNamespace);
$classesList = Bootstrap::rglob('*', 0, $baseSrcPluginPath . $apiPath);
if (empty( $path )) {
$path = PATH_PLUGINS . $restService->sNamespace . "/services/rest/$classname.php";
foreach ($classesList as $classFile) {
if (pathinfo($classFile, PATHINFO_EXTENSION) === 'php') {
if (! file_exists( $path )) {
$path = PATH_PLUGINS . $restService->sNamespace . "/services/rest/crud/$classname.php";
$ns = str_replace(
DIRECTORY_SEPARATOR,
'\\',
str_replace('.php', '', str_replace($baseSrcPluginPath, '', $classFile))
);
ProcessMaker\Util\Logger::log("Namespace found: " . $ns);
// Ensure that is registering only existent classes.
if (class_exists($ns)) {
$this->_restServices[strtolower($sNamespace)][] = array(
"filepath" => $classFile,
"namespace" => $ns
);
ProcessMaker\Util\Logger::log("class exists: YES");
} else {
ProcessMaker\Util\Logger::log("class exists: NO");
}
ProcessMaker\Util\Logger::log($this->_restServices);
}
}
if (! file_exists( $path )) {
return false;
}
$restService->path = $path;
$this->_restServices[] = $restService;
return true;
}
@@ -1370,31 +1405,14 @@ class PMPluginRegistry
*/
public function unregisterRestService ($sNamespace)
{
foreach ($this->_restServices as $i => $service) {
if ($sNamespace == $service->sNamespace) {
unset( $this->_restServices[$i] );
}
}
// Re-index when all js were unregistered
$this->_restServices = array_values( $this->_restServices );
unset($this->_restServices[$sNamespace]);
}
public function getRegisteredRestServices ()
public function getRegisteredRestServices()
{
return $this->_restServices;
}
public function getRegisteredRestClassFiles ()
{
$restClassFiles = array ();
foreach ($this->_restServices as $restService) {
$restClassFiles[] = $restService->path;
}
return $restClassFiles;
}
/**
* return all dashboard pages
*
@@ -1435,6 +1453,16 @@ class PMPluginRegistry
}
$language->updateLanguagePlugin($namePlugin, SYS_LANG);
}
}
}
/**
* Function to enable rest service for plugins
* @param string $sNamespace
* @param bool $enable
*/
function enableRestService($sNamespace, $enable)
{
$this->_restServiceEnabled[$sNamespace] = $enable;
}
}

View File

@@ -1,5 +1,5 @@
<?php
namespace ProcessMaker;
namespace ProcessMaker\Services;
class Api
{
@@ -31,9 +31,6 @@ class Api
public function getUserId()
{
//return self::$userId;
return \Api\OAuth2\Server::getUserId();
return \Services\Api\OAuth2\Server::getUserId();
}
}
}

View File

@@ -0,0 +1,40 @@
<?php
namespace ProcessMaker\Util;
class Logger
{
private static $instance;
private $logFile;
private $fp;
protected function __construct()
{
$this->logFile = sys_get_temp_dir() . '/processmaker.log';
$this->fp = fopen($this->logFile, "a+");
}
public static function getInstance()
{
if (is_null(self::$instance)) {
self::$instance = new Logger();
}
return self::$instance;
}
public function setLog($data)
{
if (! is_string($data)) {
$data = print_r($data, true);
}
fwrite($this->fp, "PM LOG: ".date('Y-m-d H:i:s') . " " . $data . PHP_EOL);
}
public static function log($data)
{
$me = Logger::getInstance();
$me->setLog($data);
}
}

View File

@@ -1,7 +1,7 @@
<?php
namespace Services\Api\ProcessMaker;
use \ProcessMaker\Api;
use \ProcessMaker\Services\Api;
use \Luracast\Restler\RestException;
//TODO we need Refactor this class

View File

@@ -1,7 +1,7 @@
<?php
namespace Services\Api\ProcessMaker\Project;
use \ProcessMaker\Api;
use \ProcessMaker\Services\Api;
use \Luracast\Restler\RestException;
/**

View File

@@ -1,42 +1,9 @@
<?php
namespace Services\Api\ProcessMaker\Project\Activity;
use \ProcessMaker\Api;
use \ProcessMaker\Services\Api;
use \Luracast\Restler\RestException;
class StepStructure
{
/**
* @var string {@from body}{@min 32}{@max 32}
*/
public $step_uid;
/**
* @var string {@from body}{@choice DYNAFORM,INPUT_DOCUMENT,OUTPUT_DOCUMENT}
*/
public $step_type_obj;
/**
* @var string {@from body}{@min 32}{@max 32}
*/
public $step_uid_obj;
/**
* @var string
*/
public $step_condition;
/**
* @var int {@from body}{@min 1}
*/
public $step_position;
/**
* @var string {@from body}{@choice EDIT,VIEW}
*/
public $step_mode;
}
/**
* Project\Activity\Step Api Controller
*
@@ -122,3 +89,35 @@ class Step extends Api
}
}
class StepStructure
{
/**
* @var string {@from body}{@min 32}{@max 32}
*/
public $step_uid;
/**
* @var string {@from body}{@choice DYNAFORM,INPUT_DOCUMENT,OUTPUT_DOCUMENT}
*/
public $step_type_obj;
/**
* @var string {@from body}{@min 32}{@max 32}
*/
public $step_uid_obj;
/**
* @var string
*/
public $step_condition;
/**
* @var int {@from body}{@min 1}
*/
public $step_position;
/**
* @var string {@from body}{@choice EDIT,VIEW}
*/
public $step_mode;
}

View File

@@ -1,7 +1,7 @@
<?php
namespace Services\Api\ProcessMaker;
use \ProcessMaker\Api;
use \ProcessMaker\Services\Api;
use \Luracast\Restler\RestException;
class Test extends Api

View File

@@ -1,7 +1,7 @@
<?php
namespace Services\Api\ProcessMaker;
use \ProcessMaker\Api;
use \ProcessMaker\Services\Api;
use \Luracast\Restler\RestException;
class Test2 extends Api

View File

@@ -1,7 +1,7 @@
<?php
namespace Services\Api\ProcessMaker;
use \ProcessMaker\Api;
use \ProcessMaker\Services\Api;
use \Luracast\Restler\RestException;
class Test3 extends Api