Uploading files in a forum with a Web Service in Moodle - web-services

I need to upload files into a forum in moodle through Web Services, I have been searching and I found that exist a WS called core_files_upload(). I looked at the code of this WS and the context level of this WS is only (block, course, coursecat, system, user or module), the context forum not exist and this WS is deprecated.
I also found that in Moodle 3.0 there are 2 new WS related to forums, they are mod_forum_add_discussion and mod_forum_add_discussion_post but I also looked at the code and they don't allow upload.
Then I decided that the best solution would be to create a new one, but I don't know much about uploading files in Moodle and can't find much information. I'm a little bit familiar with the structure of the WS in Moodle because I have made 2 very simple WS but I don't know how to do this.
If anyone knows how to do it or have any examples or documentation that may be useful, it would be helpful.
Thanks in advance.

You can look up for the file
/webservice/upload.php
this file is for uploading files
$params = array('token'=>$token, 'filepath' => $filepath
, 'filearea'=>'draft') + $_FILES ;
$serverurl = <domainname>. '/webservice/upload.php'. '?token=' . $token;
$ch = curl_init();
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_VERBOSE, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible;)");
curl_setopt($ch, CURLOPT_URL, $serverurl);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
$response = curl_exec($ch);
or this can code can help you, that will create a file in moodle data and record in file table from temp file.
$fs = get_file_storage();
$target_path = <target-path>;
$context = get_context_instance(CONTEXT_USER, $userID, MUST_EXIST);
$cm = get_coursemodule_from_instance('forum', $forum->id);
$modcontext = context_module::instance($cm->id, MUST_EXIST);
//saving in draft
$item = rand();
$file_record = array('contextid'=>$context->id, 'component'=>'user', 'filearea'=>'draft', 'itemid'=>$item,
'filepath'=>"/", 'filename'=><filename>, 'userid'=>$userID);
$fs->create_file_from_pathname($file_record, $CFG->dirroot."/".$target_path.<filename>);
// saving for post
$file_record = array('contextid'=>$modcontext->id, 'component'=>'mod_forum', 'filearea'=>'post', 'itemid'=>$post->id,
'filepath'=>"/", 'filename'=><filename>, 'userid'=>$userID);
$fs->create_file_from_pathname($file_record, $CFG->dirroot."/".$target_path.$imagefileEnc);

