Last active
December 15, 2015 00:19
-
-
Save lbenedix/5171782 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
class UiFeedbackAPI extends ApiBase { | |
public function execute() { | |
$can_read = $this->getUser()->isAllowed( 'read_uifeedback' ); | |
$can_write = $this->getUser()->isAllowed( 'write_uifeedback' ); | |
// Get the parameters | |
$params = $this->extractRequestParams(); | |
if ( !$can_read ) { | |
$this->dieUsage( 'you have to be logged in to use that api' ); | |
} else { | |
$method = $params[ 'mode' ]; | |
if ( $method == 'feedback' ) { /* handling of feedback requests */ | |
$type = $params[ 'ui-feedback-type' ]; | |
if ( $type !== '1' && $type !== '0' ) { | |
$this->dieUsage( 'ui-feedback-type has to be either 0 or 1! ', 'error-code', 400 ); | |
} | |
/* I decided to use getFuzzyBool, because using $params['ui-feedback-anonymous'] leads to mysterious behaviour, | |
a request with "ui-feedback-anonymous:false" was "ui-feedback-anonymous: true" when I printed params to the response */ | |
$anonymous = $this->getRequest()->getFuzzyBool( 'ui-feedback-anonymous' ); | |
if ( $anonymous ) { | |
$username = ''; | |
} else { | |
/* username or IP */ | |
$username = $this->getUser()->getName(); | |
} | |
$notify = 0; | |
if ( !$anonymous ) { | |
$notify = $this->getRequest()->getFuzzyBool( 'ui-feedback-notify', null ); | |
} | |
$task = $params[ 'ui-feedback-task' ]; | |
$other = $params[ 'ui-feedback-task-other' ]; | |
if ( $other !== null ) { | |
$task .= ' - ' . $other; | |
} | |
$done = $params[ 'ui-feedback-done' ]; | |
if ( $done === '1' ) { | |
$done = 1; | |
} else if ( $done === '0' ) { | |
$done = 0; | |
} else { | |
$done = null; | |
} | |
$url = $params[ 'ui-feedback-url' ]; | |
$a = array( | |
'type' => $type, | |
'url' => $url, | |
'task' => $task, | |
'done' => $done, | |
'importance' => $params[ 'ui-feedback-importance' ], | |
'happened' => $params[ 'ui-feedback-happened' ], | |
'text1' => $params[ 'ui-feedback-text1' ], | |
'username' => $username, | |
'useragent' => $params[ 'ui-feedback-useragent' ], | |
'notify' => $notify, | |
//'image_size' => $file_size, | |
// 'screenshot' => $file_content, | |
'status' => '0', | |
'comment' => '' | |
); | |
$dbw = wfGetDB( DB_MASTER ); | |
/* insert Feedback into Database */ | |
$dbw->begin(); | |
$dbw->insert( 'uifeedback', $a, __METHOD__, array() ); | |
$id = $dbw->insertId(); | |
$dbw->update( 'uifeedback_stats', array( 'sent = sent + 1' ), array( 'type' => $type ), __METHOD__ ); | |
$dbw->commit(); | |
/* SCREENSHOT */ | |
$token = $this->getContext()->getUser()->editToken(); | |
$file_content = 'foo'; | |
$file_size = 0; | |
if ( $type == 1 ) { // screenshot | |
$uploadName = 'file'; | |
if ( array_key_exists( $uploadName, $_FILES ) ) { // Upload via files | |
$file_content = file_get_contents( $this->getRequest()->getFileTempname( $uploadName ) ); | |
} elseif ( array_key_exists( $uploadName, $_POST ) ) { // Upload via dataURI | |
$file_content = substr( $_POST[ $uploadName ], strpos( $_POST[ $uploadName ], "," ) + 1 ); | |
$file_content = base64_decode( $file_content ); | |
} | |
// $file_size = sizeofvar( $file_content ); | |
} | |
$filename = 'UIFeedback-screenshot-' . $id . '.png'; | |
$request = new UploadFauxRequest ( | |
$this->getRequest(), | |
array( | |
'action' => 'upload', | |
'filename' => $filename, | |
'file' => $file_content, | |
'token' => $token, | |
), | |
false // was posted? | |
); | |
$request->addUpload( 'file', $file_content ); | |
$api = new ApiMain( | |
$request, | |
true // enable write? | |
); | |
$api->execute(); | |
$upload_response = & $api->getResultData(); | |
/* END SCREENSHOT */ | |
$this->getResult()->addValue( null, $this->getModuleName(), array( 'status' => 'ok', 'id' => $id, '$done' => $done, 'token' => $token, 'getValues' => $request->getValues() ) ); | |
return true; | |
/* end feedback */ | |
} else if ( $method == 'count' ) { /* handling of count requests (for statistics) */ | |
$type = $params[ 'type' ]; /* 0 dynamic request (popup), 1 questionnaire-button, 2 screenshot-button */ | |
$show = $this->getRequest()->getFuzzyBool( 'show', false ); /* 1 = true */ | |
$click = $this->getRequest()->getFuzzyBool( 'click', false ); /* 1 = true*/ | |
$sent = $this->getRequest()->getFuzzyBool( 'sent', false ); /* 1 = true*/ | |
/* illegal request */ | |
if ( ( !$can_read ) || ( $type < 0 || $type > 2 ) || ( !$show && !$click && !$sent ) ) { | |
$this->dieUsage( "Bad request!" ); | |
} | |
/* if click, show and sent are 1 I have no idea what to do */ | |
if ( $click == $show && $show == $sent ) { | |
$this->dieUsage( "Bad request! Either show, click or sent can be true!" ); | |
} | |
if ( $show ) { | |
$value = array( 'shown = shown + 1' ); | |
} else if ( $click ) { | |
$value = array( 'clicked = clicked + 1' ); | |
} else if ( $sent ) { | |
$value = array( 'sent = sent + 1' ); | |
} else { | |
$this->dieUsage( 'Bad Request' ); | |
} | |
/* update table */ | |
$dbw = wfGetDB( DB_MASTER ); | |
$dbw->update( 'uifeedback_stats', | |
$value, | |
array( 'type' => $type ), | |
__METHOD__ | |
); | |
return; | |
/* end count */ | |
/* review */ | |
} else if ( $method == 'review' ) { | |
$id = $params[ 'id' ]; | |
$new_status = $params[ 'status' ]; | |
$comment = $params[ 'comment' ]; | |
$reviewer = $this->getUser()->getName(); | |
if ( $id != -1 && $new_status != -1 ) { | |
$dbw = wfGetDB( DB_MASTER ); | |
$dbw->begin(); | |
$values = array( 'status' => $new_status, 'comment' => $comment ); | |
$conds = array( 'id' => $id ); | |
$dbw = wfGetDB( DB_MASTER ); | |
$dbw->update( 'uifeedback', $values, $conds, __METHOD__, array() ); | |
$values = array( 'feedback_id' => $id, | |
'reviewer' => $reviewer, | |
'status' => $new_status, | |
'comment' => $comment | |
); | |
$dbw->insert( 'uifeedback_reviews', $values, __METHOD__, array() ); | |
$dbw->commit(); | |
$this->getResult()->addValue( null, $this->getModuleName(), array( 'status' => 'ok', 'params' => $params ) ); | |
} | |
} else { | |
$this->dieUsage( 'Bad Request' ); | |
} | |
} | |
} | |
// Description | |
public function getDescription() { | |
return 'This Api handles requests from the UIFeedback Extension'; | |
} | |
// parameter. | |
public function getAllowedParams() { | |
return array( | |
'mode' => array(), | |
'ui-feedback-anonymous' => array( ApiBase::PARAM_TYPE => 'boolean', | |
ApiBase::PARAM_DFLT => false ), | |
'ui-feedback-username' => array(), | |
'ui-feedback-notify' => array(), | |
'ui-feedback-task' => array(), | |
'ui-feedback-task-other' => array( ApiBase::PARAM_TYPE => 'string', | |
ApiBase::PARAM_DFLT => null ), | |
'ui-feedback-done' => array( ApiBase::PARAM_TYPE => 'string', /* i took string here because boolean defaults to false when not set */ | |
ApiBase::PARAM_DFLT => 'undefined' ), | |
'ui-feedback-type' => array( ApiBase::PARAM_TYPE => array( '0', '1' ) ), | |
'ui-feedback-url' => array(), | |
'ui-feedback-importance' => array( ApiBase::PARAM_TYPE => array( '0', '1', '2', '3', '4', '5' ), | |
ApiBase::PARAM_DFLT => '0' ), | |
'ui-feedback-url' => array(), | |
'ui-feedback-happened' => array( ApiBase::PARAM_TYPE => array( '0', '1', '2', '3', '4' ), | |
ApiBase::PARAM_DFLT => '0' ), | |
'ui-feedback-text1' => array( ApiBase::PARAM_TYPE => 'string' ), | |
'ui-feedback-useragent' => array( ApiBase::PARAM_TYPE => 'string' ), | |
'file' => array(), | |
'id' => array( ApiBase::PARAM_TYPE => 'integer' ), | |
'type' => array( ApiBase::PARAM_TYPE => 'integer' ), | |
'status' => array( ApiBase::PARAM_TYPE => array( '1', '2', '3' ) ), | |
'comment' => array( ApiBase::PARAM_TYPE => 'string' ), | |
'click' => array( ApiBase::PARAM_TYPE => 'integer', | |
ApiBase::PARAM_DFLT => 0 ), | |
'show' => array( ApiBase::PARAM_TYPE => 'integer', | |
ApiBase::PARAM_DFLT => 0 ), | |
'sent' => array( ApiBase::PARAM_TYPE => 'integer', | |
ApiBase::PARAM_DFLT => 0 ), | |
); | |
} | |
// Describe the parameter | |
public function getParamDescription() { | |
return array_merge( parent::getParamDescription(), array( | |
'mode' => 'method to use in the api (feedback, review, count)', | |
'ui-feedback-anonymous' => 'true, if the user want to post the feedback privately', | |
'ui-feedback-username' => 'the username of the user ', | |
'ui-feedback-notify' => '1, if the user wants be be notified about updated on this issue', | |
'ui-feedback-task' => 'the task (position in the list of tasks)', | |
'ui-feedback-task-other' => 'free text, if other is selected in task', | |
'ui-feedback-done' => '0: no, 1: yes, undefined', | |
'ui-feedback-type' => '0: Screenshot, 1: Questionnaire', | |
'ui-feedback-url' => 'the url from where the feedback came', | |
'ui-feedback-importance' => 'an integer for the importance, 0-5', | |
'ui-feedback-happened' => '0 unknown, 1 not expected, 2 confused, 3 missing feature, 4 other', | |
'ui-feedback-text1' => 'the comment (free text)', | |
'ui-feedback-useragent' => 'the useragent', | |
'file' => 'binary data (the rendered png)', | |
'type' => '', | |
'id' => 'for review-mode: feedback-id', | |
'status' => 'for review-mode: review-status', | |
'comment' => 'for review-mode: review-comment', | |
'click' => '', | |
'show' => '', | |
'sent' => '', | |
) ); | |
} | |
// Get examples | |
// TODO | |
public function getExamples() { | |
return array( | |
'api.php?action=apisampleoutput&face=O_o&format=xml' => 'Get a sideways look (and the usual predictions)' | |
); | |
} | |
} | |
/* this classes are written by brion */ | |
class FauxWebRequestUpload extends WebRequestUpload { | |
public function __construct( $request, $filedata ) { | |
if ( $filedata === false ) { | |
$this->doesExist = false; | |
$this->fileInfo = null; | |
} else { | |
$tmp = tempnam( sys_get_temp_dir(), 'fakeupload' ); | |
file_put_contents( $tmp, $filedata ); | |
$this->doesExist = true; | |
$this->fileInfo = array( | |
'name' => $tmp, | |
'type' => 'application/octet-stream', | |
'size' => strlen( $filedata ), | |
'tmp_name' => $tmp | |
); | |
} | |
} | |
} | |
class UploadFauxRequest extends DerivativeRequest { | |
function addUpload( $name, $filedata ) { | |
$this->uploads = array(); | |
$this->uploads[ $name ] = new FauxWebRequestUpload( $this, $filedata ); | |
} | |
function getUpload( $name ) { | |
if ( isset( $this->uploads[ $name ] ) ) { | |
return $this->uploads[ $name ]; | |
} else { | |
return new FauxWebRequestUpload( $this, false ); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment