hook_user(): inserting extra field into database not just form - drupal-6

I can add an extra field to the registration. What I need to know is what step do I need to take to then grab that input and insert it into the user table of drupal. The code below is in my module this adds just a field to the form, but when its submitted it doesnt do anything with the data.
function perscriptions_user($op, &$edit, &$account, $category = NULL){
if ($op == 'register') {
$form['surgery_address'] = array (
'#type' => 'textarea',
'#title' => t('Surgery Address'),
'#required' => TRUE,
);
return $form;
}
if ($op == 'update') {
// …
}
}

As reported in hook_user() documentation:
$op What kind of action is being performed. Possible values (in alphabetical order):
- "insert": The user account is being added. The module should save its custom additions to the user object into the database and set the saved fields to NULL in $edit.
- "update": The user account is being changed. The module should save its custom additions to the user object into the database and set the saved fields to NULL in $edit.
- "validate": The user account is about to be modified. The module should validate its custom additions to the user object, registering errors as necessary.
The module needs to create its own database table in hook_install().
hook_user() could be implemented with the following code, for example:
function perscriptions_user($op, &$edit, &$account, $category = NULL){
if ($op == 'register' || ($op == 'form' && $category = 'account')) {
$form['surgery_address'] = array (
'#type' => 'textarea',
'#title' => t('Surgery Address'),
'#required' => TRUE,
);
return $form;
}
if ($op == 'insert' || $op == 'update') {
prescriptions_save_user_profile($account->uid, $edit['surgery_address']);
}
if ($op == 'validate' && $category == 'account') {
// Verify the entered values are valid.
// In this example, the value is contained in $edit['surgery_address'].
}
}
prescriptions_save_user_profile() is the function that saves the user profile values in the database. The code checks the category to avoid to show the same form fields in all the tabs shown in the user profile edit form.

Related

How to pass values for multi select custom fields using RESTlet in Netsuite?

I can pass values for select, text box and etc but not for multi select. I can update values for multi select. But i can't create a record by passing values for multi select.
This is the code :
$datastring = array(
"gu_action"=> "create",
"recordtype"=>"vendor",
"companyname"=>"Jerald Vend",
'subsidiary'=>1,
'custentity36'=>1
);
custentity36 is multiselect control. It's label is Course
when i pass single value , It works fine.
when i try to pass multiple values for multi select like the below code , i am getting error like "Please enter value(s) for: Course"
$datastring = array(
"gu_action"=> "create",
"recordtype"=>"vendor",
"companyname"=>"Jerald Vend",
'subsidiary'=>1,
'custentity36'=>array(1,3)
);
The Code is : https://gist.githubusercontent.com/ganeshprabhus/a3ebd67712913df3de29/raw/3a6df6a3af8642fceacb3a4b8e519ad96a054e69/ns_script.js
The value you pass is in correct format. In this case the RESTlet code should have the compatibility of handling the multiselect filed. The field set value api that used in the RESTlet should be
nlapiSetFieldValues()
This is the api can be used to set multiselect field value. As per the github refernce you shared. under the create_record function
/********************** Creation *********************************/
function create_record(datain) {
var err = new Object();
// Validate if mandatory record type is set in the request
if (!datain.recordtype) {
err.status = "Failed";
err.message = "Missing recordtype";
return err;
}
var record = nlapiCreateRecord(datain.recordtype);
for ( var fieldname in datain) {
if (datain.hasOwnProperty(fieldname)) {
if (fieldname != 'recordtype' && fieldname != 'id') {
var value = datain[fieldname];
// ignore other type of parameters
if (value && typeof value != 'object') {
record.setFieldValue(fieldname, value);
}
} //recordtype and id checking ends
}
} //for ends
var recordId = nlapiSubmitRecord(record);
nlapiLogExecution('DEBUG', 'id=' + recordId);
var nlobj = nlapiLoadRecord(datain.recordtype, recordId);
return nlobj;
}
The quoted code should be
record.setFieldValues(fieldname,value) // fieldname : custentity36 , value : 1,3

