Hi, you may know me from my time spent working on OpenEx. You may also remember that the product i delivered was subpar and very unacceptable. As a result of the closure of the exchange, i now owe about 10,000 dollars at the time of investment worth of bitcoin to 20 or so investors. I have been working very hard for the last 3 months improving my skills, and i am close to being able to relaunch OpenEx.
I will display a small showcase of my skills here, as well as a link to my stackoverflow profile. I am looking for small jobs in php, jquery, or css/html so that i can begin working on paying off the investors who got the brunt of the demise of OpenEx. I feel very responsible for this. If you are willing at all to give me a shot, even on a trial basis i will work very hard for you and or your company.
I have grown familiar with two sets of front end developer frameworks:
Bootstrap and Ink Interface Kit(
http://ink.sapo.pt)
my stackoverflow profilehttp://stackoverflow.com/users/2401804/r3wtlive demo of OpenEx current versionhttps://openex.infoHere's a few code snippets and/or live examples of sites i am actively developing.
An ajax Profile Picture and Profile Information Update. (jquery,php,ink ui kit)jquery//the profile fields form
$('#profile-up').submit(function() {
var queryString = $(this).formSerialize();
$.post('./ajax/private/?do=profileupdate', queryString, function(data){
var d = JSON.parse(data);
for(var i = 0; i < d.length; i++)
{
if(d[i].type == 'success')
{
$('#'+d[i].message+'').val(d[i].update);
notify('Your '+d[i].message+' was succesfully updated','false');
}
if(d[i].type == 'error')
{
notify(d[i].message,'true');
}
}
});
return false;
});
//the image form
$("#image-up").submit(function(){
$('#loading').show();
$('#overlay').show();
$.ajax({
url: "./upload.php",
type: "POST",
data: new FormData(this),
contentType: false,
cache: false,
processData:false,
success: function(data){
var d = JSON.parse(data);
console.log(d);
for(var i = 0; i < d.length; i++)
{
if(d[i].type == 'error')
{
notify(d[i].message,"true");
}
if(d[i].type == 'success')
{
notify(d[i].message,"true");
$('#profile-pic').attr('src','http://website.com/uploads/'+d[i].update+'');
}
}
},
error: function(){
}
});
$('#overlay').hide();
$('#loading').hide();
return false;
});
//pre upload file tests using html5 file api.
function beforeSubmit() {
if (window.File && window.FileReader && window.FileList && window.Blob)
{
if( !$('#image-input').val())
{
notify("Please select a file to continue",'true');//notify is just a wrapper function to jGrowl.
return false;
}
var fsize = $('#image-input')[0].files[0].size; //get file size
var ftype = $('#image-input')[0].files[0].type; // get file type
switch(ftype)
{
case 'image/png': case 'image/gif': case 'image/jpeg':
break;
default:
notify("Unsupported File Type",'true');
return false;
}
var mbyte = 1048576;
if(fsize> mbyte)
{
notify("Image is too large. Maximum upload size is 1 Mb.","true");
return false;
}
}else{
//the browser doesn't support the html5 api, but we need to upload the image. we'll validate the file size and type serverside.
return return true;
}
return true;
}
HTML(Ink UI Kit), rendered from php view functionfunction profileView($profile)
{
global $loggedInUser,$cfg;
@$pub = security($_GET['pub-view']) or null;
if(!profileExists($profile))
{
jumpTo('/error/?t=418',0); die;
}else{
if($loggedInUser->profile_id == $profile && $pub == null)
{
echo
'
<center>
<h3>'. $loggedInUser->username .'\'s Profile</h3>
</center>
<hr>
<div class="column-group quarter-gutters">
<form action="" name="profile-up" id="profile-up" class="ink-form all-50 small-100 tiny-100">
<center>
<h5>
<div class="ink-dropdown push-left" data-target="#prof-options" id="prof-dropdown" style="display:inline-block;">
<button class="ink-button fa fa-cog"></button>
<ul id="prof-options" class="dropdown-menu hide-all">
<li class="heading">Settings</li>
<li class="separator-above"><a href="#">Privacy</a></li>
<li><a href="#">Change Password</a></li>
<li><a href="#">Channel Settings</a></li>
<li class="separator-above disabled"><a href="#">...</a></li>
</ul>
</div>
<script>
new Dropdown(\'#prof-dropdown\');
</script>
Your Profile Settings
</h5></center>
<fieldset>
<div class="control-group column-group quarter-gutters">
<label for="username" class="all-20 align-right">Username</label>
<div class="control all-80">
<input type="text" id="username" name="username" value="'. $loggedInUser->username .'">
<p class="tip">Subject to Admin approval</p>
</div>
</div>
<div class="control-group column-group quarter-gutters">
<label for="email" class="all-20 align-right">Email</label>
<div class="control all-80">
<input type="text" id="email" name="email" value="'. $loggedInUser->email .'">
<p class="tip">Change Your Email</p>
</div>
</div>
<div class="control-group column-group quarter-gutters">
<label for="caption" class="all-20 align-right">Caption</label>
<div class="control all-80">
<textarea id="caption" name="caption">'. $loggedInUser->caption .'</textarea>
<p class="tip">Change your public profile description</p>
</div>
</div>
<div class="control-group column-group quarter-gutters">
<label for="submit" class="all-20 align-right"> </label>
<div class="control all-80">
'.form_protect($loggedInUser->csrf_token).'
<input type="submit" value="Update" id="submit-form">
</div>
</div>
</fieldset>
</form>
<div class="all-50 small-100 tiny-100">
<center><h5>Your Profile Picture</h5>
<img id="profile-pic" src="/uploads/'. $loggedInUser->avatar .'" alt="" class="all-100 small-100 tiny-100 push-center">
<br/>
<form name="image-up" method="post" action="" enctype="multipart/form-data" id="image-up" class="ink-form all-100 small-100 tiny-100">
<div class="control-group column-group">
<div class="control all-100">
<div class="input-file all-100">
<input type="file" id="image-input" name="image-input" class="all-100" />
'.form_protect($loggedInUser->csrf_token).'
<input type="submit" value="Update" id="submit-file" class="all-25 ink-button" />
</div>
</div>
</div>
</form>
</center>
</div>
</div>
<hr>
';
}else{
$info = getProfile($profile);
$vids = getVideos($profile);
$foto = getPhotos($profile);
//to do: finish public profile view
}
}
}
Profile Field server side code for ajax request(PHP)this function handles the ajax request, validates the request, and if the request is valid it returns a json encoded response.
if(isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
if(isUserLoggedIn() && $loggedInUser !== null && is_object($loggedInUser) !== false) {
#rate limiting#
$minute = 60;
$minute_limit = 100;
$last_ajax_request = $loggedInUser->last_ajax_request;
$last_ajax_diff = time() - $last_ajax_request; # in seconds
$minute_throttle = $loggedInUser->minute_throttle;
if (is_null($minute_limit)) {
$new_minute_throttle = 0;
}else{
$new_minute_throttle = $minute_throttle - $last_ajax_diff;
$new_minute_throttle = $new_minute_throttle < 0 ? 0 : $new_minute_throttle;
$new_minute_throttle += $minute / $minute_limit;
$minute_hits_remaining = floor(($minute - $new_minute_throttle ) * $minute_limit / $minute);
$minute_hits_remaining = $minute_hits_remaining >= 0 ? $minute_hits_remaining : 0;
}
if ($new_minute_throttle > $minute) {
$wait = ceil($new_minute_throttle - $minute);
$response = ['type'=>'error','message'=>'rate limit exceeded wait '.$wait.' seconds.'];
die(json_encode($response));//ajax rate limiting exceeded.
}
$loggedInUser->last_ajax_request = time();
$loggedInUser->minute_throttle = $new_minute_throttle;
#end#
@$do = security($_GET["do"]);
@$csrf = security($_POST["csrf_token"]);
if(isset($csrf))
{
if($loggedInUser->csrf_validate($csrf) === true)
{
if($do == 'profileupdate')
{
$response = updateProfile();
}
elseif($do == 'somethingelse')
{
//for other ajax methods to be added later.
}else{
$response = ['type'=>'error','message'=>'failed'];
}
if(isset($response) && !empty($response))
{
die(json_encode($response));
}else{
http_response_code(500);
die;
}
}else{
http_response_code(404);
die;
}
}else{
http_response_code(404);
die;
}
}else{
http_response_code(401);
die;
}
}else{
http_response_code(405);
die;
}
update profile function from above exampleThis function updates the user's session object($loggedInUser) and updates the database, but only if each field differs from the session object.
function updateProfile()
{
global $loggedInUser;
$response = [];
if($loggedInUser == null || isUserLoggedIn() === false)
{
$response[] = json_encode(['type'=>'error','message'=>'login']);
}else{
if(!empty($_POST))
{
$uid = $loggedInUser->user_id;
$uname = sanitize(trim($_POST["username"]));
$captn = sanitize($_POST["caption"]);//leave spaces in tact for caption.
$ename = sanitize(trim($_POST["email"]));
if(!empty($uname) && ($uname !== $loggedInUser->username))
{
if(!ctype_alnum($uname)){
$response[] = ['type'=>'error','message'=>lang("ACCOUNT_USER_INVALID_CHARACTERS")];
}else{
if(!usernameExists($uname))
{
if(updateUsername($uid,$uname))
{
$loggedInUser->username = $uname;
$response[] = ['type'=>'success','message'=>'username','update'=>security($uname)];
}else{
$response[] = ['type'=>'error','message'=>'an error occured. please try again.'];
}
}else{
$response[] = ['type'=>'error','message'=>'Username is taken. try again.'];
}
}
}
if((!empty($captn)) &&($captn !== $loggedInUser->caption))
{
if(updateCaption($uid,$captn))
{
$loggedInUser->caption = $captn;
$response[] = ['type'=>'success','message'=>'caption','update'=>$captn];
}else{
$response[] = ['type'=>'error','message'=>'an error occured. please try again.'];
}
}
if((!empty($ename)) && ($ename !== $loggedInUser->email))
{
if(!emailExists($ename))
{
if(updateEmail($ename))
{
$loggedInUser->email = $ename;
$response[] = ['type'=>'success','message'=>'email','update'=>security($ename)];
}
}
}
}else{
$response[] = ['type'=>'error','message'=>'empty'];
}
}
return $response;
}
Image upload processing script(PHP)if(isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
if(isUserLoggedIn() === true && $loggedInUser !== null && is_object($loggedInUser) !== false) {
if(isset($_POST) && !empty($_POST))
{
$response = [];
@$csrf = security($_POST['csrf_token']);
if($loggedInUser->csrf_validate($csrf) === true)
{
if($_FILES)
{
$BigImageMaxSize = 300; //Image Maximum height or width
//$maxheight = 200;
$DestinationDirectory = 'uploads/'; //specify upload directory
$Quality = 90; //jpeg quality
if(!isset($_FILES['image-input']) || !is_uploaded_file($_FILES['image-input']['tmp_name']))
{
$response[] = ['type'=>'error','message'=>'empty file upload'];
}else{
$RandomNumber = rand(0, 9999999999);
$rand2 = rand(0, 999);
$ImageName = $RandomNumber .'-'. md5(openssl_random_pseudo_bytes(4)) . '-da-' . $rand2 . time();
$ImageSize = $_FILES['image-input']['size'];
$TempSrc = $_FILES['image-input']['tmp_name'];
$ImageType = $_FILES['image-input']['type'];
$mbyte = 1048576;//1 megabyte
if( (int) $ImageSize > $mbyte)
{
die(json_encode(['type'=>'error','message'=>'F_SIZE_EXCEEDS']));//kill script and return json error response.
}
switch(strtolower($ImageType))
{
case 'image/png':
//Create a new image from file
$CreatedImage = imagecreatefrompng($_FILES['image-input']['tmp_name']);
break;
case 'image/gif':
$CreatedImage = imagecreatefromgif($_FILES['image-input']['tmp_name']);
break;
case 'image/jpeg':
case 'image/pjpeg':
$CreatedImage = imagecreatefromjpeg($_FILES['image-input']['tmp_name']);
break;
default:
$response[] = ['type'=>'error','message'=>'unsupported file type']; //output error and exit
}
list($CurWidth,$CurHeight) = getimagesize($TempSrc);
if($CurWidth == null || $CurHeight == null)
{
die(json_encode(['type'=>'error','string'=>'418']));
}
$ImageExt = substr($_FILES['image-input']['name'], strrpos($_FILES['image-input']['name'], '.'));
$ImageExt = str_replace('.','',$ImageExt);
$NewImageName = $ImageName.'.'.$ImageExt;
$DestRandImageName = $DestinationDirectory.$NewImageName; // Image with destination directory
}
if(resizeImage($CurWidth,$CurHeight,$BigImageMaxSize,$DestRandImageName,$CreatedImage,$Quality,$ImageType))
{
$uid = $loggedInUser->user_id;
if(updateAvatar($uid,$NewImageName))
{
$loggedInUser->avatar = $NewImageName;
$response[] = ['type'=>'success','message'=>'your profile picture was updated','update'=>$NewImageName];
}
}else{
$response[] = ['type'=>'error','message'=>'error resizing image'];
}
if(isset($response) && !empty($response))
{
die(json_encode($response));
}else{
die(json_encode(['type'=>'error','message'=>'script error occured']));
}
}
}else{
http_response_code(403);
}
}else{
http_response_code(401);
}
}else{
http_response_code(403);
}
}else{
http_response_code(405);
}
Thanks for your time