From 1e9263bd6434be9e35967fc3a4ee2ca0fabb3d49 Mon Sep 17 00:00:00 2001 From: Matheus Garcia Date: Tue, 28 Sep 2021 17:32:08 -0300 Subject: [PATCH] =?UTF-8?q?Esqueleto=20de=20validador=20e=20de=20m=C3=A9to?= =?UTF-8?q?do=20para=20retornar=20notas=20de=20alunos?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/client.php | 42 ++ client/curl.php | 622 ++++++++++++++++++++++ db/access.php | 25 + db/install.xml | 17 + db/services.php | 17 +- externallib.php | 53 +- lang/{pt/mod_sga.php => en/sga.php} | 1 + lang/{en/mod_sga.php => pt/sga.php} | 0 lang/{pt_BR/mod_sga.php => pt_br/sga.php} | 1 + validador.php | 32 ++ version.php | 2 +- 11 files changed, 793 insertions(+), 19 deletions(-) create mode 100644 client/client.php create mode 100644 client/curl.php create mode 100644 db/access.php create mode 100755 db/install.xml rename lang/{pt/mod_sga.php => en/sga.php} (67%) rename lang/{en/mod_sga.php => pt/sga.php} (100%) rename lang/{pt_BR/mod_sga.php => pt_br/sga.php} (67%) create mode 100644 validador.php diff --git a/client/client.php b/client/client.php new file mode 100644 index 0000000..b3e59c4 --- /dev/null +++ b/client/client.php @@ -0,0 +1,42 @@ + Advanced features) +// 3- Enable XMLRPC protocol (Admin > Plugins > Web services > Manage protocols) +// 4- Create a token for a specific user and for the service 'My service' (Admin > Plugins > Web services > Manage tokens) +// 5- Run this script directly from your browser: you should see 'Hello, FIRSTNAME' + + +/// SETUP - NEED TO BE CHANGED +$token = '2c4c550b3710b648dd7743d446884211'; +$domainname = 'http://localhost/saberes'; + +/// FUNCTION NAME +$functionname = 'mod_sga_get_notas_curso'; + +/// PARAMETERS +$codCurso = 123; + +///// XML-RPC CALL +header('Content-Type: text/plain'); +$serverurl = $domainname . '/webservice/xmlrpc/server.php'. '?wstoken=' . $token; +require_once('./curl.php'); +$curl = new curl; +$post = xmlrpc_encode_request($functionname, array($codCurso)); +$resp = xmlrpc_decode($curl->post($serverurl, $post)); +print_r($resp); diff --git a/client/curl.php b/client/curl.php new file mode 100644 index 0000000..a6ab568 --- /dev/null +++ b/client/curl.php @@ -0,0 +1,622 @@ + + * $c = new curl; + * // enable cache + * $c = new curl(array('cache'=>true)); + * // enable cookie + * $c = new curl(array('cookie'=>true)); + * // enable proxy + * $c = new curl(array('proxy'=>true)); + * + * // HTTP GET Method + * $html = $c->get('http://example.com'); + * // HTTP POST Method + * $html = $c->post('http://example.com/', array('q'=>'words', 'name'=>'moodle')); + * // HTTP PUT Method + * $html = $c->put('http://example.com/', array('file'=>'/var/www/test.txt'); + * + * + * @author Dongsheng Cai - https://github.com/dongsheng/cURL + * @license http://www.gnu.org/copyleft/gpl.html GNU Public License + */ + +class curl { + /** @var bool */ + public $cache = false; + public $proxy = false; + /** @var array */ + public $response = array(); + public $header = array(); + /** @var string */ + public $info; + public $error; + + /** @var array */ + private $options; + /** @var string */ + private $proxy_host = ''; + private $proxy_auth = ''; + private $proxy_type = ''; + /** @var bool */ + private $debug = false; + private $cookie = false; + + /** + * @param array $options + */ + public function __construct($options = array()){ + if (!function_exists('curl_init')) { + $this->error = 'cURL module must be enabled!'; + trigger_error($this->error, E_USER_ERROR); + return false; + } + // the options of curl should be init here. + $this->resetopt(); + if (!empty($options['debug'])) { + $this->debug = true; + } + if(!empty($options['cookie'])) { + if($options['cookie'] === true) { + $this->cookie = 'curl_cookie.txt'; + } else { + $this->cookie = $options['cookie']; + } + } + if (!empty($options['cache'])) { + if (class_exists('curl_cache')) { + $this->cache = new curl_cache(); + } + } + } + /** + * Resets the CURL options that have already been set + */ + public function resetopt(){ + $this->options = array(); + $this->options['CURLOPT_USERAGENT'] = 'MoodleBot/1.0'; + // True to include the header in the output + $this->options['CURLOPT_HEADER'] = 0; + // True to Exclude the body from the output + $this->options['CURLOPT_NOBODY'] = 0; + // TRUE to follow any "Location: " header that the server + // sends as part of the HTTP header (note this is recursive, + // PHP will follow as many "Location: " headers that it is sent, + // unless CURLOPT_MAXREDIRS is set). + //$this->options['CURLOPT_FOLLOWLOCATION'] = 1; + $this->options['CURLOPT_MAXREDIRS'] = 10; + $this->options['CURLOPT_ENCODING'] = ''; + // TRUE to return the transfer as a string of the return + // value of curl_exec() instead of outputting it out directly. + $this->options['CURLOPT_RETURNTRANSFER'] = 1; + $this->options['CURLOPT_BINARYTRANSFER'] = 0; + $this->options['CURLOPT_SSL_VERIFYPEER'] = 0; + $this->options['CURLOPT_SSL_VERIFYHOST'] = 2; + $this->options['CURLOPT_CONNECTTIMEOUT'] = 30; + } + + /** + * Reset Cookie + */ + public function resetcookie() { + if (!empty($this->cookie)) { + if (is_file($this->cookie)) { + $fp = fopen($this->cookie, 'w'); + if (!empty($fp)) { + fwrite($fp, ''); + fclose($fp); + } + } + } + } + + /** + * Set curl options + * + * @param array $options If array is null, this function will + * reset the options to default value. + * + */ + public function setopt($options = array()) { + if (is_array($options)) { + foreach($options as $name => $val){ + if (stripos($name, 'CURLOPT_') === false) { + $name = strtoupper('CURLOPT_'.$name); + } + $this->options[$name] = $val; + } + } + } + /** + * Reset http method + * + */ + public function cleanopt(){ + unset($this->options['CURLOPT_HTTPGET']); + unset($this->options['CURLOPT_POST']); + unset($this->options['CURLOPT_POSTFIELDS']); + unset($this->options['CURLOPT_PUT']); + unset($this->options['CURLOPT_INFILE']); + unset($this->options['CURLOPT_INFILESIZE']); + unset($this->options['CURLOPT_CUSTOMREQUEST']); + } + + /** + * Set HTTP Request Header + * + * @param array $headers + * + */ + public function setHeader($header) { + if (is_array($header)){ + foreach ($header as $v) { + $this->setHeader($v); + } + } else { + $this->header[] = $header; + } + } + /** + * Set HTTP Response Header + * + */ + public function getResponse(){ + return $this->response; + } + /** + * private callback function + * Formatting HTTP Response Header + * + * @param mixed $ch Apparently not used + * @param string $header + * @return int The strlen of the header + */ + private function formatHeader($ch, $header) + { + $this->count++; + if (strlen($header) > 2) { + list($key, $value) = explode(" ", rtrim($header, "\r\n"), 2); + $key = rtrim($key, ':'); + if (!empty($this->response[$key])) { + if (is_array($this->response[$key])){ + $this->response[$key][] = $value; + } else { + $tmp = $this->response[$key]; + $this->response[$key] = array(); + $this->response[$key][] = $tmp; + $this->response[$key][] = $value; + + } + } else { + $this->response[$key] = $value; + } + } + return strlen($header); + } + + /** + * Set options for individual curl instance + * + * @param object $curl A curl handle + * @param array $options + * @return object The curl handle + */ + private function apply_opt($curl, $options) { + // Clean up + $this->cleanopt(); + // set cookie + if (!empty($this->cookie) || !empty($options['cookie'])) { + $this->setopt(array('cookiejar'=>$this->cookie, + 'cookiefile'=>$this->cookie + )); + } + + // set proxy + if (!empty($this->proxy) || !empty($options['proxy'])) { + $this->setopt($this->proxy); + } + $this->setopt($options); + // reset before set options + curl_setopt($curl, CURLOPT_HEADERFUNCTION, array(&$this,'formatHeader')); + // set headers + if (empty($this->header)){ + $this->setHeader(array( + 'User-Agent: MoodleBot/1.0', + 'Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7', + 'Connection: keep-alive' + )); + } + curl_setopt($curl, CURLOPT_HTTPHEADER, $this->header); + + if ($this->debug){ + echo '