Kohana auth model

I'm new to kohana 3.2 and i couldnt find any answer regrading the auth module.
this is my code and forsome reason ever since i changed the user model to extend model_auth_user
the validation isnt being done prooperly. The password field can be inserted empty and no excpetion will be caught and same if the password_confirm and password fields are different:
public function action_new()
{
if ($_POST){
try
{
$user = ORM::factory('user')
->values(array(
'username' => $_POST['username'],
'email' => $_POST['email'],
'password' => $_POST['password'],
'password_confirm' => $_POST['password_confirm']));
$user->save();
$user->add('roles', ORM::factory('role', array('name' => 'login')));
$this->request->redirect('user/index');
}
catch (ORM_Validation_Exception $e)
{
$errors = $e->errors();
}
}
$view = View::factory('user/new')
->bind('errors',$errors); //pass the info to the view
$this->response->body($view); //show the view
}
thanks
You can override run_filter() method to force Kohana ignore password filtering in case of empty value. For example, put this code to your User_Model:
protected function run_filter($field, $value)
{
if ($field === "password" AND $value === "")
return "";
parent::run_filter($field, $value);
}
Try code sample from Model_Auth_User::create_user();
$user->save(Model_User::get_password_validation($_POST)->rule('password', 'not_empty'));
This validation execute before filters(hashing password). After hashing - blank password becomes not empty string.

How to implement a pagination for a search module in Zend Framework 2?