At the request of #insightful i I'm going to publish my code, I hope this helps somebody
First the externallib.php of the WS
externallib.php
require_once($CFG->libdir . "/externallib.php");
require_once($CFG->libdir . "/filelib.php");
class local_upload_tfg_external extends external_api {
/**
* Returns description of method parameters
* #return external_function_parameters
*/
public static function upload_tfg_parameters() {
return new external_function_parameters(
array('community_key' => new external_value(PARAM_TEXT, 'Comunidad a la que se subira el TFG o TFM.', VALUE_REQUIRED, '', NULL_NOT_ALLOWED),
'username' => new external_value(PARAM_TEXT, 'Usuario que sube el archivo.', VALUE_REQUIRED, '', NULL_NOT_ALLOWED),
'folder_name' => new external_value(PARAM_TEXT, 'Directorio donde se subira el archivo.', VALUE_REQUIRED, '', NULL_NOT_ALLOWED))
);
}
public static function upload_tfg($community_key, $username, $folder_name) {
global $CFG, $DB, $USER;
require_once($CFG->dirroot . "/mod/forum/lib.php");
$params = self::validate_parameters(self::upload_tfg_parameters(),
array(
'community_key' => $community_key,
'username' => $username,
'folder_name' => $folder_name
));
//Context validation
//OPTIONAL but in most web service it should present
$contextoUser = get_context_instance(CONTEXT_USER, $USER->id);
self::validate_context($contextoUser);
$fs = get_file_storage();
$warnings = array();
//We get the course to which the file must be uploaded
$sql = "SELECT id FROM mdl_course WHERE idnumber = ?";
$result = $DB->get_records_sql($sql, array($community_key));
foreach ( $result as $n ) {
$courseid = $n->id;
}
if( is_null($courseid)){
throw new moodle_exception('no_course','No existe el curso');
}
//e get the forum to upload the file
$sql = "SELECT f.id FROM mdl_forum f , mdl_course c WHERE c.idnumber = ? AND c.id = f.course AND f.name = ?";
$result = $DB->get_records_sql($sql, array($community_key, $folder_name));
foreach ( $result as $n ) {
$forumid = $n->id;
}
if( is_null($forumid)){
throw new moodle_exception('no_forum','No existe el foro');
}
//We get the user who wants to upload the file
$sql = "SELECT id FROM mdl_user WHERE username = ?";
$result = $DB->get_records_sql($sql, array($username));
foreach ( $result as $n ) {
$userid = $n->id;
}
if( is_null($userid)){
throw new moodle_exception('no_user','No existe el usuario');
}
//We check if the user belongs to the course
$contextCourse = context_course::instance($courseid);
$enrolled = is_enrolled($contextCourse, $userid, '', true);
if( !$enrolled){
throw new moodle_exception('user_no_enrolled','El usuario no está en el curso');
}
//Files received
$numFiles = count($_FILES);
if($numFiles > 0){
// Request and permission validation.
$forum = $DB->get_record('forum', array('id' => $forumid), '*', MUST_EXIST);
list($course, $cm) = get_course_and_cm_from_instance($forum, 'forum');
$context = context_module::instance($cm->id);
self::validate_context($context);
// Normalize group.
if (!groups_get_activity_groupmode($cm)) {
// Groups not supported, force to -1.
$groupid = -1;
} else {
// Check if we receive the default or and empty value for groupid,
// in this case, get the group for the user in the activity.
if ($groupid === -1 ) {
$groupid = groups_get_activity_group($cm);
} else{
$groupid = -1;
}
}
if (!forum_user_can_post_discussion($forum, $groupid, -1, $cm, $context)) {
throw new moodle_exception('cannotcreatediscussion', 'forum');
}
$thresholdwarning = forum_check_throttling($forum, $cm);
forum_check_blocking_threshold($thresholdwarning);
foreach ($_FILES as $fieldname=>$uploaded_file) {
// check upload errors
if (!empty($_FILES[$fieldname]['error'])) {
switch ($_FILES[$fieldname]['error']) {
case UPLOAD_ERR_INI_SIZE:
throw new moodle_exception('upload_error_ini_size', 'repository_upload');
break;
case UPLOAD_ERR_FORM_SIZE:
throw new moodle_exception('upload_error_form_size', 'repository_upload');
break;
case UPLOAD_ERR_PARTIAL:
throw new moodle_exception('upload_error_partial', 'repository_upload');
break;
case UPLOAD_ERR_NO_FILE:
throw new moodle_exception('upload_error_no_file', 'repository_upload');
break;
case UPLOAD_ERR_NO_TMP_DIR:
throw new moodle_exception('upload_error_no_tmp_dir', 'repository_upload');
break;
case UPLOAD_ERR_CANT_WRITE:
throw new moodle_exception('upload_error_cant_write', 'repository_upload');
break;
case UPLOAD_ERR_EXTENSION:
throw new moodle_exception('upload_error_extension', 'repository_upload');
break;
default:
throw new moodle_exception('nofile');
}
}
/*$file = new stdClass();
$file->filename = clean_param($_FILES[$fieldname]['name'], PARAM_FILE);
// check system maxbytes setting
if (($_FILES[$fieldname]['size'] > get_max_upload_file_size($CFG->maxbytes))) {
// oversize file will be ignored, error added to array to notify web service client
$file->errortype = 'fileoversized';
$file->error = get_string('maxbytes', 'error');
} else {
$file->filepath = $_FILES[$fieldname]['tmp_name'];
// calculate total size of upload
//$totalsize += $_FILES[$fieldname]['size'];
}
$files[] = $file;*/
$filename = $_FILES[$fieldname]['name'];
$filepath = $_FILES[$fieldname]['tmp_name'];
// Create the discussion.
$discussion = new stdClass();
$discussion->course = $course->id;
$discussion->forum = $forum->id;
$discussion->message = "<p>".$filename."</p>";
$discussion->messageformat = FORMAT_HTML; // Force formatting for now.
$discussion->messagetrust = trusttext_trusted($context);
$discussion->itemid = 0;
$discussion->groupid = $groupid;
$discussion->mailnow = 0;
$discussion->subject = $filename;
$discussion->name = $discussion->subject;
$discussion->timestart = 0;
$discussion->timeend = 0;
if ($discussionid = forum_add_discussion($discussion)) {
$discussion->id = $discussionid;
//We update the user of the discursion to the one of the user received
$sql = "UPDATE mdl_forum_discussions SET userid= ? WHERE id = ?";
$DB->execute($sql, array($userid, $discussionid));
/*
// Trigger events and completion.
$params = array(
'context' => $context,
'objectid' => $discussion->id,
'other' => array(
'forumid' => $forum->id,
)
);
$event = \mod_forum\event\discussion_created::create($params);
$event->add_record_snapshot('forum_discussions', $discussion);
$event->trigger();
$completion = new completion_info($course);
if ($completion->is_enabled($cm) && ($forum->completiondiscussions || $forum->completionposts)) {
$completion->update_state($cm, COMPLETION_COMPLETE);
}
$settings = new stdClass();
$settings->discussionsubscribe = false; //discussionsubscribe (bool); subscribe to the discussion?, default to true
forum_post_subscription($settings, $forum, $discussion
//se guardara el fichero
// Get any existing file size limits.
//$maxareabytes = FILE_AREA_MAX_BYTES_UNLIMITED;
//$maxupload = get_user_max_upload_file_size($context, $CFG->maxbytes);
// Check the size of this upload.
//if ($maxupload !== USER_CAN_IGNORE_FILE_SIZE_LIMITS && $totalsize > $maxupload) {
// throw new file_exception('userquotalimit');
//}
*/
//We get the course to which the file must be uploaded
$sql = "SELECT id FROM mdl_forum_posts WHERE discussion = ? ORDER BY id ASC LIMIT 1";
$result = $DB->get_records_sql($sql, array($discussionid));
foreach ( $result as $n ) {
$postid = $n->id;
}
if( is_null($postid)){
throw new moodle_exception('no_post','No existe el post');
}
//We update the post to put the user that they send us and indicate that they have a file
$sql = "UPDATE mdl_forum_posts SET userid= ?, attachment= 1 WHERE id = ?";
$DB->execute($sql, array($userid, $postid));
$user = $DB->get_record('user', array('id'=>$userid), '*', MUST_EXIST);
$file_record = new stdClass;
$file_record->component = 'mod_forum';
$file_record->contextid = $context->id;
$file_record->userid = $userid;
$file_record->filearea = 'attachment';
$file_record->filename = $filename;
$file_record->filepath = '/';
$file_record->itemid = $postid;
$file_record->license = $CFG->sitedefaultlicense;
$file_record->author = fullname($user);
$file_record->source = $filename;
//Check if the file already exist
$existingfile = $fs->file_exists($file_record->contextid, $file_record->component, $file_record->filearea,
$file_record->itemid, $file_record->filepath, $file_record->filename);
if ($existingfile) {
throw new file_exception('filenameexist');
} else {
$stored_file = $fs->create_file_from_pathname($file_record, $filepath);
}
} else {
throw new moodle_exception('couldnotadd', 'forum');
}
}
}else{
throw new moodle_exception('nofile');
}
$result = array();
$result['discussionid'] = $discussionid;
$result['warnings'] = $warnings;
return $result;
}
/**
* Returns description of method result value
* #return external_multiple_structure
*/
public static function upload_tfg_returns() {
return new external_single_structure(
array(
'discussionid' => new external_value(PARAM_INT, 'New Discussion ID'),
'warnings' => new external_warnings()
)
);
}
}
And an example to call this WS maybe this:
$target_url = "http://localhost/pruebaMoodle/webservice/rest/server.php";
//$target_url = "http://localhost/upload.php";
$username = "raula"; //User uploading the file (must belong to the course)
$community_key = "c15c033a43976gPT"; //custom identifier of course
$folder_name = "Course 2016"; //Name of the forum to which the file will be uploaded
$fname = 'Prueba.txt'; //Name of the file or path where it is located but is in the same directory as this file
$token = "28b054f102a75a0eab2a0053fd930d62"; //token created for ws
$file_name_with_full_path = realpath($fname);
$cfile = new CURLFile($file_name_with_full_path);
$post = array (
'username' => $username,
'community_key' => $community_key,
'folder_name' => $folder_name,
'wstoken' => $token,
'wsfunction' => 'upload_tfg_tfm',
'moodlewsrestformat' => 'json',
'upload_file' => $cfile
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $target_url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible;)");
curl_setopt($ch, CURLOPT_HTTPHEADER,array('User-Agent: Opera/9.80 (Windows NT 6.2; Win64; x64) Presto/2.12.388 Version/12.15','Referer: http://localhost','Content-Type: multipart/form-data'));
curl_setopt($ch, CURLOPT_FRESH_CONNECT, 1);
curl_setopt($ch, CURLOPT_FORBID_REUSE, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
$result = curl_exec ($ch);
if ($result === FALSE) {
echo "Error sending " . $fname . " " . curl_error($ch) . "\n";
curl_close ($ch);
}else{
curl_close ($ch);
echo "<br><br>Result: " . $result. "<br>";
}
I hope this can serve you

Related

Amazon Gift Card Load Amazon Balance Api Integration In Php Laravel

I want to reward users on signing up to my app by giving them gift card balance in their amazon account and to do that i have used Load Amazon Balance api which is similar to Amazon Incentive api.
Amazon requires a digitally signed authorization payload in order to access the api. I've compared my code to amazon's process of digitally signing using aws secret key and aws access key. But its still giving me
"The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details."
I'm attaching the code of my class in the post. Can anyone help me out by looking at the code and telling if there is any mistake in the process i'm performing for sending information to the api. Thanks.
<?php
/**
* Created by PhpStorm.
*
* Date: 07-09-2018
* Time: 01:18 PM
*/
namespace App;
use App\AppConstant\AppConstant;
use App\Entities\Models\User;
use Illuminate\Support\Facades\Auth;
class AmazonReward
{
/**
* This is the bulk of the logic for making AGCOD calls.
*/
//Constants
public static $apikey;
public static $clientId = env("client_id");
public static $clientSecret = env("client_secret");
public static $awsSecretKey = env("client_secret");
public static $partnerId = env("partner_id");
public static $SERVICE_NAME = "AGCODService";
public static $ACCEPT_HEADER = "accept";
public static $CONTENT_HEADER = "content-type";
public static $HOST_HEADER = "host";
public static $XAMZDATE_HEADER = "x-amz-date";
public static $XAMZTARGET_HEADER = "x-amz-target";
public static $AUTHORIZATION_HEADER = "Authorization";
public static $AWS_SHA256_ALGORITHM = "AWS4-HMAC-SHA256";
public static $KEY_QUALIFIER = "AWS4";
public static $TERMINATION_STRING = "aws4_request";
const SERVICE_NAME = "AGCODService";
const ACCEPT_HEADER = "accept";
const CONTENT_HEADER = "content-type";
const HOST_HEADER = "host";
const XAMZDATE_HEADER = "x-amz-date";
const XAMZTARGET_HEADER = "x-amz-target";
const AUTHORIZATION_HEADER = "Authorization";
const AWS_SHA256_ALGORITHM = "AWS4-HMAC-SHA256";
const KEY_QUALIFIER = "AWS4";
const TERMINATION_STRING = "aws4_request";
const ENDPOINT ='agcod-v2.amazon.com';
// const ENDPOINT ='agcod-v2-gamma.amazon.com';
public static function get_paypload_giftcard($partnerId, $gcRequestId, $currencyCode, $gcAmount, $customer_id)
{
$amount = trim($gcAmount);
$payload = array(
"loadBalanceRequestId" => $gcRequestId,
"partnerId" => $partnerId,
"amount" =>
array(
"currencyCode" => $currencyCode,
"value" => floatval($amount)
),
"account" =>
array(
"id" => $customer_id,
"type" => "2"
),
"timestamp" => time(),
// "transactionSource" => [
// "sourceId" => ""
// ],
"externalReference" => "",
"notificationDetails" => [
"notificationMessage" => ""
]
);
return json_encode($payload);
}
/**
* Builds the "formal" request that can be hashed to verify the contents of the request.
* The request does not get sent to the server in this format, but the hash of this is.
*
* #return The formal request
*/
public static function buildCanonicalRequest($serviceOperation, $payloadHash, $customer_id) {
$ACCEPT_HEADER = self::ACCEPT_HEADER;
$HOST_HEADER = self::HOST_HEADER;
$XAMZDATE_HEADER = self::XAMZDATE_HEADER;
$XAMZTARGET_HEADER = self::XAMZTARGET_HEADER;
$ACCEPT_HEADER = self::ACCEPT_HEADER;
$dateTimeString = Self::getTimeStamp();
$header1 = Self::header1($serviceOperation);
$canonicalRequest = "POST\n/$serviceOperation HTTP/1.1\n\n$header1\n\n$ACCEPT_HEADER;$HOST_HEADER;$XAMZDATE_HEADER;$XAMZTARGET_HEADER\n$payloadHash";
return $canonicalRequest;
}
/**
* Returns part of the header used in the canonical request.
*
* #return the portion of the header.
*/
public static function header1($serviceOperation) {
$ACCEPT_HEADER = self::ACCEPT_HEADER;
$XAMZDATE_HEADER = self::XAMZDATE_HEADER;
$XAMZTARGET_HEADER = self::XAMZTARGET_HEADER;
$HOST_HEADER = Self::HOST_HEADER;
$dateTimeString = Self::getTimeStamp();
$endpoint = self::ENDPOINT;
$contentType = Self::getContentType();
return
"$ACCEPT_HEADER:$contentType\n$HOST_HEADER:$endpoint\n$XAMZDATE_HEADER:$dateTimeString\n$XAMZTARGET_HEADER:com.amazonaws.agcod.AGCODService.$serviceOperation";
}
public static function disburseFunds($customer_id){
$apiString = "https://" . Self::ENDPOINT . "/LoadAmazonBalance";
$ch = curl_init();
$xAmzDateTime = gmdate('Ymd\THis\Z');
$xAmzDate = substr($xAmzDateTime, 0, 8);
$xAmzTarget = "com.amazonaws.agcod.AGCODService.LoadAmazonBalance";
$region = "us-east-1";
$serviceOperation = "LoadAmazonBalance";
// $canonicalRequestHash = Self::myHash($canonicalRequest);
$payload = Self::get_paypload_giftcard( Self::$partnerId, Self::$partnerId . time(), "USD", 5.00, $customer_id);
$payloadHash = Self::myHash($payload);
$canonicalRequest = Self::buildCanonicalRequest($serviceOperation, $payloadHash , $customer_id);
$dateTimeString = Self::getTimeStamp();
$curl_response = Self::invokeRequest($payload, $xAmzDateTime,$canonicalRequest, $serviceOperation);
echo "<pre>";
print_r($curl_response);
exit;
$json = json_decode($curl_response);
if ( isset($json->message) || ! isset($json->cardInfo) )
{
echo "<pre>";
print_r($json);
exit;
$ret = array();
$ret['success']=false;
$ret['errorCode'] = time();
return $ret;
}
$ret = array();
$ret['success']=true;
$ret['gcValue']= $json->cardInfo->value->amount;
$ret["gcCode"]= $json->gcClaimCode;
$ret["gcResponseId"]= $json->gcId; ////done
$ret["gcRequestId"]=$json->creationRequestId;
echo "<pre>";
print_r($ret);
exit;
return $ret;
// echo "<pre>";
// print_r($canonicalRequestHash);
// exit;
// // $canonicalRequestHash = myHash($canonicalRequest);
// // $stringToSign = buildStringToSign($canonicalRequestHash);
// echo "<pre>";
// print_r($this->buildAuthSignature($stringToSign));
// exit;
// $authotization = "AWS4-HMAC-SHA256 Credential=AKIAIGHKAVYIDBOH3O3A/" . $xAmzTarget . "/" . $region . "/AGCODService/aws4_request,SignedHeaders=accept;host;x-amz-date;x-amz-target, Signature=ec86661c1d39f74b5891666505bb7656b172b0d060d911bee3b6a1c29ae17657";
// /*$post = http_build_query([
// ["Authorization" => "DEMO1"],
// ["x-amz-date" => $xAmzDate],
// ["x-amz-target" => $xAmzTarget],
// ["Accept" => "application/json"],
// ["Host" => "agcod-v2-gamma.amazon.com"]
// ]);*/
// // $post = [];
// $post = [];
// $post["loadBalanceRequestId"] = "Amazon123456";
// $post["partnerId"] = "";
// $post["amount"] = [];
// $post["amount"]["currencyCode"] = "";
// $post["amount"]["value"] = "";
// $post["account"] = [];
// $post["account"]["id"] = "F2044";
// $post["account"]["type"] = "0";
// $post["transactionSource"] = [];
// $post["transactionSource"]["sourceId"] = "";
// $post["externalReference"] = "";
// $post["notificationDetails"] = [];
// $post["notificationDetails"]["notificationMessage"] = "";
// $customHeaders = [
// "Authorization" => "Amazon",
// "x-amz-date" => $xAmzDateTime,
// "x-amz-target" => $xAmzTarget,
// "Accept" => "application/json",
// "Host" => "agcod-v2-gamma.amazon.com"
// ];
// curl_setopt($ch, CURLOPT_URL, $apiString);
// curl_setopt($ch, CURLOPT_POST, 1);
// curl_setopt($ch, CURLOPT_POSTFIELDS,$post);
// curl_setopt($ch, CURLOPT_HTTPHEADER, $customHeaders);
// curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// $server_output = curl_exec($ch);
// curl_close ($ch);
// // Further processing ...
// if ($server_output == "OK") {
// }else{
// }
}
/**
* Builds the authenication string used to prove that the request is allowed and made by the right party.
*
* #param $stringToSign The string to sign.
* #return The authenication signature.
*/
public static function buildAuthSignature($dateString, $stringToSign) {
$AWS_SHA256_ALGORITHM = Self::AWS_SHA256_ALGORITHM;
$SERVICE_NAME = Self::SERVICE_NAME;
$TERMINATION_STRING = Self::TERMINATION_STRING;
$ACCEPT_HEADER = Self::ACCEPT_HEADER;
$HOST_HEADER = Self::HOST_HEADER;
$XAMZDATE_HEADER = Self::XAMZDATE_HEADER;
$XAMZTARGET_HEADER = Self::XAMZTARGET_HEADER;
$awsKeyId = Self::$clientId;
$regionName= Self::getRegion();
$derivedKey = Self::buildDerivedKey(Self::getDateString($dateString));
$derivedKey_lower = Self::buildDerivedKey(Self::getDateString($dateString), false);
$dateString = Self::getDateString($dateString);
// Calculate signature per http://docs.aws.amazon.com/general/latest/gr/sigv4-calculate-signature.html
$finalSignature = Self::hmac($stringToSign, $derivedKey, false);
// Assemble Authorization Header with signing information
// per http://docs.aws.amazon.com/general/latest/gr/sigv4-add-signature-to-request.html
$authorizationValue =
$AWS_SHA256_ALGORITHM
. " Credential=" . $awsKeyId
. "/" . $dateString . "/" . $regionName . "/" . $SERVICE_NAME . "/" . $TERMINATION_STRING . ","
. " SignedHeaders="
. $ACCEPT_HEADER . ";" . $HOST_HEADER . ";" . $XAMZDATE_HEADER . ";" . $XAMZTARGET_HEADER . ","
. " Signature="
. $finalSignature;
return $authorizationValue;
}
/**
* Hashes the string using sha256, the standard AWS hash.
*
* #param $data a string to sign
* #return a string hash of $data
*/
public static function myHash($data) {
return hash("sha256",$data);
}
/**
* Builds the string that gets hashed and used in the authenication.
*
* #param $canonicalRequestHash The hash of the canonicalRequest
* #return The string to sign.
*/
public static function buildStringToSign($canonicalRequestHash){
$AWS_SHA256_ALGORITHM = Self::AWS_SHA256_ALGORITHM;
$TERMINATION_STRING = Self::TERMINATION_STRING;
$SERVICE_NAME = Self::SERVICE_NAME;
$awsSecretKey = Self::$awsSecretKey;
$regionName = Self::getRegion();
$dateTimeString = Self::getTimeStamp();
$dateString = Self::getDateString($dateTimeString);
$stringToSign = "$AWS_SHA256_ALGORITHM\n$dateTimeString\n$dateString/$regionName/$SERVICE_NAME/$TERMINATION_STRING\n$canonicalRequestHash";
return $stringToSign;
}
/**
* Gets the time stamp used to make the request. If not set by the client it is set to the current time on the first call to this function.
*
* #return The time stamp
*/
public static function getTimeStamp() {
global $timeStamp;
if(!isset($timeStamp)) {
//GMT time. Format is YYYYMMDDTHHmmssZ where T and Z are literals, YYYY is 4 digit year, MM is 2 digit month, DD is 2 digit day, HH is 2 digit hour (24 hour clock) mm is 2 digit minute, ss is 2 digit second.
$timeStamp = gmdate('Ymd\THis\Z');
}
return $timeStamp;
}
/**
* Get the format that we will make the request in. This tells the server how to parse the request.
* This value is retrieved from the client and can either be json or xml.
*
* #return The request format as to be passed to the AGCOD server.
*/
public static function getContentType() {
return "application/json"; //Request in JSON format
}
/**
* Makes the service call to the AGCOD server.
*
* #return The repsonse from the server (in XML or JSON format) with HTML character escaped.
*/
public static function invokeRequest($payload, $dateTimeString,$canonicalRequest, $serviceOperation) {
$KEY_QUALIFIER = self::KEY_QUALIFIER;
$ACCEPT_HEADER = self::ACCEPT_HEADER;
$CONTENT_HEADER = self::CONTENT_HEADER;
$HOST_HEADER = self::HOST_HEADER;
$XAMZDATE_HEADER = self::XAMZDATE_HEADER;
$XAMZTARGET_HEADER = self::XAMZTARGET_HEADER;
$AUTHORIZATION_HEADER = self::AUTHORIZATION_HEADER;
$canonicalRequestHash = Self::myHash($canonicalRequest);
$stringToSign = Self::buildStringToSign($canonicalRequestHash);
$authorizationValue = Self::buildAuthSignature($dateTimeString, $stringToSign);
$endpoint = Self::ENDPOINT;
$regionName = Self::getRegion();
$SERVICE_NAME = "AGCODService";
$serviceTarget = "com.amazonaws.agcod." . $SERVICE_NAME . "." . $serviceOperation;
$contentType = Self::getContentType();
$url = "https://" . Self::ENDPOINT . "/" . $serviceOperation;
// print_r($url);
// exit;
//Prepare to send the data to the server
$handle = curl_init($url);
//Yes, do POST not GET
curl_setopt($handle, CURLOPT_POST, true);
//This is header, not post fields
curl_setopt($handle, CURLOPT_HTTPHEADER , array(
"Content-Type:$contentType",
'Content-Length: ' . strlen($payload),
$AUTHORIZATION_HEADER. ":" . $authorizationValue,
$XAMZDATE_HEADER . ":" . $dateTimeString,
$XAMZTARGET_HEADER . ":" . $serviceTarget,
"host:" . Self::ENDPOINT,
$ACCEPT_HEADER . ":" . $contentType
));
curl_setopt($handle, CURLOPT_POSTFIELDS, $payload);
//Yes, don't print the result to the web page, just give it to us in a string.
curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
//Do the request
$result = curl_exec($handle);
if (empty($result)) {
// some kind of an error happened
die(curl_error($handle));
curl_close($handle); // close cURL handler
}
//Free the resource
curl_close($handle);
$signaturePos = strpos($authorizationValue, "Signature=");
if($signaturePos == FALSE || $signaturePos + 10 >= strlen($authorizationValue)) {
$signatureStr = "Malformed";
}
else {
$signatureStr = substr($authorizationValue, $signaturePos + 10);
}
print_r($result);
exit;
return $result;
}
/**
* Gets the region based on the server we connect too.
*
* #return The region.
*/
public static function getRegion() {
$endpoint = Self::ENDPOINT;
$regionName = "us-east-1";
if ($endpoint == "agcod-v2-eu.amazon.com" || $endpoint == "agcod-v2-eu-gamma.amazon.com") {
$regionName = "eu-west-1";
}
else if ($endpoint == "agcod-v2-fe.amazon.com" || $endpoint == "agcod-v2-fe-gamma.amazon.com") {
$regionName = "us-west-2";
}
return $regionName;
}
/**
* Performs a hmac hash using sha256, which is what AWS uses.
*
* #param $data The data to sign.
* #param $key The key to sign the data with.
* #param $raw true to provide a raw ascii string, false to use a hex string.
* #return the hash of $data
*/
public static function hmac($data, $key, $raw = true) {
return hash_hmac("sha256", $data, $key, $raw);
}
/**
* Gets the date for the request, which is either what the client passed in, or today if none was given.
*
* #return The date in YYYYMMDD format.
*/
public static function getDateString($dateTimeString) {
// $dateTimeString = Self::getTimeStamp();
return substr($dateTimeString, 0, 8);
}
/**
* Builds the derived key, which is used for authorizating the request.
*
* #param $rawOutput true to return an ascii string using raw byes, false to return a hex string
*/
public static function buildDerivedKey($dateString, $rawOutput = true) {
$KEY_QUALIFIER = Self::KEY_QUALIFIER;
$TERMINATION_STRING = Self::TERMINATION_STRING;
$SERVICE_NAME= Self::SERVICE_NAME;
// Get pasted AWS Secret Key from user input
$awsSecretKey = Self::$awsSecretKey;
// Append Key Qaulifier, "AWS4", to secret key per http://docs.aws.amazon.com/general/latest/gr/signature-v4-examples.html
$signatureAWSKey = $KEY_QUALIFIER . $awsSecretKey;
$regionName = Self::getRegion();
// $dateString = Self::getDateString();
$kDate = Self::hmac($dateString, $signatureAWSKey);
$kRegion = Self::hmac($regionName, $kDate);
$kService = Self::hmac($SERVICE_NAME, $kRegion);
// Derived the Signing key (derivedKey aka kSigning)
$derivedKey = Self::hmac($TERMINATION_STRING, $kService, $rawOutput);
return $derivedKey;
}
}

How can I get email from Google People API?

I am using Google people API client library in PHP.
After successfully authenticating, I want to get email
Help me to find out the problem from my code below.
Can i use multiple scopes to get email, beacuse when i m using different scope it gives me error
function getClient() {
$client = new Google_Client();
$client->setApplicationName('People API');
$client->setScopes(Google_Service_PeopleService::CONTACTS);
$client->setAuthConfig('credentials.json');
$client->setAccessType('offline');
$client->setPrompt('select_account consent');
$str = file_get_contents('credentials.json');
$json = json_decode( $str, true );
$url = $json['web']['redirect_uris'][0];
if (isset($_GET['oauth'])) {
$auth_url = $client->createAuthUrl();
header('Location: ' . filter_var($auth_url, FILTER_SANITIZE_URL));
} else if (isset($_GET['code'])) {
$client->authenticate($_GET['code']);
$_SESSION['access_token'] = $client->getAccessToken();
$redirect_uri = $url;
header('Location: ' . filter_var($redirect_uri,FILTER_SANITIZE_URL));
} else if (isset($_SESSION['access_token']) && $_SESSION['access_token']) {
$client->setAccessToken($_SESSION['access_token']);
$people_service = new Google_Service_PeopleService($client);
} else {
$redirect_uri = $url.'/?oauth';
header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
}
return $people_service;
}
$optParams = array(
'pageSize' => 100,
'personFields' => 'addresses,ageRanges,biographies,birthdays,braggingRights,coverPhotos,emailAddresses,events,genders,imClients,interests,locales,memberships,metadata,names,nicknames,occupations,organizations,phoneNumbers,photos,relations,relationshipInterests,relationshipStatuses,residences,sipAddresses,skills,taglines,urls,userDefined',
);
$people_service = getClient();
$connections = $people_service->people_connections-
>listPeopleConnections('people/me', $optParams);

Undefined index: action error in facebook api

I am using php api's in my website (to make a profile page)
I am using the below code:
$action = $_REQUEST["action"];
switch($action){
case "fblogin":
include 'facebook.php';
$appid = "**********";
$appsecret = "*************************";
$facebook = new Facebook(array(
'appId' => $appid,
'secret' => $appsecret,
'cookie' => TRUE,
));
$fbuser = $facebook->getUser();
if ($fbuser) {
try {
$user_profile = $facebook->api('/me');
}
catch (Exception $e) {
echo $e->getMessage();
exit();
}
$user_fbid = $fbuser;
$user_email = $user_profile["email"];
$user_fnmae = $user_profile["first_name"];
$user_image = "https://graph.facebook.com/".$user_fbid."/picture?type=large";
$check_select = mysql_num_rows(mysql_query("SELECT * FROM `fblogin` WHERE email = '$user_email'"));
if($check_select > 0){
mysql_query("INSERT INTO `fblogin` (fb_id, name, email, image, postdate) VALUES ('$user_fbid', '$user_fnmae', '$user_email', '$user_image', '$now')");
}
}
break;
}
It gives an error saying : Undefined index: action
I am using wamp server as localhost. Please provide a solution

Will PayPal Pro processor work for PayPal Advance Payments?

I am working with CiviCRM in a Wordpress install, and it has a payment processor written for PayPal Pro. However, we need to use PayPal Advanced instead. Does anyone know if the processor / API for PayPal Pro is somehow backwards compatible for PayPal Advanced Payments?
Here is the current IPN code:
<?php
/*
+--------------------------------------------------------------------+
| CiviCRM version 4.3 |
+--------------------------------------------------------------------+
| Copyright CiviCRM LLC (c) 2004-2013 |
+--------------------------------------------------------------------+
| This file is a part of CiviCRM. |
| |
| CiviCRM is free software; you can copy, modify, and distribute it |
| under the terms of the GNU Affero General Public License |
| Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
| |
| CiviCRM is distributed in the hope that it will be useful, but |
| WITHOUT ANY WARRANTY; without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
| See the GNU Affero General Public License for more details. |
| |
| You should have received a copy of the GNU Affero General Public |
| License and the CiviCRM Licensing Exception along |
| with this program; if not, contact CiviCRM LLC |
| at info[AT]civicrm[DOT]org. If you have questions about the |
| GNU Affero General Public License or the licensing of CiviCRM, |
| see the CiviCRM license FAQ at http://civicrm.org/licensing |
+--------------------------------------------------------------------+
*/
/**
*
* #package CRM
* #copyright CiviCRM LLC (c) 2004-2013
* $Id$
*
*/
class CRM_Core_Payment_PayPalProIPN extends CRM_Core_Payment_BaseIPN {
static $_paymentProcessor = NULL;
function __construct() {
parent::__construct();
}
function getValue($name, $abort = TRUE) {
if (!empty($_POST)) {
$rpInvoiceArray = array();
$value = NULL;
$rpInvoiceArray = explode('&', $_POST['rp_invoice_id']);
foreach ($rpInvoiceArray as $rpInvoiceValue) {
$rpValueArray = explode('=', $rpInvoiceValue);
if ($rpValueArray[0] == $name) {
$value = $rpValueArray[1];
}
}
if ($value == NULL && $abort) {
echo "Failure: Missing Parameter $name<p>";
exit();
}
else {
return $value;
}
}
else {
return NULL;
}
}
static function retrieve($name, $type, $location = 'POST', $abort = TRUE) {
static $store = NULL;
$value = CRM_Utils_Request::retrieve($name, $type, $store,
FALSE, NULL, $location
);
if ($abort && $value === NULL) {
CRM_Core_Error::debug_log_message("Could not find an entry for $name in $location");
echo "Failure: Missing Parameter<p>";
exit();
}
return $value;
}
function recur(&$input, &$ids, &$objects, $first) {
if (!isset($input['txnType'])) {
CRM_Core_Error::debug_log_message("Could not find txn_type in input request");
echo "Failure: Invalid parameters<p>";
return FALSE;
}
if ($input['txnType'] == 'recurring_payment' &&
$input['paymentStatus'] != 'Completed'
) {
CRM_Core_Error::debug_log_message("Ignore all IPN payments that are not completed");
echo "Failure: Invalid parameters<p>";
return FALSE;
}
$recur = &$objects['contributionRecur'];
// make sure the invoice ids match
// make sure the invoice is valid and matches what we have in
// the contribution record
if ($recur->invoice_id != $input['invoice']) {
CRM_Core_Error::debug_log_message("Invoice values dont match between database and IPN request recur is " . $recur->invoice_id . " input is " . $input['invoice']);
echo "Failure: Invoice values dont match between database and IPN request recur is " . $recur->invoice_id . " input is " . $input['invoice'];
return FALSE;
}
$now = date('YmdHis');
// fix dates that already exist
$dates = array('create', 'start', 'end', 'cancel', 'modified');
foreach ($dates as $date) {
$name = "{$date}_date";
if ($recur->$name) {
$recur->$name = CRM_Utils_Date::isoToMysql($recur->$name);
}
}
$sendNotification = FALSE;
$subscriptionPaymentStatus = NULL;
//List of Transaction Type
/*
recurring_payment_profile_created RP Profile Created
recurring_payment RP Sucessful Payment
recurring_payment_failed RP Failed Payment
recurring_payment_profile_cancel RP Profile Cancelled
recurring_payment_expired RP Profile Expired
recurring_payment_skipped RP Profile Skipped
recurring_payment_outstanding_payment RP Sucessful Outstanding Payment
recurring_payment_outstanding_payment_failed RP Failed Outstanding Payment
recurring_payment_suspended RP Profile Suspended
recurring_payment_suspended_due_to_max_failed_payment RP Profile Suspended due to Max Failed Payment
*/
//set transaction type
$txnType = $_POST['txn_type'];
//Changes for paypal pro recurring payment
switch ($txnType) {
case 'recurring_payment_profile_created':
$recur->create_date = $now;
$recur->contribution_status_id = 2;
$recur->processor_id = $_POST['recurring_payment_id'];
$recur->trxn_id = $recur->processor_id;
$subscriptionPaymentStatus = CRM_Core_Payment::RECURRING_PAYMENT_START;
$sendNotification = TRUE;
break;
case 'recurring_payment':
if ($first) {
$recur->start_date = $now;
}
else {
$recur->modified_date = $now;
}
//contribution installment is completed
if ($_POST['profile_status'] == 'Expired') {
$recur->contribution_status_id = 1;
$recur->end_date = $now;
$sendNotification = TRUE;
$subscriptionPaymentStatus = CRM_Core_Payment::RECURRING_PAYMENT_END;
}
// make sure the contribution status is not done
// since order of ipn's is unknown
if ($recur->contribution_status_id != 1) {
$recur->contribution_status_id = 5;
}
break;
}
$recur->save();
if ($sendNotification) {
$autoRenewMembership = FALSE;
if ($recur->id &&
isset($ids['membership']) && $ids['membership']
) {
$autoRenewMembership = TRUE;
}
//send recurring Notification email for user
CRM_Contribute_BAO_ContributionPage::recurringNotify($subscriptionPaymentStatus,
$ids['contact'],
$ids['contributionPage'],
$recur,
$autoRenewMembership
);
}
if ($txnType != 'recurring_payment') {
return;
}
if (!$first) {
//check if this contribution transaction is already processed
//if not create a contribution and then get it processed
$contribution = new CRM_Contribute_BAO_Contribution();
$contribution->trxn_id = $input['trxn_id'];
if ($contribution->trxn_id && $contribution->find()) {
CRM_Core_Error::debug_log_message("returning since contribution has already been handled");
echo "Success: Contribution has already been handled<p>";
return TRUE;
}
$contribution->contact_id = $ids['contact'];
$contribution->financial_type_id = $objects['contributionType']->id;
$contribution->contribution_page_id = $ids['contributionPage'];
$contribution->contribution_recur_id = $ids['contributionRecur'];
$contribution->receive_date = $now;
$contribution->currency = $objects['contribution']->currency;
$contribution->payment_instrument_id = $objects['contribution']->payment_instrument_id;
$contribution->amount_level = $objects['contribution']->amount_level;
$objects['contribution'] = &$contribution;
}
$this->single($input, $ids, $objects,
TRUE, $first
);
}
function single(&$input, &$ids, &$objects, $recur = FALSE, $first = FALSE) {
$contribution = &$objects['contribution'];
// make sure the invoice is valid and matches what we have in the contribution record
if ((!$recur) || ($recur && $first)) {
if ($contribution->invoice_id != $input['invoice']) {
CRM_Core_Error::debug_log_message("Invoice values dont match between database and IPN request");
echo "Failure: Invoice values dont match between database and IPN request<p>contribution is" . $contribution->invoice_id . " and input is " . $input['invoice'];
return FALSE;
}
}
else {
$contribution->invoice_id = md5(uniqid(rand(), TRUE));
}
if (!$recur) {
if ($contribution->total_amount != $input['amount']) {
CRM_Core_Error::debug_log_message("Amount values dont match between database and IPN request");
echo "Failure: Amount values dont match between database and IPN request<p>";
return FALSE;
}
}
else {
$contribution->total_amount = $input['amount'];
}
$transaction = new CRM_Core_Transaction();
// fix for CRM-2842
// if ( ! $this->createContact( $input, $ids, $objects ) ) {
// return false;
// }
$participant = &$objects['participant'];
$membership = &$objects['membership'];
$status = $input['paymentStatus'];
if ($status == 'Denied' || $status == 'Failed' || $status == 'Voided') {
return $this->failed($objects, $transaction);
}
elseif ($status == 'Pending') {
return $this->pending($objects, $transaction);
}
elseif ($status == 'Refunded' || $status == 'Reversed') {
return $this->cancelled($objects, $transaction);
}
elseif ($status != 'Completed') {
return $this->unhandled($objects, $transaction);
}
// check if contribution is already completed, if so we ignore this ipn
if ($contribution->contribution_status_id == 1) {
$transaction->commit();
CRM_Core_Error::debug_log_message("returning since contribution has already been handled");
echo "Success: Contribution has already been handled<p>";
return TRUE;
}
$this->completeTransaction($input, $ids, $objects, $transaction, $recur);
}
function main($component = 'contribute') {
CRM_Core_Error::debug_var('GET', $_GET, TRUE, TRUE);
CRM_Core_Error::debug_var('POST', $_POST, TRUE, TRUE);
$objects = $ids = $input = array();
$input['component'] = $component;
// get the contribution and contact ids from the GET params
$ids['contact'] = self::getValue('c', TRUE);
$ids['contribution'] = self::getValue('b', TRUE);
$this->getInput($input, $ids);
if ($component == 'event') {
$ids['event'] = self::getValue('e', TRUE);
$ids['participant'] = self::getValue('p', TRUE);
$ids['contributionRecur'] = self::getValue('r', FALSE);
}
else {
// get the optional ids
$ids['membership'] = self::retrieve('membershipID', 'Integer', 'GET', FALSE);
$ids['contributionRecur'] = self::getValue('r', FALSE);
$ids['contributionPage'] = self::getValue('p', FALSE);
$ids['related_contact'] = self::retrieve('relatedContactID', 'Integer', 'GET', FALSE);
$ids['onbehalf_dupe_alert'] = self::retrieve('onBehalfDupeAlert', 'Integer', 'GET', FALSE);
}
if (!$ids['membership'] && $ids['contributionRecur']) {
$sql = "
SELECT m.id
FROM civicrm_membership m
INNER JOIN civicrm_membership_payment mp ON m.id = mp.membership_id AND mp.contribution_id = %1
WHERE m.contribution_recur_id = %2
LIMIT 1";
$sqlParams = array(1 => array($ids['contribution'], 'Integer'),
2 => array($ids['contributionRecur'], 'Integer'),
);
if ($membershipId = CRM_Core_DAO::singleValueQuery($sql, $sqlParams)) {
$ids['membership'] = $membershipId;
}
}
$paymentProcessorID = CRM_Core_DAO::getFieldValue('CRM_Financial_DAO_PaymentProcessorType',
'PayPal', 'id', 'name'
);
if (!$this->validateData($input, $ids, $objects, TRUE, $paymentProcessorID)) {
return FALSE;
}
self::$_paymentProcessor = &$objects['paymentProcessor'];
if ($component == 'contribute' || $component == 'event') {
if ($ids['contributionRecur']) {
// check if first contribution is completed, else complete first contribution
$first = TRUE;
if ($objects['contribution']->contribution_status_id == 1) {
$first = FALSE;
}
return $this->recur($input, $ids, $objects, $first);
}
else {
return $this->single($input, $ids, $objects, FALSE, FALSE);
}
}
else {
return $this->single($input, $ids, $objects, FALSE, FALSE);
}
}
function getInput(&$input, &$ids) {
if (!$this->getBillingID($ids)) {
return FALSE;
}
$input['txnType'] = self::retrieve('txn_type', 'String', 'POST', FALSE);
$input['paymentStatus'] = self::retrieve('payment_status', 'String', 'POST', FALSE);
$input['invoice'] = self::getValue('i', TRUE);
$input['amount'] = self::retrieve('mc_gross', 'Money', 'POST', FALSE);
$input['reasonCode'] = self::retrieve('ReasonCode', 'String', 'POST', FALSE);
$billingID = $ids['billing'];
$lookup = array(
"first_name" => 'first_name',
"last_name" => 'last_name',
"street_address-{$billingID}" => 'address_street',
"city-{$billingID}" => 'address_city',
"state-{$billingID}" => 'address_state',
"postal_code-{$billingID}" => 'address_zip',
"country-{$billingID}" => 'address_country_code',
);
foreach ($lookup as $name => $paypalName) {
$value = self::retrieve($paypalName, 'String', 'POST', FALSE);
$input[$name] = $value ? $value : NULL;
}
$input['is_test'] = self::retrieve('test_ipn', 'Integer', 'POST', FALSE);
$input['fee_amount'] = self::retrieve('mc_fee', 'Money', 'POST', FALSE);
$input['net_amount'] = self::retrieve('settle_amount', 'Money', 'POST', FALSE);
$input['trxn_id'] = self::retrieve('txn_id', 'String', 'POST', FALSE);
}
}

Is there any way to get facebook user email with django-facebookconnect?

I already integrate django-facebookconnect on my project, but when user login email field stay empty, i mean this app does not save user email ??
It seems like it does:
user = User(username=request.facebook.uid,
password=sha.new(str(random.random())).hexdigest()[:8],
email=profile.email)
But when i check it does not saves email, is this an error or a facebook restriction?
You need to get the extended permission from facebook.
<?php
$app_id = "YOUR_APP_ID";
$app_sec = "APP_SEC";
$canvas_page = "APP_CANVAS_PAGE_URL";
$scope = "&scope=user_photos,email,publish_stream"; $auth_url"http://www.facebook.com/dialog/oauth?client_id=" . $app_id . "&redirect_uri=" . urlencode($canvas_page).$scope;
$signed_request = $_REQUEST["signed_request"];
list($encoded_sig, $payload) = explode(".", $signed_request, 2);
$data = json_decode(base64_decode(strtr($payload, "-_", "+/")), true);
if (empty($data["user_id"])) {
echo(""); }
$access_token = $data["oauth_token"];
$user_id = $data["user_id"];
$user = json_decode(file_get_contents( "https://graph.facebook.com/me? access_token=" . $access_token));
function get_facebook_cookie($app_id, $application_secret) {
$args = array();
parse_str(trim($COOKIE["fbs" . $app_id], "\""), $args);
ksort($args);
$payload = "";
foreach ($args as $key => $value) {
if ($key != "sig") {
$payload .= $key . "=" . $value;
}
}
if (md5($payload . $application_secret) != $args["sig"]) {
return null;
}
return $args;
}
$cookie = get_facebook_cookie($app_id, $app_sec);
?>