I have the following cloud code on parse to update a user image but I can't seem to get it saving. help!
in php
ParseCloud::run("updateUserImage", array("file" => $_FILES['image'], "objectId" => $objectId, "name" => $_FILES['image']['name'], "type"=> $_FILES['image']['type'] ));
in cloud code
Parse.Cloud.define("updateUserImage", async (request) => {
const { file, objectId, name, type} = request.params;
var fileData = request.params.file;
var fileSave = new Parse.File(name, fileData);
fileSave.save();
var User = Parse.Object.extend(Parse.User);
var query = new Parse.Query(User);
let result = await query.get(objectId, { useMasterKey: true });
if (!result) new Error("No user found!");
result.set("profilePicture", fileSave);
try {
result.save(null, { useMasterKey: true });
return "User updated successfully!";
} catch (e) {
return e.message;
}
});
Related
i am using document picker to upload an image via php.
this is my js code:
const [singleFile, setSingleFile] = useState(null);
const uploadImage = async () => {
// Check if any file is selected or not
if (singleFile != null) {
// If file selected then create FormData
const fileToUpload = singleFile;
const data = new FormData();
data.append('name', 'imgup');
data.append('attachement_file', fileToUpload);
axios.post(''+ALL.API_URL+'/sellwithus/upload.php', data, {
headers: {
'Content-Type': 'multipart/form-data; ',
}
})
.then((response) => {
console.log(response);
})
} else {
// If no file selected the show alert
alert('Please Select File first');
}
};
the select code:
const selectFile = async () => {
// Opening Document Picker to select one file
try {
const res = await DocumentPicker.pick({
// Provide which type of file you want user to pick
type: [DocumentPicker.types.images],
// There can me more options as well
// DocumentPicker.types.allFiles
// DocumentPicker.types.images
// DocumentPicker.types.plainText
// DocumentPicker.types.audio
// DocumentPicker.types.pdf
});
// Printing the log realted to the file
console.log('res : ' + JSON.stringify(res));
// Setting the state to show single file attributes
setSingleFile(res);
} catch (err) {
setSingleFile(null);
// Handling any exception (If any)
if (DocumentPicker.isCancel(err)) {
// If user canceled the document selection
alert('Canceled');
} else {
// For Unknown Error
alert('Unknown Error: ' + JSON.stringify(err));
throw err;
}
}
};
this is the res result:
console.log(JSON.stringify(res));
res
:[{"size":1454366,"fileCopyUri":null,"name":"D0BED0E3-4567-41DA-9B21-8C409E355A87.JPG","uri":"file:///Users/saeedmatar/Library/Developer/CoreSimulator/Devices/098A7371-530E-4667-AAAF-80EAE97F9A9E/data/Containers/Data/Application/06A2878B-D812-4B3C-BEF0-2E40DBFE9A27/tmp/org.reactjs.native.example.JelApp-Inbox/D0BED0E3-4567-41DA-9B21-8C409E355A87.JPG"}]
this is my php code:
$_POST = json_decode(file_get_contents("php://input"),true);
$imageData=$_POST["_parts"][1][1][0];
file_put_contents('uploads/image.JPG', $imageData["uri"]);
the image that uploaded is 0 mb and not appearing.
how can i use uri to upload the image?
File uri returned by react-native-document-picker is a reference in the device app local cache and can't be used to upload data.
Fetch and upload document BLOB data.
const blob = await new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.onload = function () {
resolve(xhr.response);
};
xhr.onerror = function (e) {
reject(new TypeError("Network request failed"));
};
xhr.responseType = "blob";
xhr.open("GET", [DOCUMENT_PATH_URI_HERE], true);
xhr.send(null);
});
// code to submit blob data
// We're done with the blob, close and release it
blob.close();
I have a laravel-application where I want to generate a PDF from the values, the user has entered in some input fields. So when the user has entered the data, he clicks a button which generates the PDF and downloads it immediately afterwards automatically. All this should happen on the same route/view. The PDF should not be stored somewhere.
So right now, when I click the button, the entered Data gets through, e.g. stored in the DB, and it seems that a PDF is created, but I can't see or find it, and my browser does not inform me that there is a PDF available for download.
Before I started, I installed the laravel-dompdf-plugin, and followed the instructions.
So my route look like this
Route::view('formpage', 'app.statement')->name('statement'); // The blade view with the Form
Route::post('statement', 'MyController#generatePDF')->name('generatePDF'); // this is where I post the form
This is my controller
use PDF;
class MyController extends Controller {
public function generatePDF(Request $request){
$statement = Statement::create([
'name' => $validated['name'],
'email' => $validated['email'],
'phone' => $validated['phone'],
'declaration_date' => $validated['declaration_date'],
]);
$pdf = PDF::loadView('pdf.statement', $statement);
return $pdf->download('File__'.$statement->name.'.pdf');
}
}
I posting the form with javascript by using axios by simply doing this:
$('#submitBtn').click(function(e) {
const formData = new FormData();
formData.append(
"name",
$("#statement")
.find('input[name="name"]')
.val()
);
...etc with all other fields
axios.post($("#statement form").attr("action"), formData)
.then(response => {
$('#submitBtn')
.attr("disabled", "disabled")
.addClass("disabled")
.html('<i class="fas fa-fw fa-check"></i> Success'); */
$("#statement form")[0].reset();
})
.catch(error => {
console.log("ERR: ", error); // DEBUG
$("#statement .text-danger").show();
$('#sworn-statement button[type="submit"]')
.removeAttr("disabled")
.removeClass("disabled")
.html("Send");
});
}
What am I doing wrong?
UPDATE
I tried to do this:
const FileDownload = require("js-file-download");
axios.post($("#statement form").attr("action"), formData)
.then(response => {
FileDownload(response.data,"File.pdf");
}).catch(error => {
console.log('error:', error);
});
which gives me a blank page.
So as I said in the comments your problem is that the file is in the response you get from the axios POST request. If you don't handle the filedownload after you get the response nothing will happen.
You can use the js-file-download module. After you've installed this module you can modify your code to something like this:
const FileDownload = require('js-file-download');
axios.get(YOUR_URL)
.then((response) => {
FileDownload(response.data, YOUR_FILE_NAME);
});
There's also an another solution with JQuery which I got from that answer:
$.ajax({
type: "POST",
url: url,
data: params,
success: function(response, status, xhr) {
// check for a filename
var filename = "";
var disposition = xhr.getResponseHeader('Content-Disposition');
if (disposition && disposition.indexOf('attachment') !== -1) {
var filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/;
var matches = filenameRegex.exec(disposition);
if (matches != null && matches[1]) filename = matches[1].replace(/['"]/g, '');
}
var type = xhr.getResponseHeader('Content-Type');
var blob = new Blob([response], { type: type });
if (typeof window.navigator.msSaveBlob !== 'undefined') {
// IE workaround for "HTML7007: One or more blob URLs were revoked by closing the blob for which they were created. These URLs will no longer resolve as the data backing the URL has been freed."
window.navigator.msSaveBlob(blob, filename);
} else {
var URL = window.URL || window.webkitURL;
var downloadUrl = URL.createObjectURL(blob);
if (filename) {
// use HTML5 a[download] attribute to specify filename
var a = document.createElement("a");
// safari doesn't support this yet
if (typeof a.download === 'undefined') {
window.location = downloadUrl;
} else {
a.href = downloadUrl;
a.download = filename;
document.body.appendChild(a);
a.click();
}
} else {
window.location = downloadUrl;
}
setTimeout(function () { URL.revokeObjectURL(downloadUrl); }, 100); // cleanup
}
}
});
Just replace the url and params attributes with your stuff. This creates also a POST request and handles the incomming PDF file as filedownload after the response arrives.
I want to send a docx file to the client in the response of a get request:
Here's the Laravel controller code:
public function file($id)
{
$dlink = resource_path('temp/' . $id . '.docx');
$headers = [
'Content-Type' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
];
return response()->download($dlink, $id . '.docx', $headers);
}
VueJS code:
axios.get(`${location.protocol}//${location.host}/api/download/${response.data}`,
{ responseType: "arraybuffer" }
)
.then(response => {
this.downloadFile(response);
})
.catch(err => alert(err));
downloadFile(response) {
var newBlob = new Blob([response.body], {
type: "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
});
if (window.navigator && window.navigator.msSaveOrOpenBlob) {
window.navigator.msSaveOrOpenBlob(newBlob);
return;
}
const data = window.URL.createObjectURL(newBlob);
var link = document.createElement("a");
link.href = data;
link.download = "resume.docx";
link.click();
setTimeout(function() {
window.URL.revokeObjectURL(data);
}, 100);
}
It doesn't show any error. but downloads a corrupted 9bytes docx file.
changing response.body to response.data did the job.
I'm using laravel 4.2 and currently I don't how to save a csv file into public\csv\ directory using AJAX. I'm still finding some answers. Maybe someone can help me with this.
Here's my code:
In blade view:
{{Form::open(['route' => 'file_upload', 'files' => true, 'id' => 'upload_form', 'method' => 'POST'])}}
{{Form::file('csv_upload', ['id' => 'uploaded_file', 'accept' => 'text/csv'])}}
{{Form::submit('submit', ['class' => 'btn btn-primary btn-xs', 'id' => 'upload'])}}
{{Form::close()}}
Javascript Ajax:
var ajax_ready = 1
var token = {{Session::get('_token')}}
if($.type(originalOptions.data) === 'string') {
options.data = originalOptions.data+"&_token="+token;
}else if($.type(originalOptions.data) === 'object') {
//Here I got a new error
}else{
options.data = $.param(($.extend(originalOptions.data, {'_token':mmad_token})));
}
options.url = originalOptions.url.slice(0,originalOptions.url.indexOf("?_token="));
if (ajax_ready!=1){
jqXHR.abort();
}
ajax_ready = 0;
});
$('form#upload_form').on('submit', function(e){
e.preventDefault();
var uploadFile = $('#uploaded_file');
var ext = $("input#uploaded_file").val().split(".").pop().toLowerCase();
var file = $('input[name="csv_upload"]').val();
if($.inArray(ext, ["csv"]) === -1) {
alert("Please upload a .csv file!");
return false;
}
var csv = uploadFile[0].files;
var form = new FormData(this);
var csvFile = {lastModifed: csv[0].lastModified, fileName: csv[0].name, size: csv[0].size, fileType: csv[0].type};
$.post('{{ URL::route("file_upload") }}?_token={{Session::token()}}',{
data: form
}).done(function(response){
});
});
PHP:
public function upload_csv()
{
$inputs = Input::all();
$csvFile = $inputs['data']['fileName'];
$path = public_path().DIRECTORY_SEPARATOR.'csv'.DIRECTORY_SEPARATOR;
$path2 = public_path('csv/');
if(is_dir($path2))
{
#move_uploaded_file($csvFile, $path2.$csvFile); //This line can't move the uploaded files in my desired directory
}
return json_encode(['success' => 1, 'description' => 'Successfully Upload File']);
}
This code below does work when not using AJAX:
if(Input::hasFile('csv_upload'))
{
$file = Input::file('csv_upload');
$originalFilename = $file->getClientOriginalName();
$rules = ['csv_upload' => 'required|file:csv'];
$validate = Validator::make(['csv_upload' => $file], $rules);
if($validate->fails())
{
return json_encode(['error' => 1, 'description' => 'File must be in .csv format']);
}
$path = public_path('/csv/');
if(!file_exists($path))
{
mkdir($path);
}
}
Console.log of csv
You can not move file because when you submit form with ajax file is not being sent with ajax,For sending file you have to send file with FormData() javascript Object.
If you check in upload_csv controller by putting print_r($_FILES); you will get empty array.
So use FormData on client side for appending file, then try agian.
You aren't getting error beacuse you have used php Error Control Operators likes#move_uploaded_file($csvFile, $path2.$csvFile);.
if you need working example then tell me i will give it to you.
Code For Your Help:
1. In blade view:
<script type="text/javascript">
$('form#upload_form').on('submit', function(e){
e.preventDefault();
var uploadFile = $('#uploaded_file');
var ext = $("input#uploaded_file").val().split(".").pop().toLowerCase();
var file = $('input[name="mmad_csv_upload"]').val();
if($.inArray(ext, ["csv"]) === -1) {
alert("Please upload a .csv file!");
return false;
}
var csv = uploadFile[0].files;
var formData = new FormData($(this)[0]);
formData.append('uploaded_file', $("#uploaded_file")[0].files[0]);
formData.append('lastModifed', csv[0].lastModified);
formData.append('fileName', csv[0].name);
console.log(formData);
$.ajax({
url: '{{ URL::route("file_upload") }}',
type: 'POST',
data: formData,
async: true,
cache: false,
contentType: false,
processData: false,
success: function (returndata) { //alert(returndata); return false;
}
});
});
</script>
2.Controller
public function file_upload(Request $request)
{
$inputs = Input::all();
$csvFile = $inputs['fileName'];
$path = public_path().DIRECTORY_SEPARATOR.'csv'.DIRECTORY_SEPARATOR;
$path2 = public_path('/csv/');
if(is_dir($path2))
{
$success = $request->file('uploaded_file')->move($path2, $csvFile);
}
return json_encode(['success' => 1, 'description' => 'Successfully Upload File']);
}
To move the uploaded file to a new location, you should use the move method. This method will move the file from its temporary upload location (as determined by your PHP configuration) to a more permanent destination of your choosing:
Input::file('fileName')->move($destinationPath, $fileName);
If you need additional validations, you can check it at http://laravel.com/docs/5.1/requests#files
Default AJAX POST does not support file uploads. Use jQuery Form to upload files successfully. Full documentation of file upload at http://malsup.com/jquery/form/#file-upload
Below my example of a recentlty build script... My Controller uploads the files to S3, but is easy to be implemented with local storage.
var progress = function(event, position, total, percent) {
$(".progress-bar").width(percent + '%');
$(".progress-bar").html(percent + '%');
if(percent > 50) {
$(".progress-bar").css('color','#fff');
}
if(percent == 100) {
setTimeout(function(){
$(".progress").html('<span class="processing-msg">Processing... Please be patient!</span>');
$(".processing-msg").fadeIn('slow');
}, 1000);
}
}
var success = function(data) {
var obj = $.parseJSON(data);
$("#"+obj.hidden, parent.document).val(obj.filename);
var src = 'https://s3.amazonaws.com/spincms'+obj.path+'thumb_'+obj.filename;
$("#uploaded-"+obj.hidden, parent.document).html('<img class="img-circle uploaded-img" src="' + src + '">');
$(".progress").html('<span class="processing-msg-next">File has been uploaded and processed. Do not forget to submit the form!</span>');
}
var options = {
target: '#output',
uploadProgress: progress,
success: success,
resetForm: true
};
$(document).on('click', "#upload-now", function(e) {
$(".progress").html('<div class="progress-bar progress-bar-success" role="progressbar" aria-valuenow="60" aria-valuemin="0" aria-valuemax="100"></div>');
if($("#upload-form input[type=file]")[0].files.length == 0) {
$(".progress").html('<span class="processing-msg-next">No file selected!</span>');
return false;
} else {
var name = $("#upload-form input[name='name']").val();
var token = $("#upload-form input[name='_token']").val();
var file_name = $("#upload-form input[type=file]")[0].files[0].name;
$("#upload-form").ajaxSubmit(options);
}
}
});
Since you are using jQuery you can use the form plugin as it will make things much more easier for you to work with for example , this is the jquery part that you will use :
$(document).ready(function() {
// bind 'myForm' and provide a simple callback function
$('#upload_form').ajaxForm(function() {
alert("Your file has been uploaded, thanks");
});
});
and in your controller you can code it like :
pubilc function postUpload()
{
$success = false;
if(Request::ajax())
{
if(Input::hasFile('csv_upload'))
{
$file = Input::file('csv_upload');
if(!File::isDirectory(storage_path('csv'))) {
File::createDirectory(storage_path('csv'));
}
$file->move(storage_path('csv'), $file->getClientOriginalName());
// now your file is on app/storage/csv folder
$filePath = storage_path('csv/'.$file->getClientOriginalName());
$success = true;
}
}
return Response::json(['success'=>$success]);
}
So, I have this HTML5 chatting script which requires users to input their name and email to start chatting. The script grabs the users display picture from gavatar. I'm trying to change that to make it take a webcam snapshot from the users computer and set that as a display picture.
I've seen a few examples of the usage of HTML5 to access the users webcam but I can't seem to figure out how to automatically take the snapshot and set it as the users display picture.
Here's my current code.
$(document).ready(function(){
// Run the init method on document ready:
chat.init();
});
var chat = {
// data holds variables for use in the class:
data : {
lastID : 0,
noActivity : 0
},
// Init binds event listeners and sets up timers:
init : function(){
// Using the defaultText jQuery plugin, included at the bottom:
$('#name').defaultText('Nickname');
$('#email').defaultText('Email');
// Converting the #chatLineHolder div into a jScrollPane,
// and saving the plugin's API in chat.data:
chat.data.jspAPI = $('#chatLineHolder').jScrollPane({
verticalDragMinHeight: 12,
verticalDragMaxHeight: 12
}).data('jsp');
// We use the working variable to prevent
// multiple form submissions:
var working = false;
// Logging a person in the chat:
$('#loginForm').submit(function(){
if(working) return false;
working = true;
// Using our tzPOST wrapper function
// (defined in the bottom):
$.tzPOST('login',$(this).serialize(),function(r){
working = false;
if(r.error){
chat.displayError(r.error);
}
else chat.login(r.name,r.gravatar);
});
return false;
});
// Submitting a new chat entry:
$('#submitForm').submit(function(){
var text = $('#chatText').val();
if(text.length == 0){
return false;
}
if(working) return false;
working = true;
// Assigning a temporary ID to the chat:
var tempID = 't'+Math.round(Math.random()*1000000),
params = {
id : tempID,
author : chat.data.name,
gravatar : chat.data.gravatar,
text : text.replace(/</g,'<').replace(/>/g,'>')
};
// Using our addChatLine method to add the chat
// to the screen immediately, without waiting for
// the AJAX request to complete:
chat.addChatLine($.extend({},params));
// Using our tzPOST wrapper method to send the chat
// via a POST AJAX request:
$.tzPOST('submitChat',$(this).serialize(),function(r){
working = false;
$('#chatText').val('');
$('div.chat-'+tempID).remove();
params['id'] = r.insertID;
chat.addChatLine($.extend({},params));
});
return false;
});
// Logging the user out:
$('a.logoutButton').live('click',function(){
$('#chatTopBar > span').fadeOut(function(){
$(this).remove();
});
$('#submitForm').fadeOut(function(){
$('#loginForm').fadeIn();
});
$.tzPOST('logout');
return false;
});
// Checking whether the user is already logged (browser refresh)
$.tzGET('checkLogged',function(r){
if(r.logged){
chat.login(r.loggedAs.name,r.loggedAs.gravatar);
}
});
// Self executing timeout functions
(function getChatsTimeoutFunction(){
chat.getChats(getChatsTimeoutFunction);
})();
(function getUsersTimeoutFunction(){
chat.getUsers(getUsersTimeoutFunction);
})();
},
// The login method hides displays the
// user's login data and shows the submit form
login : function(name,gravatar){
chat.data.name = name;
chat.data.gravatar = gravatar;
$('#chatTopBar').html(chat.render('loginTopBar',chat.data));
$('#loginForm').fadeOut(function(){
$('#submitForm').fadeIn();
$('#chatText').focus();
});
},
// The render method generates the HTML markup
// that is needed by the other methods:
render : function(template,params){
var arr = [];
switch(template){
case 'loginTopBar':
arr = [
'<span><img src="',params.gravatar,'" width="23" height="23" />',
'<span class="name">',params.name,
'</span>Logout</span>'];
break;
case 'chatLine':
arr = [
'<div class="chat chat-',params.id,' rounded"><span class="gravatar"><img src="',params.gravatar,
'" width="23" height="23" onload="this.style.visibility=\'visible\'" />','</span><span class="author">',params.author,
':</span><span class="text">',params.text,'</span><span class="time">',params.time,'</span></div>'];
break;
case 'user':
arr = [
'<div class="user" title="',params.name,'"><img src="',
params.gravatar,'" width="30" height="30" onload="this.style.visibility=\'visible\'" /></div>'
];
break;
}
// A single array join is faster than
// multiple concatenations
return arr.join('');
},
// The addChatLine method ads a chat entry to the page
addChatLine : function(params){
// All times are displayed in the user's timezone
var d = new Date();
if(params.time) {
// PHP returns the time in UTC (GMT). We use it to feed the date
// object and later output it in the user's timezone. JavaScript
// internally converts it for us.
d.setUTCHours(params.time.hours,params.time.minutes);
}
params.time = (d.getHours() < 10 ? '0' : '' ) + d.getHours()+':'+
(d.getMinutes() < 10 ? '0':'') + d.getMinutes();
var markup = chat.render('chatLine',params),
exists = $('#chatLineHolder .chat-'+params.id);
if(exists.length){
exists.remove();
}
if(!chat.data.lastID){
// If this is the first chat, remove the
// paragraph saying there aren't any:
$('#chatLineHolder p').remove();
}
// If this isn't a temporary chat:
if(params.id.toString().charAt(0) != 't'){
var previous = $('#chatLineHolder .chat-'+(+params.id - 1));
if(previous.length){
previous.after(markup);
}
else chat.data.jspAPI.getContentPane().append(markup);
}
else chat.data.jspAPI.getContentPane().append(markup);
// As we added new content, we need to
// reinitialise the jScrollPane plugin:
chat.data.jspAPI.reinitialise();
chat.data.jspAPI.scrollToBottom(true);
},
// This method requests the latest chats
// (since lastID), and adds them to the page.
getChats : function(callback){
$.tzGET('getChats',{lastID: chat.data.lastID},function(r){
for(var i=0;i<r.chats.length;i++){
chat.addChatLine(r.chats[i]);
}
if(r.chats.length){
chat.data.noActivity = 0;
chat.data.lastID = r.chats[i-1].id;
}
else{
// If no chats were received, increment
// the noActivity counter.
chat.data.noActivity++;
}
if(!chat.data.lastID){
chat.data.jspAPI.getContentPane().html('<p class="noChats">No chats yet</p>');
}
// Setting a timeout for the next request,
// depending on the chat activity:
var nextRequest = 1000;
// 2 seconds
if(chat.data.noActivity > 3){
nextRequest = 2000;
}
if(chat.data.noActivity > 10){
nextRequest = 5000;
}
// 15 seconds
if(chat.data.noActivity > 20){
nextRequest = 15000;
}
setTimeout(callback,nextRequest);
});
},
// Requesting a list with all the users.
getUsers : function(callback){
$.tzGET('getUsers',function(r){
var users = [];
for(var i=0; i< r.users.length;i++){
if(r.users[i]){
users.push(chat.render('user',r.users[i]));
}
}
var message = '';
if(r.total<1){
message = 'No one is online';
}
else {
message = r.total+' '+(r.total == 1 ? 'person':'people')+' online';
}
users.push('<p class="count">'+message+'</p>');
$('#chatUsers').html(users.join(''));
setTimeout(callback,15000);
});
},
// This method displays an error message on the top of the page:
displayError : function(msg){
var elem = $('<div>',{
id : 'chatErrorMessage',
html : msg
});
elem.click(function(){
$(this).fadeOut(function(){
$(this).remove();
});
});
setTimeout(function(){
elem.click();
},5000);
elem.hide().appendTo('body').slideDown();
}
};
// Custom GET & POST wrappers:
$.tzPOST = function(action,data,callback){
$.post('php/ajax.php?action='+action,data,callback,'json');
}
$.tzGET = function(action,data,callback){
$.get('php/ajax.php?action='+action,data,callback,'json');
}
// A custom jQuery method for placeholder text:
$.fn.defaultText = function(value){
var element = this.eq(0);
element.data('defaultText',value);
element.focus(function(){
if(element.val() == value){
element.val('').removeClass('defaultText');
}
}).blur(function(){
if(element.val() == '' || element.val() == value){
element.addClass('defaultText').val(value);
}
});
return element.blur();
}
And this is the PHP file for grabbing the users DP from gravatar.
<?php
class ChatUser extends ChatBase{
protected $name = '', $gravatar = '';
public function save(){
DB::query("
INSERT INTO webchat_users (name, gravatar)
VALUES (
'".DB::esc($this->name)."',
'".DB::esc($this->gravatar)."'
)");
return DB::getMySQLiObject();
}
public function update(){
DB::query("
INSERT INTO webchat_users (name, gravatar)
VALUES (
'".DB::esc($this->name)."',
'".DB::esc($this->gravatar)."'
) ON DUPLICATE KEY UPDATE last_activity = NOW()");
}
}
?>
Also another bit of code.
<?php
/* The Chat class exploses public static methods, used by ajax.php */
class Chat{
public static function login($name,$email){
if(!$name || !$email){
throw new Exception('Fill in all the required fields.');
}
if(!filter_input(INPUT_POST,'email',FILTER_VALIDATE_EMAIL)){
throw new Exception('Your email is invalid.');
}
// Preparing the gravatar hash:
$gravatar = md5(strtolower(trim($email)));
$user = new ChatUser(array(
'name' => $name,
'gravatar' => $gravatar
));
// The save method returns a MySQLi object
if($user->save()->affected_rows != 1){
throw new Exception('This nick is in use.');
}
$_SESSION['user'] = array(
'name' => $name,
'gravatar' => $gravatar
);
return array(
'status' => 1,
'name' => $name,
'gravatar' => Chat::gravatarFromHash($gravatar)
);
}
public static function checkLogged(){
$response = array('logged' => false);
if($_SESSION['user']['name']){
$response['logged'] = true;
$response['loggedAs'] = array(
'name' => $_SESSION['user']['name'],
'gravatar' => Chat::gravatarFromHash($_SESSION['user']['gravatar'])
);
}
return $response;
}
public static function logout(){
DB::query("DELETE FROM webchat_users WHERE name = '".DB::esc($_SESSION['user']['name'])."'");
$_SESSION = array();
unset($_SESSION);
return array('status' => 1);
}
public static function submitChat($chatText){
if(!$_SESSION['user']){
throw new Exception('You are not logged in');
}
if(!$chatText){
throw new Exception('You haven\' entered a chat message.');
}
$chat = new ChatLine(array(
'author' => $_SESSION['user']['name'],
'gravatar' => $_SESSION['user']['gravatar'],
'text' => $chatText
));
// The save method returns a MySQLi object
$insertID = $chat->save()->insert_id;
return array(
'status' => 1,
'insertID' => $insertID
);
}
public static function getUsers(){
if($_SESSION['user']['name']){
$user = new ChatUser(array('name' => $_SESSION['user']['name']));
$user->update();
}
// Deleting chats older than 5 minutes and users inactive for 30 seconds
DB::query("DELETE FROM webchat_lines WHERE ts < SUBTIME(NOW(),'0:5:0')");
DB::query("DELETE FROM webchat_users WHERE last_activity < SUBTIME(NOW(),'0:0:30')");
$result = DB::query('SELECT * FROM webchat_users ORDER BY name ASC LIMIT 18');
$users = array();
while($user = $result->fetch_object()){
$user->gravatar = Chat::gravatarFromHash($user->gravatar,30);
$users[] = $user;
}
return array(
'users' => $users,
'total' => DB::query('SELECT COUNT(*) as cnt FROM webchat_users')->fetch_object()->cnt
);
}
public static function getChats($lastID){
$lastID = (int)$lastID;
$result = DB::query('SELECT * FROM webchat_lines WHERE id > '.$lastID.' ORDER BY id ASC');
$chats = array();
while($chat = $result->fetch_object()){
// Returning the GMT (UTC) time of the chat creation:
$chat->time = array(
'hours' => gmdate('H',strtotime($chat->ts)),
'minutes' => gmdate('i',strtotime($chat->ts))
);
$chat->gravatar = Chat::gravatarFromHash($chat->gravatar);
$chats[] = $chat;
}
return array('chats' => $chats);
}
public static function gravatarFromHash($hash, $size=23){
return 'http://www.gravatar.com/avatar/'.$hash.'?size='.$size.'&default='.
urlencode('http://www.gravatar.com/avatar/ad516503a11cd5ca435acc9bb6523536?size='.$size);
}
}
?>
You can copy the media stream into a canvas and later manipulate as you wish. Then you can assign an event listener to canvas and on mouse click to create an image. You can do that with canvas toDataUrl method.
So the workflow would be something like this:
accessing the camera with getUserMedia
create a copy of the life media stream and move into the canvas
attach an event listener to canvas and on click...
export the canvas to an image with toDataUrl method
I hope you got the idea.
EDIT:
I just found the same explanation done by me with real code example: https://developer.mozilla.org/en-US/docs/WebRTC/Taking_webcam_photos