I have a module Search in my ZF2 application. The user fills in a search form out and gets a list of courses.
Now I'm adding the pagination to the module. The paginator is basically working: I can retrieve data over it and the pagination is displayed correctly (pagelinks 1-7 for 70 found courses with the dafault setting 10 items per page).
But it's still not usable. When I click on a pagelink, the form POST data is lost. I know -- it cannot work the way, how I implemented it (see the code below). But I have no idea, how to do it correctly, in order to eep checking the form data and nonetheless be able to use pagination.
That is my code:
Table class Search\Model\CourseTable
class CourseTable {
...
// without pagination
// public function findAllByCriteria(CourseSearchInput $input) {
// with pagination
public function findAllByCriteria(CourseSearchInput $input, $pageNumber) {
...
$select = new Select();
$where = new Where();
$having = new Having();
...
// without pagination
// $resultSet = $this->tableGateway->selectWith($select);
// return $resultSet;
// with pagination
$adapter = new \MyNamespqce\Paginator\Adapter\DbSelect($select, $this->tableGateway->getAdapter());
$paginator = new \Zend\Paginator\Paginator($adapter);
$paginator->setCurrentPageNumber($pageNumber);
return $paginator;
}
...
}
Search\Controller\SearchController
class SearchController extends AbstractActionController {
public function searchCoursesAction() {
$form = $this->getServiceLocator()->get('Search\Form\CourseSearchForm');
$request = $this->getRequest();
if ($request->isPost()) {
$courseSearchInput = new CourseSearchInput();
$form->setInputFilter($courseSearchInput->getInputFilter());
$form->setData($request->getPost());
if ($form->isValid()) {
$courseSearchInput->exchangeArray($form->getData());
// without pagination
// $courses = $this->getCourseTable()->findAllByCriteria($courseSearchInput);
// with pagination
$page = $this->params()->fromRoute('page');
$paginator = $this->getCourseTable()->findAllByCriteria($courseSearchInput, $page);
} else {
$paginator = null;
}
} else {
$paginator = null;
}
return new ViewModel(array(
'form' => $form,
// without pagination
// 'courses' => $courses,
// with pagination
'paginator' => $paginator,
'cities' => ...
));
}
...
}
How to get it working?
I also have the same problem, and I have solved it. But this is not good way. May be the idea will help you.
I solved it as follow: (Search pagination for Zend tutorial album module)
I build two action in controller named "search" and "index".
Whenever the search form submitted, it always post the value to search action. Search action build the url with search parameters, and redirect to index to disply search result.
And when the pagination links clicked, then posted values are passed through url. So whenever index action ask for search parameters, it always get the values in same format.
I defined route as follows:
'album' => array(
'type' => 'segment',
'options' => array(
'route' => '/album[/:action][/:id][/page/:page][/order_by/:order_by][/:order][/search_by/:search_by]',
'constraints' => array(
'action' => '(?!\bpage\b)(?!\border_by\b)(?!\bsearch_by\b)[a-zA-Z][a-zA-Z0-9_-]*',
'id' => '[0-9]+',
'page' => '[0-9]+',
'order_by' => '[a-zA-Z][a-zA-Z0-9_-]*',
'order' => 'ASC|DESC',
),
'defaults' => array(
'controller' => 'Album\Controller\Album',
'action' => 'index',
),
),
),
There is a parameter named "search_by", which will keep all search parameters as a json string. This is the point, which is not good I know, but have not find any other way yet.
"Search" action build this string as -
public function searchAction()
{
$request = $this->getRequest();
$url = 'index';
if ($request->isPost()) {
$formdata = (array) $request->getPost();
$search_data = array();
foreach ($formdata as $key => $value) {
if ($key != 'submit') {
if (!empty($value)) {
$search_data[$key] = $value;
}
}
}
if (!empty($search_data)) {
$search_by = json_encode($search_data);
$url .= '/search_by/' . $search_by;
}
}
$this->redirect()->toUrl($url);
}
And next index action decode the string, do necessary action, and also send the json string to view.
public function indexAction() {
$searchform = new AlbumSearchForm();
$searchform->get('submit')->setValue('Search');
$select = new Select();
$order_by = $this->params()->fromRoute('order_by') ?
$this->params()->fromRoute('order_by') : 'id';
$order = $this->params()->fromRoute('order') ?
$this->params()->fromRoute('order') : Select::ORDER_ASCENDING;
$page = $this->params()->fromRoute('page') ? (int) $this->params()->fromRoute('page') : 1;
$select->order($order_by . ' ' . $order);
$search_by = $this->params()->fromRoute('search_by') ?
$this->params()->fromRoute('search_by') : '';
$where = new \Zend\Db\Sql\Where();
$formdata = array();
if (!empty($search_by)) {
$formdata = (array) json_decode($search_by);
if (!empty($formdata['artist'])) {
$where->addPredicate(
new \Zend\Db\Sql\Predicate\Like('artist', '%' . $formdata['artist'] . '%')
);
}
if (!empty($formdata['title'])) {
$where->addPredicate(
new \Zend\Db\Sql\Predicate\Like('title', '%' . $formdata['title'] . '%')
);
}
}
if (!empty($where)) {
$select->where($where);
}
$album = $this->getAlbumTable()->fetchAll($select);
$totalRecord = $album->count();
$itemsPerPage = 2;
$album->current();
$paginator = new Paginator(new paginatorIterator($album));
$paginator->setCurrentPageNumber($page)
->setItemCountPerPage($itemsPerPage)
->setPageRange(7);
$searchform->setData($formdata);
return new ViewModel(array(
'search_by' => $search_by,
'order_by' => $order_by,
'order' => $order,
'page' => $page,
'paginator' => $paginator,
'pageAction' => 'album',
'form' => $searchform,
'totalRecord' => $totalRecord
));
}
All the sorting and paging url contain that string.
If you know all the searching paarameters before, then you can define that at route, and pass like the same way without json string. As I have to build a common search, I have build a single string.
Source code for "Album search" is available in git hub at https://github.com/tahmina8765/zf2_search_with_pagination_example.
Live Demo: http://zf2pagination.lifencolor.com/public/album
#Sam & #automatix in the question comments are both right. My suggestion (though I'm looking for a simpler alternative) is to construct a segment route, which covers all of the options that you're likely to need and start with a standard form POST request.
Then, after the request is validated, pass the form data to the paginationControl helper as follows:
$resultsView = new ViewModel(array(
'paginator' => $paginator,
'routeParams' => array_filter($form->getData())
));
Then, in your view template, set the route parameters in the paginationControl view helper:
<?php echo $this->paginationControl($paginator, 'Sliding', 'paginator/default',
array('routeParams' => $routeParams)
) ?>
I've used array_filter here because it's a really simple way of removing any element from the form data that's null, empty or so on. That way you don't pass in extra data that you don't need.

