Skip to content

Instantly share code, notes, and snippets.

@cblanquera
Created December 4, 2015 12:21
Show Gist options
  • Select an option

  • Save cblanquera/348b9dbef5398bd11776 to your computer and use it in GitHub Desktop.

Select an option

Save cblanquera/348b9dbef5398bd11776 to your computer and use it in GitHub Desktop.
A comparison of Node and PHP
module.exports = function(job, done) {
//need to have
// item - product item
// app_id
// profile_id
// profile_type
var data = job.data;
var item = data.item;
var results = { images: [] };
this.sync()
//create product
.then(function(next) {
this.model('product').create().process(item, next);
})
//link app
.then(function(error, model, next) {
if(error) {
return done(error);
}
results.product = model.get();
//link profile with product
this.model('product').linkApp({
app_id : data.app_id,
product_id : results.product.product_id
}, next);
})
//profile choice
.then(function(error, row, next) {
if(error) {
return done(error);
}
//if guest_phone and/or guest_name
//the intentions was to create a guest profile
//this should only happen if this is an app doing this
if(data.app_id
&& (item.guest_phone && item.guest_phone.toString().length
|| item.guest_email && item.guest_email.length)) {
return next.thread('guest-find');
}
next();
})
//find guest
.thread('guest-find', function(next) {
//1. Look for an existing guest profile
// where the name or the email matches
var search = this.model('profile')
.list()
.process()
.filterByProfileType('guest');
if(item.guest_phone && item.guest_phone.toString().length
&& item.guest_email && item.guest_email.length) {
search.addFilter(
'(profile_email = ? OR profile_phone = ?)',
item.guest_email,
item.guest_phone);
} else if(item.guest_phone && item.guest_phone.toString().length) {
search.filterByProfilePhone(item.guest_phone);
} else {
search.filterByProfileEmail(item.guest_email);
}
search.getRow(next.thread.bind(this, 'guest-create'));
})
//create profile
.thread('guest-create', function(error, row, meta, next) {
if(error) {
return done(error);
}
//2a. if it exists, just use that
if(row) {
data.profile_id = row.profile_id;
data.profile_type = 'guest';
return next();
}
//2b. if not, then create one and use that
var profile = {
profile_name: 'Guest-' + Date.now(),
profile_type: 'guest'
};
if(item.guest_phone && item.guest_phone.toString().length) {
profile.profile_phone = item.guest_phone.toString();
}
if(item.guest_email && item.guest_email.length){
profile.profile_email = item.guest_email;
}
var callback = next.thread.bind(this, 'guest-image-create');
//create profile
this.model('profile')
.create()
.process(profile, callback);
})
//create image
.thread('guest-image-create', function(error, model, next) {
if(error) {
return done(error);
}
results.profile = model.get();
data.profile_id = model.profile_id;
data.profile_type = 'guest';
var config = this.config('s3');
var file = config.host + '/'
+ config.bucket + '/avatar/avatar-'
+ ((Math.floor(Math.random() * 1000) % 11) + 1) + '.png';
var callback = next.thread.bind(this, 'guest-image-link');
this.model('file').create().process({ file_link: file }, callback);
})
//link image
.thread('guest-image-link', function(error, model, next) {
if(error) {
return done(error);
}
results.profile.profie_image = model.get();
this.model('profile').linkFile({
file_id : model.file_id,
profile_id : data.profile_id
}, next.thread.bind(this, 'guest-done'));
})
//go to next then
.thread('guest-done', function(error, row, next) {
if(error) {
return done(error);
}
next();
})
//link profile
.then(function(next) {
//The user is the developer identified by the app token
this.model('product').linkProfile({
profile_id: data.profile_id,
product_id: results.product.product_id
}, next);
})
//upgrade
.then(function(error, row, next) {
if(error) {
return done(error);
}
//if they are a seller
if(['merchant', 'seller'].indexOf(data.profile_type) !== -1) {
return next(null, {});
}
//profile is now a seller
this.model('profile').update().process({
profile_id : data.profile_id,
profile_type : 'seller'
}, next);
})
//enter file loop
.then(function(error, model, next) {
if(error) {
return done(error);
}
//if no images, return
if(!item.images || !item.images.length) {
return next();
}
next.thread('file-loop', 0);
})
//add the image one at a time
.thread('file-loop', function(i, next) {
if(i < item.images.length) {
var file = item.images[i];
file.file_type = 'product_image';
if(i === 0) {
file.file_type = 'main_product';
}
//1. Validate
file.imageOnly = true;
var errors = this.model('file')
.create()
.errors(file);
if(Object.keys(errors).length) {
return next.thread('file-loop', i + 1);
}
// 2. Process
callback = next.thread.bind(this, 'file-link', i);
this.model('file')
.create()
.process(file, callback);
return;
}
next();
})
//link
.thread('file-link', function(i, error, model, next) {
if(error) {
//yes, ignore errors
return next.thread('file-loop', i + 1);
}
results.images.push(model.get());
this.model('product').linkFile({
file_id : model.file_id,
product_id : results.product.product_id
}, next.thread.bind(this, 'file-iterate', i));
})
//iterate
.thread('file-iterate', function(i, error, row, next) {
//yes ignore errors
next.thread('file-loop', i + 1);
})
//end
.then(function( next) {
done(null, results);
});
};
<?php //-->
/**
* A Custom Project
*
* Copyright and license information can be found at LICENSE
* distributed with this package.
*/
namespace Eve\Job\Product;
use Eve\Framework\Job\Base;
use Eve\Framework\Job\Exception;
/**
* Product Job Create
*
* GUIDE:
* -- eve() - The current server controller
* use this to access the rest of the framework
*
* -- eve()->database() - Returns the current database
*
* -- eve()->model('noun') - Returns the given model factory
*
* -- eve()->job('noun-action') - Returns a job following noun/action
*
* -- eve()->settings('foo') - Returns a settings data originating
* from the settings path. ie. settings/foo.php
*
* -- eve()->registry() - Returns Eden\Registry\Index used globally
*
* -- $this->data - Provides all raw data
* originally passed into the job
*
* @vendor Custom
* @package Project
* @author My Name <my@email.com>
* @standard PSR-2
*/
class Create extends Base
{
/**
* @const string FAIL_406 Error template
*/
const FAIL_406 = 'Invalid Data';
/**
* Executes the job
*
* @return void
*/
public function run()
{
//if no data
if (empty($this->data)) {
//there should be a global catch somewhere
throw new Exception(self::FAIL_406);
}
//this will be returned at the end
$results = array();
//NEXT ...
//if there is no product_id provided
if (!isset($this->data['product_id'])) {
//create the product
$results['product'] = eve()
->model('product')
->create()
->process($this->data)
->get();
$this->data['product_id'] = $results['product']['product_id'];
}
//NEXT ...
//if there is a profile_name provided
if(isset($this->data['profile_name'])
&& !isset($this->data['profile_id'])
) {
//check if the email and/or phone exists
//this logic is so we don't create dupe guests
//imagine millions of product posts by one guest
$email = $phone = '';
if(isset($this->data['profile_email'])) {
$email = $this->data['profile_email'];
}
if(isset($this->data['profile_phone'])) {
$phone = $this->data['profile_phone'];
}
$profile = eve()
->database()
->search('profile')
->addFilter('(profile_email = %s AND profile_phone = %s)
OR (profile_email = %s AND profile_phone IS NULL)
OR (profile_email IS NULL AND profile_phone = %s)',
$email, $phone, $email, $phone)
->filterByProfileType('guest')
->getRow();
if($profile) {
$results['profile'] = $profile;
} else {
//create the profile
$results['profile'] = eve()
->model('profile')
->create()
->process($this->data)
->get();
}
$this->data['profile_id'] = $results['profile']['profile_id'];
}
//NEXT ...
//if there is a profile_id
if (isset($this->data['profile_id'])) {
//link the profile
eve()
->model('product')
->linkProfile(
$results['product']['product_id'],
$this->data['profile_id']
);
}
//NEXT ...
//if there is a list of file
if (isset($this->data['file'])
&& is_array($this->data['file'])
) {
foreach($this->data['file'] as $i => $row) {
//if no file_id
if(!isset($row['file_id'])) {
$row['file_type'] = 'product_image';
if($i === 0) {
$row['file_type'] = 'main_product';
}
//create the file
$row = eve()
->model('file')
->create()
->process($row)
->get();
}
//now link the files
eve()
->model('product')
->linkFile(
$results['product']['product_id'],
$row['file_id']
);
//build thumb
eve()
->job('random-resize')
->setData($row)
->run();
}
}
//NEXT ...
//if there is a app_id
if (isset($this->data['app_id'])) {
//link the app
eve()
->model('product')
->linkApp(
$results['product']['product_id'],
$this->data['app_id']
);
}
return $results;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment