php - Function mod_scorm_insert_scorm_tracks "Invalid parameter" -
i have problem webservice function moodle callen "mod_scorm_insert_scorm_tracks"
this function used inserting track information (i.e. star time) of user in scorm progress.
part of estructure of function
scoid= int attempt= int tracks[0][element]= string tracks[0][value]= string
new php structe has this
[tracks] => array ( [0] => array ( [element] => string [value] => string ) )
i have used 1 of examples had in website fine until got error
<b>notice</b>: array string conversion in <b>c:\xampp\htdocs\otros\php-rest\curl.php</b> on line <b>247</b><br /> <?xml version="1.0" encoding="utf-8" ?> <exception class="invalid_parameter_exception"> <errorcode>invalidparameter</errorcode> <message>invalid parameter value detected</message> <debuginfo>tracks => invalid parameter value detected: arrays accepted. bad value is: 'array'</debuginfo> </exception>
and problem seems here:
$item1 = new stdclass(); $item1->scoid = '2'; $item1->attempt = '1'; $item1->tracks = array( array( array( 'element' => 'x.start.time', 'value' => '1473102672' ), ), array( array( 'element' => 'x.start.time', 'value' => '1473102680' ), ), );
i tried in many ways
$item1 = new stdclass(); $item1->scoid = '2'; $item1->attempt = '1'; $item1->tracks = array('element' => 'x.start.time','value' => '1473102672');
or
$item1 = new stdclass(); $item1->scoid = '2'; $item1->attempt = '1'; $item1->tracks = array(array ('element' => 'x.start.time','value' => '1473102672'));
and still getting same message, i'm pretty problema wyntax have tried in many ways , still not working hope yo can me.
complete code:
/// setup - need changed $token = '481bf3d85a7eb539e37eabc88feccb3c'; $domainname = 'http://localhost/moodle'; //$functionname = 'mod_scorm_launch_sco'; $functionname = 'mod_scorm_insert_scorm_tracks'; //$functionname ='mod_scorm_view_scorm'; // rest returned values format $restformat = 'xml'; //also possible in moodle 2.2 , later: 'json' //setting 'json' fail calls on earlier moodle version $item1 = new stdclass(); $item1->scoid = '2'; $item1->attempt = '1'; $item1->tracks = array( array( array( 'element' => 'x.start.time', 'value' => 1473102672 ), ), array( array( 'element' => 'x.start.time', 'value' => 1473102680 ), ), ); $params = $item1; /// rest call header('content-type: text/plain'); $serverurl = $domainname . '/webservice/rest/server.php'. '?wstoken=' . $token . '&wsfunction='.$functionname; require_once('./curl.php'); $curl = new curl; //if rest format == 'xml', not add param backward compatibility moodle < 2.2 $restformat = ($restformat == 'json')?'&moodlewsrestformat=' . $restformat:''; $resp = $curl->post($serverurl . $restformat, $params); print_r($resp);
curl.php
<?php /** * curl class * * wrapper class curl, quite easy use: * <code> * $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 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'); * </code> * * @author dongsheng cai <dongsheng@moodle.com> - 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; private $count = 0; /** * @param array $options */ public function __construct($options = array()){ if (!function_exists('curl_init')) { $this->error = 'curl module must enabled!'; trigger_error($this->error, e_user_error); return false; } // options of curl should 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 curl options have been set */ public function resetopt(){ $this->options = array(); $this->options['curlopt_useragent'] = 'moodlebot/1.0'; // true include header in output $this->options['curlopt_header'] = 0; // true exclude body output $this->options['curlopt_nobody'] = 0; // true follow "location: " header server // sends part of http header (note recursive, // php follow many "location: " headers sent, // unless curlopt_maxredirs set). //$this->options['curlopt_followlocation'] = 1; $this->options['curlopt_maxredirs'] = 10; $this->options['curlopt_encoding'] = ''; // true return transfer string of return // value of curl_exec() instead of outputting 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 null, function * reset options default value. * */ public function setopt($options = array()) { if (is_array($options)) { foreach($options $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 $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 strlen of 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 individual curl instance * * @param object $curl curl handle * @param array $options * @return object curl handle */ private function apply_opt($curl, $options) { // clean $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 '<h1>options</h1>'; var_dump($this->options); echo '<h1>header</h1>'; var_dump($this->header); } // set options foreach($this->options $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()} specific download headers * * <code> * $c = new curl; * $c->download(array( * array('url'=>'http://localhost/', 'file'=>fopen('a', 'wb')), * array('url'=>'http://localhost/20/', 'file'=>fopen('b', 'wb')) * )); * </code> * * @param array $requests array of files request * @param array $options array of options set * @return array array of results */ public function download($requests, $options = array()) { $options['curlopt_binarytransfer'] = 1; $options['returntransfer'] = false; return $this->multi($requests, $options); } /* * mulit http requests * function run multi-requests in parallel. * * @param array $requests array of files request * @param array $options array of options set * @return array array of results */ protected function multi($requests, $options = array()) { $count = count($requests); $handles = array(); $results = array(); $main = curl_multi_init(); ($i = 0; $i < $count; $i++) { $url = $requests[$i]; foreach($url $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; { curl_multi_exec($main, $running); } while($running > 0); ($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 url 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 '<h1>return data</h1>'; var_dump($ret); echo '<h1>info</h1>'; var_dump($this->info); echo '<h1>error</h1>'; var_dump($this->error); } curl_close($curl); if (empty($this->error)){ return $ret; } else { return $this->error; // exception 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 array in post parameter * @param array $arraydata - array going format , add &$data array * @param string $currentdata - row of final postdata array @ instant t * when finish, it's assign $data under format: name[keyname][][]...[]='value' * @param array $data - final data array containing post parameters : 1 row = 1 parameter */ function format_array_postdata_for_curlcall($arraydata, $currentdata, &$data) { foreach ($arraydata $k=>$v) { $newcurrentdata = $currentdata; if (is_object($v)) { $v = (array) $v; } if (is_array($v)) { //the value array, call function recursively $newcurrentdata = $newcurrentdata.'['.urlencode($k).']'; $this->format_array_postdata_for_curlcall($v, $newcurrentdata, $data); } else { //add post parameter $data array $data[] = $newcurrentdata.'['.urlencode($k).']='.urlencode($v); } } } /** * transform php array post parameter * (see recursive function format_array_postdata_for_curlcall) * @param array $postdata * @return array containing post parameters (1 row = 1 post parameter) */ function format_postdata_for_curlcall($postdata) { if (is_object($postdata)) { $postdata = (array) $postdata; } $data = array(); foreach ($postdata $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 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; } } /** * class used curl class, use case: * * <code> * * $c = new curl(array('cache'=>true), 'module_cache'=>'repository'); * $ret = $c->get('http://www.google.com'); * </code> * * @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 module using curl_cache * */ function __construct() { $this->dir = '/tmp/'; if (!file_exists($this->dir)) { mkdir($this->dir, 0700, true); } $this->ttl = 1200; } /** * 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 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); } } } } } }
thanks!
well after research took plan b
i wrote tracks in different variable:
$tracks = array(); $tracks[] = array( 'element' => 'cmi.core.lesson_status', 'value' => 'completed' );
and followed curl.php array set option:
$arrayname = array('' => , );
then when inserted scoid , attemps single variables in array:
$params = array('scoid' => '2', 'attempt' => '1', 'tracks' => $tracks);
and boala!the record on table:
Comments
Post a Comment