drupal 6: write to 2 different tables for user account registration form

function Mymodule_user($op,&$edit, &$account, $category = NULL) {
switch ($op) {
case 'register':
$result = db_query("SELECT id,name FROM {sites} ORDER BY name");
while($row=db_fetch_array($result)) {
$sites[$row['id']] = $row['name'];
}
$form['site_select'] = array(
'#type' => 'select',
'#title' => t('Select your site'),
'#options' => $sites,
)
return $form;
case 'insert':
//How to take the $form values from above and use in my query to
//write to my own table while writing to the standard 'users' table?
db_query("INSERT INTO {another_table} (site_name) VALUES ('%s')",
$form['site_select']);
);
When the user hits the SUBMIT button when creating a standard Drupal account, how do I pass my custom field value of $form['site_select'] to my case 'insert' so that I can write this to 'another_table'. The regular user data such as username and password needs to continue to write to the default 'users' table.
Q: Why not just let Drupal serialize and save your data to the 'users' table in the 'data' field as it normally does?
A: Because I want to be able to AJAX-ify and use autocomplete in another Drupal form, as well as query specific custom fields in MySQL. MySQL cannot serialize/unserialize. For example, "SELECT DISTINCT site_name FROM another_table"
You're probably gonna want to alter the user_register form in order to add your own callback function to that form's #submit property, like:
<?php
/**
* Implementation of hook_form_FORMID_alter().
* #param $form
* #param $form_state
* #return void
*/
function MYMODULE_form_user_register_alter(&$form, &$form_state) {
$form['#submit'][] = 'MYMODULEs_own_register_submit_callback_func';
}
And then in the callback you're going to have $form_state filled with whatever the user filled into the form (including the value for the extra site_select field element which you added in your hook_user implementation):
<?php
function MYMODULEs_own_register_submit_callback_func(&$form, &$form_state) {
// Do stuff with $form_state['values'], i.e $form_state['values']['site_select'], etc.
}

Drupal: Create custom search

I'm trying to create a custom search but getting stuck.
What I want is to have a dropdownbox so the user can choose where to search in.
These options can mean 1 or more content types.
So if he chooses options A, then the search will look in node-type P,Q,R.
But he may not give those results, but only the uid's which will be then themed to gather specific data for that user.
To make it a little bit clearer, Suppose I want to llok for people. The what I'm searching in is 2 content profile types. But ofcourse you dont want to display those as a result, but a nice picture of the user and some data.
I started with creating a form with a textfield and the dropdown box.
Then, in the submit handler, i created the keys and redirected to another pages with those keys as a tail. This page has been defined in the menu hook, just like how search does it.
After that I want to call hook_view to do the actual search by calling node_search, and give back the results.
Unfortunately, it goes wrong. When i click the Search button, it gives me a 404.
But am I on the right track? Is this the way to create a custom search?
Thx for your help.
Here's the code for some clarity:
<?php
// $Id$
/*
* #file
* Searches on Project, Person, Portfolio or Group.
*/
/**
* returns an array of menu items
* #return array of menu items
*/
function vm_search_menu() {
$subjects = _vm_search_get_subjects();
foreach ($subjects as $name => $description) {
$items['zoek/'. $name .'/%menu_tail'] = array(
'page callback' => 'vm_search_view',
'page arguments' => array($name),
'type' => MENU_LOCAL_TASK,
);
}
return $items;
}
/**
* create a block to put the form into.
* #param $op
* #param $delta
* #param $edit
* #return mixed
*/
function vm_search_block($op = 'list', $delta = 0, $edit = array()) {
switch ($op) {
case 'list':
$blocks[0]['info'] = t('Algemene zoek');
return $blocks;
case 'view':
if (0 == $delta) {
$block['subject'] = t('');
$block['content'] = drupal_get_form('vm_search_general_form');
}
return $block;
}
}
/**
* Define the form.
*/
function vm_search_general_form() {
$subjects = _vm_search_get_subjects();
foreach ($subjects as $key => $subject) {
$options[$key] = $subject['desc'];
}
$form['subjects'] = array(
'#type' => 'select',
'#options' => $options,
'#required' => TRUE,
);
$form['keys'] = array(
'#type' => 'textfield',
'#required' => TRUE,
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Zoek'),
);
return $form;
}
function vm_search_general_form_submit($form, &$form_state) {
$subjects = _vm_search_get_subjects();
$keys = $form_state['values']['keys']; //the search keys
//the content types to search in
$keys .= ' type:' . implode(',', $subjects[$form_state['values']['subjects']]['types']);
//redirect to the page, where vm_search_view will handle the actual search
$form_state['redirect'] = 'zoek/'. $form_state['values']['subjects'] .'/'. $keys;
}
/**
* Menu callback; presents the search results.
*/
function vm_search_view($type = 'node') {
// Search form submits with POST but redirects to GET. This way we can keep
// the search query URL clean as a whistle:
// search/type/keyword+keyword
if (!isset($_POST['form_id'])) {
if ($type == '') {
// Note: search/node can not be a default tab because it would take on the
// path of its parent (search). It would prevent remembering keywords when
// switching tabs. This is why we drupal_goto to it from the parent instead.
drupal_goto($front_page);
}
$keys = search_get_keys();
// Only perform search if there is non-whitespace search term:
$results = '';
if (trim($keys)) {
// Log the search keys:
watchdog('vm_search', '%keys (#type).', array('%keys' => $keys, '#type' => $type));
// Collect the search results:
$results = node_search('search', $type);
if ($results) {
$results = theme('box', t('Zoek resultaten'), $results);
}
else {
$results = theme('box', t('Je zoek heeft geen resultaten opgeleverd.'));
}
}
}
return $results;
}
/**
* returns array where to look for
* #return array
*/
function _vm_search_get_subjects() {
$subjects['opdracht'] =
array('desc' => t('Opdracht'),
'types' => array('project')
);
$subjects['persoon'] =
array('desc' => t('Persoon'),
'types' => array('types_specialisatie', 'smaak_en_interesses')
);
$subjects['groep'] =
array('desc' => t('Groep'),
'types' => array('Villamedia_groep')
);
$subjects['portfolio'] =
array('desc' => t('Portfolio'),
'types' => array('artikel')
);
return $subjects;
}
To be honest, I haven't seen many people implement hook_search. Most just use Views, or, for advanced things, something like Faceted Search.
Did you consider using either for your current project? Why didn't it work?
you could also use a combination of hook_menu for your results, and db_queries with your custom (and optimized so faster) queries.
For example:
search/%/%
where the arguments could be whatever you need, for example the first one for minimum price, the second price to the maximum price, third for minimal bedrooms... Your url would look always like that:
search/200/400/null/3/ ...
I have used a null, but it could be anything that you prefer to consider this field as empty.
Then, from your select form you have just to redirect following the structure of this url and adding the parameters in its correct place.
It is probalby not the most beautiful way of building a url, but using this technique and hook_theme will allow you to have an unlimited flexibility. I can show you a project where we are using this technique and, I think it looks pretty good :-).
Any comment regarding this would be much aprreciated :-).

Resources