Release note v15.3

------------------
### Fixes
 * Fix issue: classes should be loaded even the module is disabled
 * Deleting the only Admin user is not allowed
 * Fixes for handling non UTF-8
 * Fix for non-mandatory select boxes are shown as mandatory
This commit is contained in:
Thilina Hasantha
2016-04-15 15:53:14 +05:30
parent 9ffa8617e9
commit 6fd9ba20c8
21 changed files with 1447 additions and 60 deletions

View File

@@ -65,6 +65,10 @@ abstract class AbstractModuleManager{
*/
public abstract function setupModuleClassDefinitions();
public function initCalculationHooks(){
}
public function initQuickAccessMenu(){
}
@@ -207,6 +211,10 @@ abstract class AbstractModuleManager{
$eh->Save();
}
public function addCalculationHook($code, $name, $class, $method){
BaseService::getInstance()->addCalculationHook($code, $name, $class, $method);
}
}

View File

@@ -46,7 +46,8 @@ class BaseService{
var $emailSender = null;
var $user = null;
var $historyManagers = array();
var $calculationHooks = array();
private static $me = null;
private function __construct(){
@@ -131,10 +132,15 @@ class BaseService{
LogManager::getInstance()->debug("Query: "."1=1".$query.$orderBy);
LogManager::getInstance()->debug("Query Data: ".print_r($queryData,true));
$list = $obj->Find("1=1".$query.$orderBy,$queryData);
}
}
$newList = array();
foreach($list as $listObj){
$newList[] = $this->cleanUpAdoDB($listObj);
}
if(!empty($mappingStr) && count($map)>0){
$list = $this->populateMapping($list, $map);
$list = $this->populateMapping($newList, $map);
}
return $list;
@@ -363,7 +369,7 @@ class BaseService{
$processedList = array();
foreach($list as $obj){
$processedList[] = $obj->postProcessGetData($obj);
$processedList[] = $this->cleanUpAdoDB($obj->postProcessGetData($obj));
}
$list = $processedList;
@@ -488,7 +494,8 @@ class BaseService{
}
}
}
return $obj->postProcessGetData($obj);
$obj = $obj->postProcessGetElement($obj);
return $this->cleanUpAdoDB($obj->postProcessGetData($obj));
}
return null;
}
@@ -685,6 +692,7 @@ class BaseService{
}
foreach($list as $obj){
$obj = $this->cleanUpAdoDB($obj);
if(count($values) == 1){
$ret[$obj->$key] = $obj->$value;
}else{
@@ -1258,6 +1266,60 @@ class BaseService{
return $obj;
}
public function addCalculationHook($code, $name, $class, $method){
$calcualtionHook = new CalculationHook();
$calcualtionHook->code = $code;
$calcualtionHook->name = $name;
$calcualtionHook->class = $class;
$calcualtionHook->method = $method;
$this->calculationHooks[$code] = $calcualtionHook;
}
public function getCalculationHooks(){
return array_values($this->calculationHooks);
}
public function getCalculationHook($code){
return $this->calculationHooks[$code];
}
public function executeCalculationHook($parameters, $code = NULL){
$ch = BaseService::getInstance()->getCalculationHook($code);
if(empty($ch->code)){
return null;
}
$class = $ch->class;
return call_user_func_array(array(new $class(), $ch->method), $parameters);
}
public function cleanNonUTFChar($obj){
$regex = <<<'END'
/
(
(?: [\x00-\x7F] # single-byte sequences 0xxxxxxx
| [\xC0-\xDF][\x80-\xBF] # double-byte sequences 110xxxxx 10xxxxxx
| [\xE0-\xEF][\x80-\xBF]{2} # triple-byte sequences 1110xxxx 10xxxxxx * 2
| [\xF0-\xF7][\x80-\xBF]{3} # quadruple-byte sequence 11110xxx 10xxxxxx * 3
){1,100} # ...one or more times
)
| . # anything else
/x
END;
if(is_string($obj)){
return preg_replace($regex, '$1', $obj);
}else{
foreach($obj as $key => $val){
$obj->$key = preg_replace($regex, '$1', $val);
}
return $obj;
}
}
}

View File

@@ -102,7 +102,7 @@ class IceCron{
return true;
}
}else{
if(intval(date('m')) <= intval($time) && date('H') != date('H',strtotime($lastRunTime))){
if(intval(date('i')) <= intval($time) && date('H') != date('H',strtotime($lastRunTime))){
return true;
}
}
@@ -113,7 +113,7 @@ class IceCron{
return true;
}
}else{
if(intval(date('H')) <= intval($time) && date('d') != date('d',strtotime($lastRunTime))){
if(intval(date('H')) >= intval($time) && date('d') != date('d',strtotime($lastRunTime))){
return true;
}
}
@@ -124,7 +124,7 @@ class IceCron{
return true;
}
}else{
if(intval(date('d')) <= intval($time) && date('m') != date('m',strtotime($lastRunTime))){
if(intval(date('d')) >= intval($time) && date('m') != date('m',strtotime($lastRunTime))){
return true;
}
}
@@ -134,7 +134,7 @@ class IceCron{
return true;
}
}else{
if(intval(date('m')) <= intval($time) && date('Y') != date('Y',strtotime($lastRunTime))){
if(intval(date('m')) >= intval($time) && date('Y') != date('Y',strtotime($lastRunTime))){
return true;
}
}

176
src/classes/Macaw.php Executable file
View File

@@ -0,0 +1,176 @@
<?php
namespace NoahBuscher\Macaw;
/**
* @method static Macaw get(string $route, Callable $callback)
* @method static Macaw post(string $route, Callable $callback)
* @method static Macaw put(string $route, Callable $callback)
* @method static Macaw delete(string $route, Callable $callback)
* @method static Macaw options(string $route, Callable $callback)
* @method static Macaw head(string $route, Callable $callback)
*/
class Macaw
{
public static $halts = false;
public static $routes = array();
public static $methods = array();
public static $callbacks = array();
public static $patterns = array(
':any' => '[^/]+',
':num' => '[0-9]+',
':all' => '.*'
);
public static $error_callback;
/**
* Defines a route w/ callback and method
*/
public static function __callstatic($method, $params)
{
$uri = dirname($_SERVER['PHP_SELF']).$params[0];
$callback = $params[1];
array_push(self::$routes, $uri);
array_push(self::$methods, strtoupper($method));
array_push(self::$callbacks, $callback);
}
/**
* Defines callback if route is not found
*/
public static function error($callback)
{
self::$error_callback = $callback;
}
public static function haltOnMatch($flag = true)
{
self::$halts = $flag;
}
/**
* Runs the callback for the given request
*/
public static function dispatch()
{
$uri = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
$method = $_SERVER['REQUEST_METHOD'];
$searches = array_keys(static::$patterns);
$replaces = array_values(static::$patterns);
$found_route = false;
self::$routes = str_replace('//', '/', self::$routes);
// check if route is defined without regex
if (in_array($uri, self::$routes)) {
$route_pos = array_keys(self::$routes, $uri);
foreach ($route_pos as $route) {
//using an ANY option to match both GET and POST requests
if (self::$methods[$route] == $method || self::$methods[$route] == 'ANY') {
$found_route = true;
//if route is not an object
if(!is_object(self::$callbacks[$route])){
//grab all parts based on a / separator
$parts = explode('/',self::$callbacks[$route]);
//collect the last index of the array
$last = end($parts);
//grab the controller name and method call
$segments = explode('@',$last);
//instanitate controller
$controller = new $segments[0]();
//call method
$controller->$segments[1]();
if (self::$halts) return;
} else {
//call closure
call_user_func(self::$callbacks[$route]);
if (self::$halts) return;
}
}
}
} else {
// check if defined with regex
$pos = 0;
foreach (self::$routes as $route) {
if (strpos($route, ':') !== false) {
$route = str_replace($searches, $replaces, $route);
}
if (preg_match('#^' . $route . '$#', $uri, $matched)) {
if (self::$methods[$pos] == $method) {
$found_route = true;
array_shift($matched); //remove $matched[0] as [1] is the first parameter.
if(!is_object(self::$callbacks[$pos])){
//grab all parts based on a / separator
$parts = explode('/',self::$callbacks[$pos]);
//collect the last index of the array
$last = end($parts);
//grab the controller name and method call
$segments = explode('@',$last);
//instanitate controller
$controller = new $segments[0]();
//fix multi parameters
if(!method_exists($controller, $segments[1])){
echo "controller and action not found";
}else{
call_user_func_array(array($controller, $segments[1]), $matched);
}
//call method and pass any extra parameters to the method
// $controller->$segments[1](implode(",", $matched));
if (self::$halts) return;
} else {
call_user_func_array(self::$callbacks[$pos], $matched);
if (self::$halts) return;
}
}
}
$pos++;
}
}
// run the error callback if the route was not found
if ($found_route == false) {
if (!self::$error_callback) {
self::$error_callback = function() {
header($_SERVER['SERVER_PROTOCOL']." 404 Not Found");
echo '404';
};
}
call_user_func(self::$error_callback);
}
}
}

View File

@@ -49,14 +49,14 @@ class RestApiManager{
$accessToken = $this->generateUserAccessToken($user)->getData();
if(!empty($accessTokenObj->id)){
$accessTokenObj->token = $accessToken;
$accessTokenObj->hash = base64_encode(CLIENT_BASE_URL).":".md5($accessTokenObj->token);
$accessTokenObj->hash = md5(CLIENT_BASE_URL.$accessTokenObj->token);
$accessTokenObj->updated = date("Y-m-d H:i:s");
$accessTokenObj->Save();
}else{
$accessTokenObj = new RestAccessToken();
$accessTokenObj->userId = $user->id;
$accessTokenObj->token = $accessToken;
$accessTokenObj->hash = base64_encode(CLIENT_BASE_URL).":".md5($accessTokenObj->token);
$accessTokenObj->hash = md5(CLIENT_BASE_URL.$accessTokenObj->token);
$accessTokenObj->updated = date("Y-m-d H:i:s");
$accessTokenObj->created = date("Y-m-d H:i:s");
$accessTokenObj->Save();
@@ -69,13 +69,14 @@ class RestApiManager{
public function validateAccessToken($hash){
$accessTokenObj = new RestAccessToken();
LogManager::getInstance()->info("AT Hash:".$hash);
$accessTokenObj->Load("hash = ?",array($hash));
LogManager::getInstance()->info("AT Hash Object:".json_encode($accessTokenObj));
if(!empty($accessTokenObj->id) && $accessTokenObj->hash == $hash){
return $this->validateAccessTokenInner($accessTokenObj->token);
}
return new IceResponse(IceResponse::ERROR, "Acess Token not found");
return new IceResponse(IceResponse::ERROR, "Access Token not found");
}
private function validateAccessTokenInner($accessToken){
@@ -122,30 +123,40 @@ class RestApiManager{
class RestEndPoint{
var $url;
public function setUrl($url){
$this->url = $url;
public function process($type , $parameter = NULL){
$resp = $this->$type($parameter);
$this->printResponse($resp);
}
public function getUrl(){
return $this->url;
public function get($parameter){
return new IceResponse(IceResponse::ERROR, "Method not Implemented");
}
public function get($parameters){
return new IceResponse(IceResponse::ERROR, false);
public function post($parameter){
return new IceResponse(IceResponse::ERROR, "Method not Implemented");
}
public function post($parameters){
return new IceResponse(IceResponse::ERROR, false);
public function put($parameter){
return new IceResponse(IceResponse::ERROR, "Method not Implemented");
}
public function put($parameters){
return new IceResponse(IceResponse::ERROR, false);
public function delete($parameter){
return new IceResponse(IceResponse::ERROR, "Method not Implemented");
}
public function delete($parameters){
return new IceResponse(IceResponse::ERROR, false);
public function clearObject($obj){
return BaseService::getInstance()->cleanUpAdoDB($obj);
}
public function validateAccessToken(){
$accessTokenValidation = RestApiManager::getInstance()->validateAccessToken($_REQUEST['access_token']);
return $accessTokenValidation;
}
public function printResponse($response){
echo json_encode($response,JSON_PRETTY_PRINT);
}
}