Options

'; + var_dump($this->options); + echo '

Header

'; + var_dump($this->header); + } + + // set options + foreach($this->options as $name => $val) { + if (is_string($name)) { + $name = constant(strtoupper($name)); + } + curl_setopt($curl, $name, $val); + } + return $curl; + } + /** + * Download multiple files in parallel + * + * Calls {@link multi()} with specific download headers + * + * + * $c = new curl; + * $c->download(array( + * array('url'=>'http://localhost/', 'file'=>fopen('a', 'wb')), + * array('url'=>'http://localhost/20/', 'file'=>fopen('b', 'wb')) + * )); + * + * + * @param array $requests An array of files to request + * @param array $options An array of options to set + * @return array An array of results + */ + public function download($requests, $options = array()) { + $options['CURLOPT_BINARYTRANSFER'] = 1; + $options['RETURNTRANSFER'] = false; + return $this->multi($requests, $options); + } + /* + * Mulit HTTP Requests + * This function could run multi-requests in parallel. + * + * @param array $requests An array of files to request + * @param array $options An array of options to set + * @return array An array of results + */ + protected function multi($requests, $options = array()) { + $count = count($requests); + $handles = array(); + $results = array(); + $main = curl_multi_init(); + for ($i = 0; $i < $count; $i++) { + $url = $requests[$i]; + foreach($url as $n=>$v){ + $options[$n] = $url[$n]; + } + $handles[$i] = curl_init($url['url']); + $this->apply_opt($handles[$i], $options); + curl_multi_add_handle($main, $handles[$i]); + } + $running = 0; + do { + curl_multi_exec($main, $running); + } while($running > 0); + for ($i = 0; $i < $count; $i++) { + if (!empty($options['CURLOPT_RETURNTRANSFER'])) { + $results[] = true; + } else { + $results[] = curl_multi_getcontent($handles[$i]); + } + curl_multi_remove_handle($main, $handles[$i]); + } + curl_multi_close($main); + return $results; + } + /** + * Single HTTP Request + * + * @param string $url The URL to request + * @param array $options + * @return bool + */ + protected function request($url, $options = array()){ + // create curl instance + $curl = curl_init($url); + $options['url'] = $url; + $this->apply_opt($curl, $options); + if ($this->cache && $ret = $this->cache->get($this->options)) { + return $ret; + } else { + $ret = curl_exec($curl); + if ($this->cache) { + $this->cache->set($this->options, $ret); + } + } + + $this->info = curl_getinfo($curl); + $this->error = curl_error($curl); + + if ($this->debug){ + echo '

