diff --git a/module/api/control.php b/module/api/control.php index 47f9ff8373..2543fd3430 100755 --- a/module/api/control.php +++ b/module/api/control.php @@ -158,7 +158,7 @@ class api extends control /* Append id for second sort. */ $sort = common::appendOrder($orderBy); - $releases = $this->api->getReleaseByQuery($libID, '', $sort); + $releases = $this->api->getReleaseByQuery(array($libID), '', $sort); $this->view->title = $this->lang->api->managePublish; $this->view->releases = $releases; @@ -719,16 +719,16 @@ class api extends control if(strpos($fileDirPath, $this->app->getModuleRoot()) !== 0 && strpos($fileDirPath, $this->app->getExtensionRoot()) !== 0) return; if($action == 'extendModel') { - $method = $this->api->getMethod($filePath, 'Model'); + $method = $this->apiZen->getMethod($filePath, 'Model'); } elseif($action == 'extendControl') { - $method = $this->api->getMethod($filePath); + $method = $this->apiZen->getMethod($filePath); } if(!empty($_POST)) { - $result = $this->api->request($method->className, $method->methodName, $action); + $result = $this->apiZen->request($method->className, $method->methodName, $action); $content = json_decode($result['content']); $status = zget($content, 'status', ''); $data = isset($content->data) ? json_decode($content->data) : ''; diff --git a/module/api/model.php b/module/api/model.php index 90912e4c60..2e891675b3 100644 --- a/module/api/model.php +++ b/module/api/model.php @@ -515,13 +515,13 @@ class apiModel extends model * 获取指定文档库下的数据结构列表。 * Get release list by lib id. * - * @param int $libID + * @param array $libID * @param object $pager * @param string $orderBy * @access public * @return array */ - public function getReleaseByQuery(int $libID, object $pager = null, string $orderBy = ''): array + public function getReleaseByQuery(array $libID, object $pager = null, string $orderBy = ''): array { return $this->dao->select('*')->from(TABLE_API_LIB_RELEASE) ->where('lib')->in($libID) @@ -531,151 +531,31 @@ class apiModel extends model } /** - * Get struct tree by lib id - * - * @param int $libID - * @param int $structID - * @access public - * @return string - */ - public function getStructTreeByLib($libID = 0, $structID = 0) - { - $list = $this->getStructListByLibID($libID); - - $html = ""; - - return $html; - } - - /** - * Get the details of the method by file path. - * - * @param string $filePath - * @param string $ext - * @access public - * @return object - */ - public function getMethod($filePath, $ext = '') - { - $fileName = dirname($filePath); - $className = basename(dirname(dirname($filePath))); - if(!class_exists($className)) helper::import($fileName); - $methodName = basename($filePath); - - $method = new ReflectionMethod($className . $ext, $methodName); - $data = new stdClass(); - $data->startLine = $method->getStartLine(); - $data->endLine = $method->getEndLine(); - $data->comment = $method->getDocComment(); - $data->parameters = $method->getParameters(); - $data->className = $className; - $data->methodName = $methodName; - $data->fileName = $fileName; - $data->post = false; - - $file = file($fileName); - for($i = $data->startLine - 1; $i <= $data->endLine; $i++) - { - if(strpos($file[$i], '$this->post') or strpos($file[$i], 'fixer::input') or strpos($file[$i], '$_POST')) - { - $data->post = true; - } - } - return $data; - } - - /** - * Request the api. - * - * @param string $moduleName - * @param string $methodName - * @param string $action - * @access public - * @return array - */ - public function request($moduleName, $methodName, $action) - { - $host = common::getSysURL(); - $param = ''; - if($action == 'extendModel') - { - if(!isset($_POST['noparam'])) - { - foreach($_POST as $key => $value) $param .= ',' . $key . '=' . $value; - $param = ltrim($param, ','); - } - $url = rtrim($host, '/') . inlink('getModel', "moduleName=$moduleName&methodName=$methodName¶ms=$param", 'json'); - $url .= strpos($url, '?') === false ? '?' : '&'; - $url .= $this->config->sessionVar . '=' . session_id(); - } - else - { - if(!isset($_POST['noparam'])) - { - foreach($_POST as $key => $value) $param .= '&' . $key . '=' . $value; - $param = ltrim($param, '&'); - } - $url = rtrim($host, '/') . helper::createLink($moduleName, $methodName, $param, 'json'); - $url .= strpos($url, '?') === false ? '?' : '&'; - $url .= $this->config->sessionVar . '=' . session_id(); - } - - /* Unlock session. After new request, restart session. */ - session_write_close(); - $content = file_get_contents($url); - session_start(); - - return array('url' => $url, 'content' => $content); - } - - /** + * 查询SQL语句并返回结果。 * Query sql. * - * @param string $sql - * @param string $keyField + * @param string $sql + * @param string $keyField * @access public * @return array */ - public function sql($sql, $keyField = '') + public function sql(string $sql, string $keyField = '') { + /* 检查允许接口调用SQL的配置项是否打开。 */ if(!$this->config->features->apiSQL) return sprintf($this->lang->api->error->disabled, '$config->features->apiSQL'); $sql = trim($sql); if(strpos($sql, ';') !== false) $sql = substr($sql, 0, strpos($sql, ';')); - $result = array(); - $result['status'] = 'fail'; - $result['message'] = ''; + /* 如果没传SQL参数,则无法进行下一步。 */ + if(empty($sql)) return array('status' => 'fail', 'message' => ''); - if(empty($sql)) return $result; - - if(stripos($sql, 'select ') !== 0) - { - $result['message'] = $this->lang->api->error->onlySelect; - return $result; - } + /* 如果SQL语句中没有select单词,则无法进行下一步。 */ + if(stripos($sql, 'select ') !== 0) return array('status' => 'fail', 'message' => $this->lang->api->error->onlySelect); try { $stmt = $this->dbh->query($sql); - $rows = array(); if(empty($keyField)) { @@ -683,16 +563,15 @@ class apiModel extends model } else { + /* 用keyFiled作为键展示查询结果。 */ while($row = $stmt->fetch()) $rows[$row->$keyField] = $row; } - $result['status'] = 'success'; - $result['data'] = $rows; + $result = array('status' => 'success', 'data' => $rows); } catch(PDOException $e) { - $result['status'] = 'fail'; - $result['message'] = $e->getMessage(); + $result = array('status' => 'fail', 'message' => $e->getMessage()); } return $result; diff --git a/module/api/test/model/getbyid.php b/module/api/test/model/getbyid.php index 6e7d8ce8c5..eced645ed9 100755 --- a/module/api/test/model/getbyid.php +++ b/module/api/test/model/getbyid.php @@ -9,7 +9,7 @@ zdTable('api_lib_release')->gen(10); /** -title=测试 apiModel->getById(); +title=测试 apiModel->getByID(); timeout=0 cid=1 diff --git a/module/api/test/model/sql.php b/module/api/test/model/sql.php new file mode 100755 index 0000000000..3da4f1965b --- /dev/null +++ b/module/api/test/model/sql.php @@ -0,0 +1,52 @@ +#!/usr/bin/env php +gen(10); + +/** + +title=测试 apiModel->sql(); +timeout=0 +cid=1 + +- 在没启用配置的时候调用sql接口。 @因为安全原因,该功能被禁用。可以到config目录,修改配置项 $config->features->apiSQL,打开此功能。 +- SQL语句为空时调用sql接口。 + - 属性status @fail + - 属性message @` ` +- SQL语句不符合规范时调用sql接口。 + - 属性status @fail + - 属性message @SQL查询接口只允许SELECT查询 +- 使用正确的SQL查询调用sql接口。 + - 第0条的id属性 @1 + - 第0条的title属性 @BUG接口1 + - 第1条的id属性 @2 + - 第1条的title属性 @BUG接口2 +- 使用正确的SQL查询并按照以id作为键返回sql接口的查询结果。 + - 第1条的id属性 @1 + - 第1条的title属性 @BUG接口1 + - 第2条的id属性 @2 + - 第2条的title属性 @BUG接口2 + +*/ + +global $tester, $config; +$tester->loadModel('api'); + +$sql = ''; +$config->features->apiSQL = false; +r($tester->api->sql($sql)) && p() && e('因为安全原因,该功能被禁用。可以到config目录,修改配置项 $config->features->apiSQL,打开此功能。'); //在没启用配置的时候调用sql接口。 + +$config->features->apiSQL = true; +r($tester->api->sql($sql)) && p('status,message') && e('fail,` `'); //SQL语句为空时调用sql接口。 + +$sql = 'delete from zt_api'; +r($tester->api->sql($sql)) && p('status,message') && e('fail,SQL查询接口只允许SELECT查询'); //SQL语句不符合规范时调用sql接口。 + +$sql = 'select * from zt_api'; +$result = $tester->api->sql($sql); +r($result['data']) && p('0:id,title;1:id,title') && e('1,BUG接口1,2,BUG接口2'); //使用正确的SQL查询调用sql接口。 + +$result = $tester->api->sql($sql, 'id'); +r($result['data']) && p('1:id,title;2:id,title') && e('1,BUG接口1,2,BUG接口2'); //使用正确的SQL查询并按照以id作为键返回sql接口的查询结果。 diff --git a/module/api/zen.php b/module/api/zen.php index 60eb098822..04e5c574fa 100644 --- a/module/api/zen.php +++ b/module/api/zen.php @@ -111,4 +111,90 @@ class apiZen extends api $objectDropdown['link'] = helper::createLink('api', 'ajaxGetDropMenu', "objectType=$objectType&objectID=$objectID&libID=$lib->id&version=$version"); return $objectDropdown; } + + /** + * 解析请求地获得请求的详细信息。 + * Get the details of the method by file path. + * + * @param string $filePath + * @param string $ext + * @access public + * @return object + */ + public function getMethod(string $filePath, string $ext = ''): object + { + $fileName = dirname($filePath); + $className = basename(dirname(dirname($filePath))); + $methodName = basename($filePath); + + if(!class_exists($className)) helper::import($fileName); + $method = new ReflectionMethod($className . $ext, $methodName); + $data = new stdClass(); + + $data->startLine = $method->getStartLine(); + $data->endLine = $method->getEndLine(); + $data->comment = $method->getDocComment(); + $data->parameters = $method->getParameters(); + $data->className = $className; + $data->methodName = $methodName; + $data->fileName = $fileName; + $data->post = false; + + $file = file($fileName); + for($i = $data->startLine - 1; $i <= $data->endLine; $i++) + { + if(strpos($file[$i], '$this->post') or strpos($file[$i], 'fixer::input') or strpos($file[$i], '$_POST')) + { + $data->post = true; + } + } + return $data; + } + + /** + * 对指定模块下的指定方法进行调用并返回请求结果。 + * Request the api. + * + * @param string $moduleName + * @param string $methodName + * @param string $action extendModel | extendControl + * @access public + * @return array + */ + public function request(string $moduleName, string $methodName, string $action): array + { + $host = common::getSysURL(); + $param = ''; + if($action == 'extendModel') + { + /* 对model的函数进行调用。 */ + if(!isset($_POST['noparam'])) + { + foreach($_POST as $key => $value) $param .= ',' . $key . '=' . $value; + $param = ltrim($param, ','); + } + $url = rtrim($host, '/') . inlink('getModel', "moduleName=$moduleName&methodName=$methodName¶ms=$param", 'json'); + $url .= strpos($url, '?') === false ? '?' : '&'; + $url .= $this->config->sessionVar . '=' . session_id(); + } + else + { + /* 对control的函数进行调用。 */ + if(!isset($_POST['noparam'])) + { + foreach($_POST as $key => $value) $param .= '&' . $key . '=' . $value; + $param = ltrim($param, '&'); + } + $url = rtrim($host, '/') . helper::createLink($moduleName, $methodName, $param, 'json'); + $url .= strpos($url, '?') === false ? '?' : '&'; + $url .= $this->config->sessionVar . '=' . session_id(); + } + + /* Unlock session. After new request, restart session. */ + session_write_close(); + $content = file_get_contents($url); + session_start(); + + return array('url' => $url, 'content' => $content); + } }