Blepharitis inflammation of eyelid symptoms cause everything included along w...
Drupal Sins: How to Avoid Common Pitfalls
1. Drupal Sins
How I learned to stop thinking and love sites
that bomb.
By: Aaron Crosman
2. The Goal
Allow a blackbox third-party application
authenticate against Drupal and save/retrieve
data using custom REST-inspired interface.
3. The sinful solution
Create a series of bootstrap scripts to handle
all the interactions, turning Drupal into a
glorified database layer (also while you’re at it,
bypass all SQL injection attack protections to
make sure Drupal provides as little value as
possible).
4. Boot Drupal!
If you don’t give me what I want, I’ll pretend I’m not here...
No problem with that...nope
5. If I don’t rename the variables how will I know what they are called.
I better pass my own hash of the authentication around that’s much
more secure than anything someone else might provide...
Yeah, nothing to see here. No problem with just dumping a variable
into SQL...nope. And why would I want to use $obj->uid when I can
save a character and use a variable.
If you can’t login, I’ll just pretend I’m not here, and use my own
magic status code...
6. Again, nothing wrong with a variable or two in the SQL...
I loaded an object, now I’ll just put those into some variables, these
objects are awfully hard to work with...
Here’s a web page with a new query string in it. I hope that’s what you wanted. Too
bad there aren’t better formats for this...
7. Better Solutions:
Use a custom menu to define paths, and have
the application just go there instead.
Use Services module:
https://www.drupal.org/project/services
Hire a call center to ask all your users for their
data.
(dear God just don’t do what was done above.)
8. function hook_menu() {
$items['games/auth'] = array(
'title' => 'Games Authorization',
'page callback' => 'game_module_auth_user',
'access arguments' => array('access content'),
'type' => MENU_CALLBACK,
);
$items['games/game_name/data'] = array( // yes, you could make that a variable instead of hard code
'title' => 'Game Data',
'page callback' => 'game_module_game_name_capture_data', // and if you did you could use one function and pass that variable
'access arguments' => array('player'),
'type' => MENU_CALLBACK,
);
return $items;
}
9. Schema: If I need someplace for my data
'fields' => array(
'recordID' => array(
'description' => 'The primary identifier for a record.',
'type' => 'serial',
...
'uid' => array(
'description' => 'The user ID.',
'type' => 'int',
...
'game' => array(
'description' => 'The game name',
'type' => 'text',
...
'data' => array(
'description' => 'Serialized data from Game application',
'type' => 'blob',
10. function game_module_auth_user($user_name = '', $pass = '') { // Here I am using GET, but I don’t have to
global $user;
if($user->uid != 0) { // They are logged in already, so reject them
drupal_access_denied();
}
$account = user_authenticate($user_name, $pass);
//Generate a response based on result....
}
function game_module_[game_name]_capture_data() {
global $user;
if($user->uid == 0) { // They aren’t logged in, so they can’t save data
drupal_access_denied();
}
$record = drupal_get_query_parameters($query = $_POST); // ← we can work with POST just as well as GET if we ask Drupal
to look in the right place.
db_insert('game_data')
->fields(array(
'uid' => $user->uid, 'game' => '[game_name]', 'data' => serialize($record), ))
->execute();
// Provide useful response.
}