Return Data

'; + var_dump($ret); + echo '

Info

'; + var_dump($this->info); + echo '

Error

'; + var_dump($this->error); + } + + curl_close($curl); + + if (empty($this->error)){ + return $ret; + } else { + return $this->error; + // exception is not ajax friendly + //throw new moodle_exception($this->error, 'curl'); + } + } + + /** + * HTTP HEAD method + * + * @see request() + * + * @param string $url + * @param array $options + * @return bool + */ + public function head($url, $options = array()){ + $options['CURLOPT_HTTPGET'] = 0; + $options['CURLOPT_HEADER'] = 1; + $options['CURLOPT_NOBODY'] = 1; + return $this->request($url, $options); + } + + /** + * Recursive function formating an array in POST parameter + * @param array $arraydata - the array that we are going to format and add into &$data array + * @param string $currentdata - a row of the final postdata array at instant T + * when finish, it's assign to $data under this format: name[keyname][][]...[]='value' + * @param array $data - the final data array containing all POST parameters : 1 row = 1 parameter + */ + function format_array_postdata_for_curlcall($arraydata, $currentdata, &$data) { + foreach ($arraydata as $k=>$v) { + $newcurrentdata = $currentdata; + if (is_object($v)) { + $v = (array) $v; + } + if (is_array($v)) { //the value is an array, call the function recursively + $newcurrentdata = $newcurrentdata.'['.urlencode($k).']'; + $this->format_array_postdata_for_curlcall($v, $newcurrentdata, $data); + } else { //add the POST parameter to the $data array + $data[] = $newcurrentdata.'['.urlencode($k).']='.urlencode($v); + } + } + } + + /** + * Transform a PHP array into POST parameter + * (see the recursive function format_array_postdata_for_curlcall) + * @param array $postdata + * @return array containing all POST parameters (1 row = 1 POST parameter) + */ + function format_postdata_for_curlcall($postdata) { + if (is_object($postdata)) { + $postdata = (array) $postdata; + } + $data = array(); + foreach ($postdata as $k=>$v) { + if (is_object($v)) { + $v = (array) $v; + } + if (is_array($v)) { + $currentdata = urlencode($k); + $this->format_array_postdata_for_curlcall($v, $currentdata, $data); + } else { + $data[] = urlencode($k).'='.urlencode($v); + } + } + $convertedpostdata = implode('&', $data); + return $convertedpostdata; + } + + /** + * HTTP POST method + * + * @param string $url + * @param array|string $params + * @param array $options + * @return bool + */ + public function post($url, $params = '', $options = array()){ + $options['CURLOPT_POST'] = 1; + if (is_array($params)) { + $params = $this->format_postdata_for_curlcall($params); + } + $options['CURLOPT_POSTFIELDS'] = $params; + return $this->request($url, $options); + } + + /** + * HTTP GET method + * + * @param string $url + * @param array $params + * @param array $options + * @return bool + */ + public function get($url, $params = array(), $options = array()){ + $options['CURLOPT_HTTPGET'] = 1; + + if (!empty($params)){ + $url .= (stripos($url, '?') !== false) ? '&' : '?'; + $url .= http_build_query($params, '', '&'); + } + return $this->request($url, $options); + } + + /** + * HTTP PUT method + * + * @param string $url + * @param array $params + * @param array $options + * @return bool + */ + public function put($url, $params = array(), $options = array()){ + $file = $params['file']; + if (!is_file($file)){ + return null; + } + $fp = fopen($file, 'r'); + $size = filesize($file); + $options['CURLOPT_PUT'] = 1; + $options['CURLOPT_INFILESIZE'] = $size; + $options['CURLOPT_INFILE'] = $fp; + if (!isset($this->options['CURLOPT_USERPWD'])){ + $this->setopt(array('CURLOPT_USERPWD'=>'anonymous: noreply@moodle.org')); + } + $ret = $this->request($url, $options); + fclose($fp); + return $ret; + } + + /** + * HTTP DELETE method + * + * @param string $url + * @param array $params + * @param array $options + * @return bool + */ + public function delete($url, $param = array(), $options = array()){ + $options['CURLOPT_CUSTOMREQUEST'] = 'DELETE'; + if (!isset($options['CURLOPT_USERPWD'])) { + $options['CURLOPT_USERPWD'] = 'anonymous: noreply@moodle.org'; + } + $ret = $this->request($url, $options); + return $ret; + } + /** + * HTTP TRACE method + * + * @param string $url + * @param array $options + * @return bool + */ + public function trace($url, $options = array()){ + $options['CURLOPT_CUSTOMREQUEST'] = 'TRACE'; + $ret = $this->request($url, $options); + return $ret; + } + /** + * HTTP OPTIONS method + * + * @param string $url + * @param array $options + * @return bool + */ + public function options($url, $options = array()){ + $options['CURLOPT_CUSTOMREQUEST'] = 'OPTIONS'; + $ret = $this->request($url, $options); + return $ret; + } + public function get_info() { + return $this->info; + } +} + +/** + * This class is used by cURL class, use case: + * + * + * + * $c = new curl(array('cache'=>true), 'module_cache'=>'repository'); + * $ret = $c->get('http://www.google.com'); + * + * + * @package core + * @subpackage file + * @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com} + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class curl_cache { + /** @var string */ + public $dir = ''; + /** + * + * @param string @module which module is using curl_cache + * + */ + function __construct() { + $this->dir = '/tmp/'; + if (!file_exists($this->dir)) { + mkdir($this->dir, 0700, true); + } + $this->ttl = 1200; + } + + /** + * Get cached value + * + * @param mixed $param + * @return bool|string + */ + public function get($param){ + $this->cleanup($this->ttl); + $filename = 'u_'.md5(serialize($param)); + if(file_exists($this->dir.$filename)) { + $lasttime = filemtime($this->dir.$filename); + if(time()-$lasttime > $this->ttl) + { + return false; + } else { + $fp = fopen($this->dir.$filename, 'r'); + $size = filesize($this->dir.$filename); + $content = fread($fp, $size); + return unserialize($content); + } + } + return false; + } + + /** + * Set cache value + * + * @param mixed $param + * @param mixed $val + */ + public function set($param, $val){ + $filename = 'u_'.md5(serialize($param)); + $fp = fopen($this->dir.$filename, 'w'); + fwrite($fp, serialize($val)); + fclose($fp); + } + + /** + * Remove cache files + * + * @param int $expire The number os seconds before expiry + */ + public function cleanup($expire){ + if($dir = opendir($this->dir)){ + while (false !== ($file = readdir($dir))) { + if(!is_dir($file) && $file != '.' && $file != '..') { + $lasttime = @filemtime($this->dir.$file); + if(time() - $lasttime > $expire){ + @unlink($this->dir.$file); + } + } + } + } + } + /** + * delete current user's cache file + * + */ + public function refresh(){ + if($dir = opendir($this->dir)){ + while (false !== ($file = readdir($dir))) { + if(!is_dir($file) && $file != '.' && $file != '..') { + if(strpos($file, 'u_')!==false){ + @unlink($this->dir.$file); + } + } + } + } + } +} diff --git a/db/access.php b/db/access.php new file mode 100644 index 0000000..2c6b96a --- /dev/null +++ b/db/access.php @@ -0,0 +1,25 @@ +. + +/** + */ + +defined('MOODLE_INTERNAL') || die(); + +$capabilities = array( + + +); diff --git a/db/install.xml b/db/install.xml new file mode 100755 index 0000000..bcfced2 --- /dev/null +++ b/db/install.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + +
+
+
\ No newline at end of file diff --git a/db/services.php b/db/services.php index b7e1025..6d18784 100644 --- a/db/services.php +++ b/db/services.php @@ -16,12 +16,12 @@ /** * External functions and service definitions. */ -/* + // We define the services to install as pre-build services. A pre-build service is not editable by administrator. $services = array( - 'Escola Modelo Service' => array( + 'SGA Service' => array( 'functions' => array ( - 'block_escola_modelo_get_usage_statistics' + 'mod_sga_get_notas_curso' ), 'restrictedusers' => 0, 'enabled'=>1, @@ -30,13 +30,12 @@ $services = array( // We defined the web service functions to install. $functions = array( - 'block_escola_modelo_get_usage_statistics' => array( - 'classname' => 'block_escola_modelo_external', - 'methodname' => 'get_usage_statistics', - 'classpath' => 'block/escola_modelo/externallib.php', - 'description' => 'Returns user statistics from this moodle installation', + 'mod_sga_get_notas_curso' => array( + 'classname' => 'mod_sga_external', + 'methodname' => 'get_notas_curso', + 'classpath' => 'mod/sga/externallib.php', + 'description' => 'Retorna notas para alunos matriculados em determinado curso', 'type' => 'read', ), ); - */ diff --git a/externallib.php b/externallib.php index 78da0d2..fc533de 100644 --- a/externallib.php +++ b/externallib.php @@ -19,24 +19,59 @@ require_once($CFG->libdir . "/externallib.php"); class mod_sga_external extends external_api { - - /* public static function get_usage_statistics() { + + public static function get_notas_curso() { global $USER; - return '{"cursos": "10", "alunos":"20", "certificados":"12"}'; + // TODO: obter as notas do aluno no curso + // e retornar como JSON + // ver exemplo https://github.com/interlegis/moodle-local_wsilb/blob/main/externallib.php + + + $nota1 = array( + "aluno" => '05272886674', + "nota" => "9", + ); + + $nota2 = array( + "aluno" => '13504211628', + "nota" => '8' + ); + + $notas= array($nota1, $nota2); + + $obj = new StdClass(); + $obj->curso = 123; + $obj->notas = $notas; + + $json = json_encode($obj); + + return $json; + ' + { + "curso":123, + "notas":[ + { + "aluno":"05272886674", + "nota":9 + }, + { + "aluno":"13504211628", + "nota":8 + } + ] + }'; } - public static function get_usage_statistics_parameters() { + public static function get_notas_curso_parameters() { return new external_function_parameters( - array() + array(PARAM_INT, 'Código do curso') ); } - public static function get_usage_statistics_returns() { - return new external_value(PARAM_TEXT, 'JSON with statistics of this installation'); + public static function get_notas_curso_returns() { + return new external_value(PARAM_TEXT, 'JSON com notas dos alunos no curso especificado'); } - */ - } diff --git a/lang/pt/mod_sga.php b/lang/en/sga.php similarity index 67% rename from lang/pt/mod_sga.php rename to lang/en/sga.php index ac2c75d..871b8c2 100644 --- a/lang/pt/mod_sga.php +++ b/lang/en/sga.php @@ -2,5 +2,6 @@ $string['pluginname'] = 'Integração com o SGA'; $string['modulename'] = 'Integração com o SGA'; +$string['pagetitle'] = 'Validação de documentos'; diff --git a/lang/en/mod_sga.php b/lang/pt/sga.php similarity index 100% rename from lang/en/mod_sga.php rename to lang/pt/sga.php diff --git a/lang/pt_BR/mod_sga.php b/lang/pt_br/sga.php similarity index 67% rename from lang/pt_BR/mod_sga.php rename to lang/pt_br/sga.php index ac2c75d..871b8c2 100644 --- a/lang/pt_BR/mod_sga.php +++ b/lang/pt_br/sga.php @@ -2,5 +2,6 @@ $string['pluginname'] = 'Integração com o SGA'; $string['modulename'] = 'Integração com o SGA'; +$string['pagetitle'] = 'Validação de documentos'; diff --git a/validador.php b/validador.php new file mode 100644 index 0000000..c4148ee --- /dev/null +++ b/validador.php @@ -0,0 +1,32 @@ +set_pagelayout('incourse'); // FIXME trocar para outro tipo de layout + +// $strname = get_string('name'); +// $strintro = get_string('moduleintro'); +// $strlastmodified = get_string('lastmodified'); + +$PAGE->set_url('/mod/sga/validador.php', array('code' => $code)); +$PAGE->set_title(get_string('pagetitle')); +$PAGE->set_heading(get_string('pagetitle')); +//$PAGE->navbar->add($strpalestras); + +echo $OUTPUT->header(); + +$saida = 'Aluno' . "Fulano" . '
Curso: ' . 'Direito Legislativo'; + +echo html_writer::div($saida); + +echo $OUTPUT->footer(); diff --git a/version.php b/version.php index 74c4f9d..a9dc92e 100644 --- a/version.php +++ b/version.php @@ -1,4 +1,4 @@ version = 2021092701; +$plugin->version = 2021092805; $plugin->requires = 2017110800; $plugin->component = 'mod_sga';