How to Save Multiple User Metadata in Database? - wordpress

I am trying to create a registration form (here) with the help of a free plugin.
There are many elements in the registration form.
In the admin panel, meta keys can be assigned for each element in the plugin interface. So there is such an opportunity.
I'm trying to collect many of the elements on the same meta key by taking advantage of this possibility. In this direction, I gave the common meta key value to the elements I created. For example: info_about_register
So far everything is fine. However, if the form is posted, I can only get the last entry in the usermeta table. So the plugin is not serializing the same meta key data. An array does not occur.
There are many form elements. I want to pull these to the admin panel later. Therefore, I think that defining a separate line for each element will tire the system a lot. I contacted the plugin developers about this issue. However, no response for about 1.5 weeks.
I tried to solve this problem myself and found the codes where the action was taken. I made some changes to these. However, I was not successful. I would be very happy if you guide me.
.../includes/class-frontend.php
/*
* Called after submission save
* Registers new user into WordPress.
* Also map field values to user meta (If configured)
*/
public function after_submission_insertion($errors, $submission, $data) {
$sub_model = erforms()->submission;
$form_model = erforms()->form;
$form = $form_model->get_form($submission['form_id']);
// Copy attachment values in data from submission (as $data does not have any uploaded file values)
if(!empty($submission['attachments'])){
foreach($submission['attachments'] as $attachment){
if(!isset($data[$attachment['f_name']])){
$data[$attachment['f_name']]= $attachment['f_val'];
}
}
}
if ($form['type'] == "reg") { // Handling of registration forms
$user = 0;
$id = 0;
// Get mapping for user meta fields if any
$user_field_map = erforms_filter_user_fields($form['id'], $submission['fields_data']);
// Avoid user registration process if user already logged in
if (!is_user_logged_in()) {
$email_or_username = $user_field_map['user_email'];
if (isset($user_field_map['password'])) {
// Silently creates user
$username = isset($user_field_map['username']) ? $data[$user_field_map['username']] : $data[$email_or_username];
do_action('erf_before_user_creation',$submission);
$id = wp_create_user($username, $data[$user_field_map['password']], $data[$email_or_username]);
} else {
// Register user and sends random password via email notification
do_action('erf_before_user_creation',$submission);
$id = register_new_user($data[$email_or_username], $data[$email_or_username]);
}
if (is_wp_error($id)) {
// In case something goes wrong delete the submission
wp_delete_post($submission['id'], true);
$error_code = $id->get_error_code();
if ($error_code == 'existing_user_login') {
$email_or_username = 'username_error';
}
$errors[] = array($email_or_username, $id->get_error_message($id->get_error_code()));
return $errors;
} else {
$selected_role = erforms_get_selected_role($submission['form_id'], $data);
if (!empty($selected_role)) { // Means user has selected any role
$user_model = erforms()->user;
$selected_role= apply_filters('erf_before_setting_user_role',$selected_role,$id,$form, $submission);
$user_model->set_user_role($id, $selected_role);
}
foreach ($user_field_map as $req_key => $meta_key) {
$is_primary_key = in_array($meta_key, erforms_primary_field_types());
if (isset($data[$req_key]) && !$is_primary_key) {
$m_keys= explode(',',$meta_key);
foreach($m_keys as $m_key){
if(!empty($m_key)){
$status = erforms_update_user_meta($id, $m_key, $data[$req_key]);
do_action('erf_user_meta_updated',$m_key,$id,$data[$req_key],$status);
}
}
}
}
do_action('erf_user_created', $id, $form['id'], $submission['id']);
}
} else {
// Get user details
$user = wp_get_current_user();
$id = $user->ID;
foreach ($user_field_map as $req_key => $meta_key) {
$is_primary_key = in_array($meta_key, erforms_primary_field_types());
if (isset($data[$req_key]) && !$is_primary_key) {
$m_keys= explode(',',$meta_key);
foreach($m_keys as $m_key){
if(!empty($m_key)){
$status= erforms_update_user_meta($id,$m_key,$data[$req_key]);
do_action('erf_user_meta_updated',$m_key,$id,$data[$req_key],$status);
}
}
}
}
//...
// User meta,URL params or default values should be prefilled only when we are not loading submission data
if(empty($submission)){
$user_meta = erforms()->user->frontend_localize_user_meta($form);
$filtered_url_params = array();
foreach ($_GET as $key => $val) {
$filtered_url_params[urldecode(strtolower(wp_unslash($key)))] = sanitize_text_field(wp_unslash($val));
}
$url_keys = array_keys($filtered_url_params);
foreach ($form['fields'] as $field) {
$label = !empty($field['label']) ? strtolower(str_replace(' ', '_', $field['label'])) : '';
$label = str_replace('&', 'and', $label); // Cause URL params do not allow &
if (!empty($field['name']) && !empty($label) && in_array($label, $url_keys)) {
if (!isset($user_meta[$field['name']]) && !empty($filtered_url_params[$label])) {
$user_meta[$field['name']] = stristr($filtered_url_params[$label], '|') ? explode('|', $filtered_url_params[$label]) : $filtered_url_params[$label];
}
}
if(!empty($field['name']) && empty($user_meta[$field['name']]) && !empty($field['value'])){
$user_meta[$field['name']] = $field['value'];
}
}
if (!empty($user_meta)) {
$data['user_meta'] = $user_meta;
}
}
$data= apply_filters('erf_form_localize_data',$data,$form);
return $data;
}
.../includes/functions.php
/**
* Wrapper to call update_user_meta function.
* This simply calls wordpress meta function and does not add any special prefix.
* Checks for any special meta key to update user table data.
* For example: display_name : updates user's display name. Instead of adding display_name usermeta
*/
function erforms_update_user_meta($user_id, $m_key, $m_val) {
switch ($m_key) {
case 'display_name' : $status = wp_update_user(array('ID' => $user_id, $m_key => $m_val));
return is_wp_error($status) ? false : true;
}
return update_user_meta($user_id, $m_key, $m_val);
}

Update:
Data can be stored as an array with a definition like below. Also, the key values ($all_meta_value[$req_key]) are equal to the id, name values automatically assigned to the HTML elements by the plugin.
Using this, different conditional states can be written.
The following code must be defined in the function.php file in the child theme:
add_action('erf_user_meta_updated','for_new_user_meta_uptated',10);
function for_new_user_meta_uptated($data){
//if the defined meta key (info_about_register) matches
if($m_key == 'info_about_register'){
$all_meta_value[$req_key] = $data;
}
}
add_action('erf_user_created', 'for_new_user_created',10);
function for_new_user_created($id){
//Save the values as a new user meta
add_user_meta($id, 'new_info_about_register', $get_meta_value);
//Remove saved single element user meta.
delete_user_meta($id, 'info_about_register');
}

Related

How to pre-select a selct box in Ninja Forms from a query string

I am trying to pre select a value within a select field in my contact from on the contact page from another page by passing a query string ?request=call-back. I am using Ninja Forms and the values that I have in my select field are: email-us, call-back
I have tried the following:
add_filter( 'ninja_forms_render_default_value', 'my_ninja_forms_pre_populate', 10, 3 );
function my_ninja_forms_pre_populate( $default_value, $field_type, $field_settings ){
if( 'request' == $field_settings[ 'key' ] ){
$default_value = $_GET['request'];
}
return $default_value;
}
I would like the select field to have call-back already selected.
I didnt need to use the filter that I was attempting. I changed the key value under administration within the ninja form builder and I made sure that none of the values were pre selected.
This drove me mad... but finally I've got a solution:
// register custom get parameter (to use it with get_query_var() for safety reasons)
function add_get_val() {
global $wp;
$wp->add_query_var('request');
}
add_action('init', 'add_get_val');
add_filter('ninja_forms_localize_field_listselect', function ($field) {
if (get_query_var('request')) {
$request = get_query_var('request');
$optionExists = FALSE;
// check if field exists
foreach ($field['settings']['options'] as $option) {
if ($option['value'] === $request) {
$optionExists = TRUE;
break;
}
}
if ($optionExists) {
foreach ($field['settings']['options'] as $key => $option) {
// deselect all fields
$field['settings']['options'][$key]['selected'] = 0;
// select parameter
if ($option['value'] === $request) {
$field['settings']['options'][$key]['selected'] = 1;
}
}
}
}
return $field;
});

Silverstripe 3.2: How to make a custom action button in the CMS to create a new Dataobject and populate it from another one

I'm searching for a way to create a custom action button which allows me to make a new DataObject with pre-filled content from another DataObject. As a simple example: When I have an email and click the "answer"-button in my email-client, I get a new window with pre-filled content from the email before. I need exactly this functionality for my button. This button should appear next to each DataObject in the GridField.
So I know how to make a button and add it to my GridField (--> https://docs.silverstripe.org/en/3.2/developer_guides/forms/how_tos/create_a_gridfield_actionprovider/) and I know how to go to a new DataObject:
Controller::curr()->redirect($gridField->Link('item/new'));
I also found out that there is a duplicate function for DataObjects:
public function duplicate($doWrite = true) {
$className = $this->class;
$clone = new $className( $this->toMap(), false, $this->model );
$clone->ID = 0;
$clone->invokeWithExtensions('onBeforeDuplicate', $this, $doWrite);
if($doWrite) {
$clone->write();
$this->duplicateManyManyRelations($this, $clone);
}
$clone->invokeWithExtensions('onAfterDuplicate', $this, $doWrite);
return $clone;
}
Perhaps it's easier than I think but at the moment I just don't get how to rewrite this to get what I need. Can somebody give me a hint?
That's for sure not the cleanest solution but I think it should do the trick.
At first let's create the custom gridfield action. Here we will save all accessible records in a session and add a query string to the url so that we'll know which object we want to "clone"
public function getColumnContent($gridField, $record, $columnName) {
if(!$record->canEdit()) return;
$field = GridField_FormAction::create(
$gridField,
'clone'.$record->ID,
'Clone',
'clone',
array('RecordID' => $record->ID)
);
$values = Session::get('ClonedData');
$data = $record->data()->toMap();
if($arr = $values) {
$arr[$record->ID] = $data;
} else {
$arr = array(
$record->ID => $data
);
}
Session::set('ClonedData', $arr);
return $field->Field();
}
public function getActions($gridField) {
return array('clone');
}
public function handleAction(GridField $gridField, $actionName, $arguments, $data) {
if($actionName == 'clone') {
$id = $arguments['RecordID'];
Controller::curr()->redirect($gridField->Link("item/new/?cloneID=$id"));
}
}
after adding this new component to our gridfield,
$gridField->getConfig()->addComponent(new GridFieldCustomAction());
we'll need to bring the data into the new form. To do so, add this code directly above "return $fields" on your getCMSFields function so it will be executed every time we'll open this kind of object.
$values = Session::get('ClonedData');
if($values) {
Session::clear('ClonedData');
$json = json_encode($values);
$fields->push(LiteralField::create('ClonedData', "<div id='cloned-data' style='display:none;'>$json</div>"));
}
At the end we need to bring the content back into the fields. We'll do that with a little bit of javascript so at first you need to create a new script.js file and include it in the ss backend (or just use an existing one).
(function($) {
$('#cloned-data').entwine({
onmatch: function() {
var data = JSON.parse($(this).text()),
id = getParameterByName('cloneID');
if(id && data) {
var obj = data[id];
if(obj) {
$.each(obj, function(i, val) {
$('[name=' + i + ']').val(val);
});
}
}
}
});
// http://stackoverflow.com/questions/901115/how-can-i-get-query-string-values-in-javascript#answer-901144
function getParameterByName(name) {
name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
results = regex.exec(location.search);
return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
}
})(jQuery);
And that's it ... quite tricky. Hope it will solve your problem.

swiftmail symfony duplicate check for error log / email before sending

I would like to run a duplicate content check just before firing off an email whcih uses swiftmailer inside my symph2 app to send me dev ERROR log entries.
this functionality sits right next to my error log to database function, where it too has a duplicate check, although that one is much easier, it uses sql.
for this one, i want to maintain the last mail sent body for atleast the next 10 emails sent, so that if my error log goes out of control, it wont keep firing me duplicate emails of the same error.
should i just collect this body onto an object that holds last 10 email bodies, and attach this to the swift mailer class? or is there an easier way, like using something that is already embedded in swift mailer for this kind of post sending use? Or maybe a session..
Edit, i call swift mailer from a backend helper class, so think i can pretty much do anything there so long as its atleast semi-elegant.
EDIT this is a refined version of the method that calls both the persist and firing of email
<?php
class someWierdClass
{
public function addLogAction(Request $request, $persist = TRUE, $addEmail = TRUE)
{
$responseAdd = array();
if ($this->getRequest()->request->all() !== null) {
$data = $this->getRequest()->request->get('data') ? $this->getRequest()->request->get('data') : 'no_data';
$duplicate = $this->getRequest()->request->get('duplicate', null);
}
if ($addEmail) {
$responseAdd[] = 'firedIt';
$this->fireEmailString('You have an error log here. <br>' . $data);
}
if ($persist)
{
$responseAdd[] = 'persistedIt';
$this->persistLog($data, $duplicate);
}
if ($responseAdd)
{
$body = implode(', ', $responseAdd);
return new Response($body);
}
}
}
Log emails in a table and check that there it isn't a duplicate every time you send an email.
To do this, you should create a helper function that queries the emails table for entries who's body matches the body you would like to send. If the query returns nothing, then you know that isn't a duplicate. You would then send the email and log it the database. Otherwise, if it returned (a) record(s), you would send a dev ERROR log entry.
If you would like to only check against the last 10 emails, you would do this by querying for both $body == $new_body and $id >= ($total_rows-10)
You would then inject this into the container and call it using something like this
$this->container->get('helper')->sendEmail($body, $subject, $recipients);
Ok, thanks Dan for the idea as to using the database to do the dup check. If you notice, per your suggestion, i was already doing the dup check, but it made me think. It helped me connect the dots.
What i have done is return the answer if its a duplicate on the response when it does the updating the database, then using that response as a flag to determine if email fires or not. (in my case, i go further to check the updated stamp is at least +1 hour old, as opposed to the 'last 10 emails content' idea)
Heres the code.. Enjoy..
<?php
namespace Acme\AcmeBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller,
Acme\AcmeBundle\Entity\Log,
Symfony\Component\HttpFoundation\JsonResponse,
Symfony\Component\HttpFoundation\Response,
Symfony\Component\Config\Definition\Exception\Exception,
Symfony\Component\HttpFoundation\Request,
Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
class someWierdClass
{
/**
* #var array
*/
protected $senderArray = array('no-reply#yorudomain.com' => 'Your Website Name');
/**
* #param Request $request
* #param bool $persist
* #param bool $addEmail
* #return Response
*/
public function addLogAction(Request $request, $persist = TRUE, $addEmail = TRUE)
{
$responseAdd = array();
if ($this->getRequest()->request->all() !== null) {
$data = $this->getRequest()->request->get('data') ? $this->getRequest()->request->get('data') : 'no_data';
$type = $this->getRequest()->request->get('type') ? $this->getRequest()->request->get('type') : 'no_type';
$duplicate = $this->getRequest()->request->get('duplicate', null);
}
if ($addEmail) {
$responseAdd[] = 'firedIt';
$this->fireEmailString('You have an error log here. <br>' . $data);
}
if ($persist) {
$responseAdd[] = 'persistedIt';
$persistResponse = $this->persistLog( $type = $data, $duplicate);
if ($persistResponse) {
// a dup check is done here and results of this is on the response. (e.g. $content->passesCutoff)
$content = json_decode($persistResponse->getContent());
}
}
if ( $addEmail && ( isset($content->passesCutoff) && $content->passesCutoff ))
{
//fire off an email also, because its kind of hard to look in teh logs all the time, sometimes we just want an email.
$successEmail = $this->fireEmailString($data);
if( ! $successEmail )
{
$responseAdd[] = 'firedIt';
}
}
if ($responseAdd) {
$body = implode(', ', $responseAdd);
return new Response($body);
}
}
/**
* #param $emailStringData
* #param null $emailSubject
* #param null $emailTo
* #return mixed
*/
protected function fireEmailString($emailStringData, $emailSubject = null, $emailTo=null){
$templateName = 'AcmeBundle:Default:fireEmailString.html.twig';
if( ! $emailSubject )
{
$emailSubject = 'An email is being fired to you!' ;
}
if( ! $emailTo )
{
$emailTo = 'youremail#gmail.com';
}
$renderedView = $this->renderView(
$templateName, array(
'body' => $emailStringData,
));
$mailer = $this->get('mailer');
$message = $mailer->createMessage()
->setSubject( $emailSubject)
->setBody($emailStringData, 'text/plain')
->addPart($renderedView, 'text/html')
->setFrom($this->senderArray)
->setSender($this->senderArray)
->setTo($emailTo);
$results = $mailer->send($message);
return $results;
}
/**
* #param $type
* #param $data
* #param $duplicate
* #return JsonResponse
*/
protected function persistLog($type, $data, $duplicate) {
$em = $this->getDoctrine()->getManager();
$count = null;
$passesCutoff = null;
$mysqlNow = new \DateTime(date('Y-m-d G:i:s'));
//only two conditions can satisy here, strings '1' and 'true'.
if($duplicate !== '1' && $duplicate !== 'true' /*&& $duplicate != TRUE*/)
{
//in order to check if its unique we need to get the repo
//returns an object (findByData() would return an array)
$existingLog = $em->getRepository('AcmeBundle:Log')->findOneByData(
array('type' => $type, 'data' => $data)
);
if($existingLog)
{
$timeUpdatedString = strtotime($existingLog->getTimeupdated()->format('Y-m-d H:i:s'));
$cutoffStamp = strtotime('+1 hour', $timeUpdatedString); //advance 1 hour (customize this to the amount of time you want to go by before you consider this a duplicate. i think 1 hour is good)
$passesCutoff = time() >= $cutoffStamp ? TRUE : FALSE; //1 hour later
$count = $existingLog->getUpdatedcount();
$existingLog->setUpdatedcount($count + 1); // '2014-10-11 03:52:20' // date('Y-m-d G:i:s')
$em->persist($existingLog);
}
else
{
//this record isnt found, must be unique
$newLog = new Log(); //load our entity
//set in new values
$newLog->setType($type);
$newLog->setData($data);
$newLog->setUpdatedcount(0);
$newLog->setTimeupdated($mysqlNow);
$em->persist($newLog);
}
}
else
{
//we dont care if unique or not, we just want a new row
$newLog = new Log(); //load our entity
$newLog->setType($type);
$newLog->setData($data);
//time updated has been set to auto update to current timestamp in the schema, test first, then remove this
$newLog->setUpdatedcount(0);
$newLog->setTimeupdated($mysqlNow);
$em->persist($newLog);
}
$em->flush();
$response = new JsonResponse();
$response->setData(
array(
'data' => 'persistedIt',
'existingLog' => $count,
'passesCutoff' => $passesCutoff,
));
return $response;
}
}
In hindsight, i would have just passed the last update timestamp back on the response from the persist method, then do the cutoff calculation inside the fire email method obviously, but the above code does work as a starting point.. :-)

Return entity record value based on custom value in Symfony2

I'm making an API and I need to display data from entity based on action type. For example, I have User and his visibility preferences (to hide/show his name for other people). Doing this like that:
<?php
// entity
public function getSurname()
{
$visibility = $this->getVisibility();
if($visibility['name'] == 0)
return $this->surname;
return '';
}
is ok, but if User is logged in, I want to show him his name, for example, in edit account.
The best way I think is to edit record when I get it from database, but how to this on doctrine object?
<?php
//controller
$user = $this->getDoctrine()->getRepository('AcmeDemoBundle:User')->findOneById($id);
$user = $this->getVisibility();
if($user != $this->getUser() && $visibility['name'] == 0)
$user->setSurname(''); //but this save this to DB, not to "view"
UPDATE
Unfortunately (or I'm doing something wrong) my problem can't be solved by Snake answer, beause when I do this code:
<?php
$user = $this->getDoctrine()->getRepository('AcmeDemoBundle')-findOneById($id);
return array(
self::USER => $user
);
In my API response, entity modifications don't work, because I think this is getting record directly from DB? And I need return whole object like in code above.
UPDATE2
I found workaround for this
<?php
// entity
/**
* #ORM\PostLoad
*/
public function postLoad() {
$this->surname = $this->getSurname();
}
and then I can just return full $user object
If you want to show the surname depends of visibility, you can add the Symfony\Component\Security\Core\User\EquatableInterface and edit your function:
// entity
public function getSurname(Acme\DemoBundle\User $user = null)
{
// Nothing to compare or is the owner
if( !is_null( $user ) && $this->isEqualTo($user) ){
return $this->surname;
}
// else...
$visibility = $this->getVisibility();
if($visibility['name'] == 0)
return $this->surname;
return '';
}
After in your controller you only must get the surname:
//controller
$user = $this->getDoctrine()->getRepository('AcmeDemoBundle:User')->findOneById($id);
// If the user is the owner, show the surname, otherwise it shows the surname depends of visibility
$surname = $user->getSurname( $this->getUser() );
Also, you can execute the logic in the controller (check if is the same user and get the visibility...).
I suggest you read about ACL too.

Drupal 7 with Multiple Login sources?

I'm just a new to Drupal but i wanna make my site to be authenticated from external login sources. I mean, not to use the current Drupal database to login. Then use one or more external databases.
To make it a little more clear:
User Login Authentication will not use the existing Drupal database.
Then it will use the external database(s)
External Database will be one or more (If User is not found on one external database, then found on another source again.)
I've been trying to hack the Drupal Login but i can't make it yet as the structure is complicated enough. Any solution or suggestion please?
Which files will be needed to modify?
You shouldn't completely discard Drupal's user system for this, but rather piggy tail on it with your own authentication. The way this works is by 1) collecting user credentials, 2) authenticating against your custom sources and 3) registering/logging in an external user.
Collecting credentials
One way of collecting user credentials is by hijacking the user login form. You do this by implementing hook_form_alter() and add your own validation callback.
function mymodule_form_alter(&$form, &$form_state, $form_id) {
if ($form_id == 'user_login') {
$form['#validate'][] = array('mymodule_user_login_validate');
$form['#validate'][] = array('mymodule_user_login_submit');
}
}
The login form will look exactly the same and but it will send the username and password to your callback instead.
The user_login_name_validate() and user_login_final_validate() callbacks are user.module's default validators. They supply user blocking functionality and brute force protection but feel free to leave them out.
Authentication
When the login form is sent you pick up the credentials and authenticate against your custom sources.
function mymodule_user_login_validate($form, &$form_state) {
mymodule_authenticate(
$form_state['values']['name'],
$form_state['values']['name']
);
}
If the credentials doesn't check out you can just call form_set_error() to inform the user of what went wrong. Doing this will also make sure no further validation or submit callbacks are executed.
External users
So if no error is evoked then Drupal will move on to running your submit callback. Then we can run user_external_login_register() to create our external user as a Drupal user.
function mymodule_user_login_submit($form, &$form_state) {
user_external_login_register($form_state['values']['name'], 'mymodule');
}
As the name implies, this function will also log the user in. And that should be it!
There's a module for that
Chances are there is already a module for what you want to do. Always go search for existing contrib modules before starting your own!
define('DRUPAL_ROOT', 'full/path/to/drupal');
$drupal_url = 'http://site.com';
drupal_external_load($drupal_path, $drupal_url);
if ( !($user->uid > 0) ) {
drupal_external_login('user', 'pass');
} else {
print 'user is already logged';
}
function drupal_external_load($drupal_url) {
global $base_url;
// set drupal base_url (if not set set in settings.php)
// because it's used in session name
$base_url = $drupal_url;
// save current path
$current_path = getcwd();
// move to drupal path, because it uses relative path for its includes
chdir(DRUPAL_ROOT);
require_once DRUPAL_ROOT . '/includes/bootstrap.inc';
drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
// to use the drupal global user var (instead of session hack)
// drupal_bootstrap(DRUPAL_BOOTSTRAP_SESSION);
// return the current path
chdir($current_path);
}
// load a drupal user into the user obj
function drupal_external_userload($user_info = array()) {
// Dynamically compose a SQL query:
$query = array();
$params = array();
if (is_numeric($user_info)) {
$user_info = array('uid' => $user_info);
}
elseif (!is_array($user_info)) {
return FALSE;
}
foreach ($user_info as $key => $value) {
if ($key == 'uid' || $key == 'status') {
$query[] = "$key = %d";
$params[] = $value;
}
else if ($key == 'pass') {
$query[] = "pass = '%s'";
$params[] = md5($value);
}
else {
$query[]= "LOWER($key) = LOWER('%s')";
$params[] = $value;
}
}
$result = db_query('SELECT * FROM {users} u WHERE '. implode(' AND ', $query), $params);
if ($user = db_fetch_object($result)) {
$user = drupal_unpack($user);
$user->roles = array();
if ($user->uid) {
$user->roles[DRUPAL_AUTHENTICATED_RID] = 'authenticated user';
}
else {
$user->roles[DRUPAL_ANONYMOUS_RID] = 'anonymous user';
}
$result = db_query('SELECT r.rid, r.name FROM {role} r INNER JOIN {users_roles} ur ON
ur.rid = r.rid WHERE ur.uid = %d', $user->uid);
while ($role = db_fetch_object($result)) {
$user->roles[$role->rid] = $role->name;
}
//user_module_invoke('load', $user_info, $user);
}
else {
$user = FALSE;
}
return $user;
}
// don't send any headers before calling this
function drupal_external_login($username, $password) {
global $user;
if ( $user->uid > 0 ) {
if ( $user->name != $username ) {
drupal_external_logout();
} else {
return true;
}
}
require DRUPAL_ROOT. '/includes/password.inc' ;
$account = user_load_by_name($username);
if ( user_check_password($password, $account) ) {
$user = $account;
drupal_session_regenerate();
return true;
}
return false;
}
function drupal_external_logout() {
global $user;
session_destroy();
$user = drupal_anonymous_user();
}

Resources