Skip to content

Commit 19e3b4a

Browse files
committed
fix: issues related permissions
1 parent db706a9 commit 19e3b4a

File tree

6 files changed

+184
-43
lines changed

6 files changed

+184
-43
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
**.logs
22
**.log
33
.idea/**
4-
vendor/**
4+
vendor
5+
ghooks.lock
File renamed without changes.

composer.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@
1313
"scripts": {
1414
"post-install-cmd": "vendor/bin/cghooks add --ignore-lock",
1515
"post-update-cmd": "vendor/bin/cghooks update",
16-
"fix-cs": "vendor/bin/php-cs-fixer fix --config=.php_cs -v",
17-
"check-cs": "vendor/bin/php-cs-fixer fix --dry-run --format=txt --verbose --diff --diff-format=udiff --config=.cs.php"
16+
"fix-cs": "vendor/bin/php-cs-fixer fix --config=.php_cs.php -v",
17+
"check-cs": "vendor/bin/php-cs-fixer fix --dry-run --format=txt --verbose --diff --diff-format=udiff --config=.php_cs.php"
1818
},
1919
"require": {
2020
"php": ">=5.6",

includes/classes/API.php

Lines changed: 177 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -698,7 +698,6 @@ public function get($query, $db = null)
698698
}
699699
}
700700
$group_columns = $selected_columns;
701-
$prefix_columns = $this->auth->addSelectPermissions($prefix_columns, $table, $prefix, $db);
702701
$select_columns = implode(', ', $prefix_columns);
703702
}
704703

@@ -842,21 +841,21 @@ public function get($query, $db = null)
842841
// bind WHERE values
843842
if (!empty($where_values) && count($where_values) > 0) {
844843
foreach ($where_values as $key => $value) {
845-
$value = $this->cleanConditionValue($value, $query['table'], $key, $db);
844+
$value = $this->parseValue($value, $query['table'], $key, $db);
846845
$type = self::detectPDOType($value);
847846
$key = ':' . $key;
848-
$sql_compiled = self::debugCompileSQL($sql_compiled, $key, $value);
847+
$sql_compiled = self::getPartialCompiledQuery($sql_compiled, $key, $value);
849848
$sth->bindValue($key, $value, $type);
850849
}
851850
}
852851

853852
// bind JOIN values
854853
if (!empty($join_values) && count($join_values) > 0) {
855854
foreach ($join_values as $key => $value) {
856-
$value = $this->cleanConditionValue($value, $query['table'], $key, $db);
855+
$value = $this->parseValue($value, $query['table'], $key, $db);
857856
$type = self::detectPDOType($value);
858857
$key = ':' . $key;
859-
$sql_compiled = self::debugCompileSQL($sql_compiled, $key, $value);
858+
$sql_compiled = self::getPartialCompiledQuery($sql_compiled, $key, $value);
860859
$sth->bindValue($key, $value, $type);
861860
}
862861
}
@@ -1133,18 +1132,18 @@ public function patch($query, $db = null, $skipChecks = false)
11331132

11341133
// bind PUT values
11351134
foreach ($column_values as $key => $value) {
1136-
$value = $this->cleanConditionValue($value, $table, $key, $db);
1135+
$value = $this->parseValue($value, $table, $key, $db);
11371136
$key = ':' . $key;
1138-
$sql_compiled = self::debugCompileSQL($sql_compiled, $key, $value);
1137+
$sql_compiled = self::getPartialCompiledQuery($sql_compiled, $key, $value);
11391138
$sth->bindValue($key, $value);
11401139
}
11411140

11421141
// bind WHERE values
11431142
if (!empty($where_values) && count($where_values) > 0) {
11441143
foreach ($where_values as $key => $value) {
1145-
$value = $this->cleanConditionValue($value, $table, $key, $db);
1144+
$value = $this->parseValue($value, $table, $key, $db);
11461145
$key = ':' . $key;
1147-
$sql_compiled = self::debugCompileSQL($sql_compiled, $key, $value);
1146+
$sql_compiled = self::getPartialCompiledQuery($sql_compiled, $key, $value);
11481147
$sth->bindValue($key, $value);
11491148
}
11501149
}
@@ -1211,6 +1210,10 @@ public function delete($query, $db = null)
12111210
$where_additional = $this->hooks->apply_filters('delete_query_additional_where', '', $query['table']);
12121211
$where_additional_table = $this->hooks->apply_filters('delete_query_additional_where_' . strtolower($query['table']), '', $query['table']);
12131212

1213+
if (empty(trim($restriction))) {
1214+
$restriction = "'1' = '1'";
1215+
}
1216+
12141217
$sql .= ($where_exists ? ' AND ' : ' WHERE ') . ' (' . $restriction . ') ';
12151218
$sql .= (!empty($where_additional) ? ' AND (' . $where_additional . ') ' : '');
12161219
$sql .= (!empty($where_additional_table) ? ' AND (' . $where_additional_table . ') ' : '');
@@ -1223,10 +1226,10 @@ public function delete($query, $db = null)
12231226
// bind WHERE values
12241227
if (!empty($where_values) && count($where_values) > 0) {
12251228
foreach ($where_values as $key => $value) {
1226-
$value = $this->cleanConditionValue($value, $query['table'], $key, $db);
1229+
$value = $this->parseValue($value, $query['table'], $key, $db);
12271230
$type = self::detectPDOType($value);
12281231
$key = ':' . $key;
1229-
$sql_compiled = self::debugCompileSQL($sql_compiled, $key, $value);
1232+
$sql_compiled = self::getPartialCompiledQuery($sql_compiled, $key, $value);
12301233
$sth->bindValue($key, $value, $type);
12311234
}
12321235
}
@@ -1288,10 +1291,10 @@ private function executeInsert($table, $columns, $db)
12881291

12891292
// bind POST values
12901293
foreach ($columns as $column => $value) {
1291-
$value = $this->cleanConditionValue($value, $table, $column);
1294+
$value = $this->parseValue($value, $table, $column);
12921295
$column = ':' . $column;
12931296
$sth->bindValue($column, $value);
1294-
$sql_compiled = self::debugCompileSQL($sql_compiled, $column, $value);
1297+
$sql_compiled = self::getPartialCompiledQuery($sql_compiled, $column, $value);
12951298
}
12961299

12971300
$this->logger->debug($sql_compiled);
@@ -1334,34 +1337,100 @@ public function render($data)
13341337
* @param $simple_encode
13351338
* @param $query
13361339
*/
1337-
public function renderJson($data, $simple_encode = false)
1340+
public function renderJson($data, $simple_encode = false, $complex = false)
13381341
{
1339-
@header('Content-type: application/json');
1340-
1341-
if (is_multi_array($data) && !$simple_encode) {
1342-
$prefix = '';
1343-
$output = '[';
1344-
foreach ($data as $key => $row) {
1345-
$output .= $prefix . json_encode($row);
1346-
$prefix = ',';
1347-
}
1348-
$output .= ']';
1342+
if ($complex) {
1343+
$output = $this->jsonStringify($data);
13491344
} else {
1350-
$output = json_encode($data);
1345+
// TODO: replace with jsonStringify method, need to do some checks
1346+
if (is_multi_array($data) && !$simple_encode) {
1347+
$prefix = '';
1348+
$output = '[';
1349+
foreach ($data as $row) {
1350+
$output .= $prefix . json_encode($row);
1351+
$prefix = ',';
1352+
}
1353+
$output .= ']';
1354+
} else {
1355+
$output = json_encode($data);
1356+
}
13511357
}
13521358

13531359
// Prepare a JSONP callback.
13541360
$callback = jsonp_callback_filter($this->query['callback']);
13551361

13561362
// Only send back JSONP if that's appropriate for the request.
13571363
if ($callback) {
1358-
echo "{$callback}($output);";
1364+
$output = "{$callback}($output);";
1365+
}
13591366

1360-
return;
1367+
$compressed = gzencode($output);
1368+
1369+
ob_clean();
1370+
1371+
@header('Content-Type: application/json');
1372+
@header('Content-Encoding: gzip');
1373+
@header('Content-Length: ' . strlen($compressed));
1374+
1375+
exit($compressed);
1376+
}
1377+
1378+
/**
1379+
* Encode large amount of data into JSON.
1380+
*
1381+
* @param mixed $data
1382+
*
1383+
* @return string
1384+
*/
1385+
public function jsonStringify($data, $path = 'json')
1386+
{
1387+
if (is_array($data) || is_object($data)) {
1388+
if (is_object($data)) {
1389+
$isNamedKey = true;
1390+
} else {
1391+
$isNamedKey = (is_string(key($data)));
1392+
}
1393+
if ($isNamedKey) {
1394+
$output = '{';
1395+
$prefix = '';
1396+
foreach ($data as $key => $value) {
1397+
$nextPath = $path . ".$key";
1398+
if (!is_numeric($key)) {
1399+
$key = '"' . $key . '"';
1400+
}
1401+
$stringify = $this->hooks->apply_filters('render_json_process', true, $nextPath);
1402+
if ($stringify) {
1403+
$content = $this->jsonStringify($value, $nextPath);
1404+
$content = $this->hooks->apply_filters('render_json_content', $content, $nextPath);
1405+
} else {
1406+
$content = $this->hooks->apply_filters('render_json_result', 'null', $nextPath);
1407+
}
1408+
$output .= $prefix . $key . ': ' . $content;
1409+
$prefix = ',';
1410+
}
1411+
$output .= '}';
1412+
} else {
1413+
$output = '[';
1414+
$prefix = '';
1415+
foreach ($data as $key => $value) {
1416+
$nextPath = $path . "[$key]";
1417+
$stringify = $this->hooks->apply_filters('render_json_process', true, $nextPath);
1418+
if ($stringify) {
1419+
$content = $this->jsonStringify($value, $nextPath);
1420+
$content = $this->hooks->apply_filters('render_json_content', $content, $nextPath);
1421+
} else {
1422+
$content = $this->hooks->apply_filters('render_json_result', 'null', $nextPath);
1423+
}
1424+
$output .= $prefix . $content;
1425+
$prefix = ',';
1426+
}
1427+
$output .= ']';
1428+
}
1429+
} else {
1430+
$output = json_encode($data);
13611431
}
1362-
// If not JSONP, send back the data.
1363-
echo $output;
1364-
exit();
1432+
1433+
return (string)$output;
13651434
}
13661435

13671436
/**
@@ -1637,10 +1706,11 @@ private function getTableColumnsMeta($table, $db = null)
16371706
* @param $table
16381707
* @param $key
16391708
* @param $db
1709+
* @param $forceNullable
16401710
*
16411711
* @return mixed
16421712
*/
1643-
private function cleanConditionValue($value, $table, $key, $db = null)
1713+
public function parseValue($value, $table, $key, $db = null, $forceNullable = false)
16441714
{
16451715
if (is_array($value)) {
16461716
$value = serialize($value);
@@ -1663,6 +1733,8 @@ private function cleanConditionValue($value, $table, $key, $db = null)
16631733
];
16641734
if (in_array($dataType, $numericDataType)) {
16651735
$value = ($isNullable) ? null : (float)$default;
1736+
} elseif ($forceNullable) {
1737+
$value = null;
16661738
}
16671739
}
16681740
}
@@ -1896,7 +1968,7 @@ private function parseWhere($main_table, $where, $sql)
18961968
$special_value = [$special_value];
18971969
}
18981970
foreach ($special_value as $v) {
1899-
$clean_value = $this->cleanConditionValue($v, $table, $column);
1971+
$clean_value = $this->parseValue($v, $table, $column);
19001972
if ($clean_value === null) {
19011973
$clean_value = ''; // Don't accept null
19021974
}
@@ -1938,7 +2010,7 @@ private function parseWhere($main_table, $where, $sql)
19382010
if (is_null($value)) {
19392011
$index_value = "''";
19402012
} else {
1941-
$clean_value = $this->cleanConditionValue($value, $table, $column);
2013+
$clean_value = $this->parseValue($value, $table, $column);
19422014
if ($clean_value === null) {
19432015
$clean_value = ''; // Don't accept null
19442016
}
@@ -1965,7 +2037,7 @@ private function parseWhere($main_table, $where, $sql)
19652037
if (count($_value_split) > 1 && $this->checkColumn(@$_value_split[1], @$_value_split[0])) {
19662038
$index_value = $_value_split[0] . '.' . $_value_split[1];
19672039
} else {
1968-
$clean_value = $this->cleanConditionValue($value, $table, $column);
2040+
$clean_value = $this->parseValue($value, $table, $column);
19692041
if ($clean_value === null) {
19702042
$clean_value = ''; // Don't accept null
19712043
}
@@ -2130,19 +2202,85 @@ private static function detectPDOType($value)
21302202
}
21312203

21322204
/**
2133-
* Compile PDO prepare.
2205+
* Returns the partial emulated SQL string.
21342206
*
21352207
* @param $string
21362208
* @param $key
21372209
* @param $value
21382210
*
2139-
* @return string|string[]|null
2211+
* @return string
2212+
*/
2213+
public static function getPartialCompiledQuery($query, $key, $value)
2214+
{
2215+
$value = self::getCompiledParamValue($value);
2216+
2217+
return preg_replace('/' . $key . "([,]|\s|$|\))/i", $value, $query);
2218+
}
2219+
2220+
/**
2221+
* Returns the emulated SQL string.
2222+
*
2223+
* @param string $query
2224+
* @param array $parameters
2225+
*
2226+
* @return string
2227+
*/
2228+
public static function getCompiledQuery($query, $parameters = [])
2229+
{
2230+
$keys = [];
2231+
$values = [];
2232+
2233+
/**
2234+
* Get longest keys first, so the regex replacement doesn't cut markers
2235+
* (ex : replace ":username" with "marco.cesarato" if we have a param name :user ).
2236+
*/
2237+
$isNamedMarkers = false;
2238+
if (count($parameters) && is_string(key($parameters))) {
2239+
uksort($parameters, function ($k1, $k2) {
2240+
return strlen($k2) - strlen($k1);
2241+
});
2242+
$isNamedMarkers = true;
2243+
}
2244+
foreach ($parameters as $key => $value) {
2245+
// Check if named parameters (':param') or anonymous parameters ('?') are used
2246+
if (is_string($key)) {
2247+
$keys[] = '/:' . ltrim($key, ':') . '/';
2248+
} else {
2249+
$keys[] = '/[?]/';
2250+
}
2251+
$values[] = self::getCompiledParamValue($value);
2252+
}
2253+
if ($isNamedMarkers) {
2254+
return preg_replace($keys, $values, $query);
2255+
}
2256+
2257+
return preg_replace($keys, $values, $query, 1, $count);
2258+
}
2259+
2260+
/**
2261+
* Bring parameter value into human-readable format.
2262+
*
2263+
* @param mixed $rawValue
2264+
*
2265+
* @return string
21402266
*/
2141-
public static function debugCompileSQL($string, $key, $value)
2267+
public static function getCompiledParamValue($rawValue)
21422268
{
2143-
$string = preg_replace('/' . $key . "([,]|\s|$|\))/i", ($value === null ? 'NULL$1' : "'" . $value . "'$1"), $string);
2269+
if (is_string($rawValue)) {
2270+
$value = "'" . addslashes($rawValue) . "'";
2271+
} elseif (is_numeric($rawValue)) {
2272+
$value = (string)$rawValue;
2273+
} elseif (is_array($rawValue)) {
2274+
$value = implode(',', $rawValue);
2275+
} elseif (is_null($rawValue)) {
2276+
$value = 'NULL';
2277+
} elseif (is_bool($rawValue)) {
2278+
$value = (string)($rawValue);
2279+
} else {
2280+
$value = (string)($rawValue);
2281+
}
21442282

2145-
return $string;
2283+
return $value;
21462284
}
21472285

21482286
/**

includes/classes/Logger.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
namespace marcocesarato\DatabaseAPI;
44

5+
use DateTime;
6+
57
/**
68
* Logger Class.
79
*

includes/loader.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
require_once __API_DIR_INCLUDES__ . '/compatibility.php';
2626
require_once __API_DIR_INCLUDES__ . '/functions.php';
2727

28-
disable_php_errors();
28+
enable_php_errors();
2929

3030
// Libs
3131
require_once __API_DIR_CLASSES__ . '/Hooks.php';

0 commit comments

Comments
 (0)