Custom error message for validation rules in Kohana 3.2 - kohana

I have a controller=product.php,a model=category.php, and a custom error message file category.php. When I am submitting the empty form , I am getting error messages for rule "not_empty, but I am not getting error message for rule "unique_categoryname"
Please help!
class Controller_Product extends Controller_Application
{
public function action_addcategory()
{
$errors='';
$cat = new Model_Category();
$validation=Validation::factory($this->request->post())
->rule('cat_name',array($cat,'unique_categoryname'));
if ($validation->check())
{
if (HTTP_Request::POST == $this->request->method())
{
try
{
$cat_name=$_POST['cat_name'];
$cat_description=$_POST['cat_description'];
if (isset($_FILES['cat_image']))
{
$filename = $cat->upload_photo($_FILES['cat_image']);
}
$cat->InsertCategory($cat_name,$cat_description,$filename);
Request::current()->redirect('product/listcategory');
}
catch (ORM_Validation_Exception $ex)
{
$errors = $ex->errors('models');
}
}
}
$view = new View('product/addcategory');
$view->set("categories",$cat);
$view->set('errors',$errors);
$this->template->content=$view;
}
}
class Model_Category extends ORM
{
public function rules()
{
return array(
'cat_name' => array(
array('not_empty'),
array('min_length', array(':value', 4)),
array('max_length', array(':value', 32)),
),
'cat_description' => array(
array('not_empty'),
array('min_length', array(':value', 10)),
),
);
}
}
//Custom error messages page : messages/models/category.php
return array(
'cat_name' => array(
'not_empty' => 'You must provide a category name.',
'min_length' => 'The category name must be at least :param2 characters long.',
'max_length' => 'The category name must be less than :param2 characters long.',
'unique_categoryname'=> 'Category Name already exists, please change',
),
'cat_description' => array(
'not_empty' => 'You must provide category description .',
'min_length' => 'The category description must be at least :param2 characters long.',
),
);

You need to pass your $validation to the ORM save/update method.
Assuming InsertCategory is a wrapper for saving, you should pass it there:
$cat->InsertCategory($cat_name, $cat_description, $filename, $validation);
Then in InsertCategory method:
public function InsertCategory(....)
{
// .....
$this->save($validation);
}
Be aware that there is a bug in Kohana 3.2 and external validation messages go to _external.php file.
You can find more information here: http://kohanaframework.org/3.2/guide/orm/validation#external-validation

Related

Buddypress new profile tabs and sub tabs: How to set up url slug properly?

First of all, I’ve seen alot of people trying to do a similar task, which is simply to create a new tab, with sub tabs in the user profile menu. I’ve managed to do this, but I can’t seem to get the url slug to work properly. When I click on the first sub tab, it simply takes me back to the main page for the user profile, and when I click on any additional sub tabs I get 404 errors. I have a feeling I’m missing something pretty simple, and I’ve been trying to learn over the last couple weeks how to make this work without any luck. If someone could help guide me on how to get this working properly, I would very grateful, and I imagine many others would find this post useful in the future.
For the record the main profile tab works properly, but the sub-tabs do not.
Here is the code I currently have in my bp-custom.php file
// My Membership Profile Tab
function profile_new_nav_item() {
global $bp;
bp_core_new_nav_item(
array(
'name' => 'My Membership',
'slug' => 'my-membership',
'default_subnav_slug' => 'extra_sub_tab', // We add this submenu item below
'screen_function' => 'view_manage_tab_main'
)
);
}
add_action( 'bp_setup_nav', 'profile_new_nav_item', 10 );
function view_manage_tab_main() {
add_action( 'bp_template_content', 'bp_template_content_main_function' );
bp_core_load_template( 'template_content' );
}
function bp_template_content_main_function() {
if ( ! is_user_logged_in() ) {
wp_login_form( array( 'echo' => true ) );
}
}
function profile_new_subnav_item() {
global $bp;
bp_core_new_subnav_item( array(
'name' => 'Membership Level',
'slug' => 'extra_sub_tab',
'parent_url' => $bp->loggedin_user->domain . $bp->bp_nav[ 'extra_tab' ][ 'slug' ] . '/',
'parent_slug' => $bp->bp_nav[ 'my-membership' ][ 'slug' ],
'position' => 10,
'screen_function' => 'view_manage_sub_tab_main'
) );
}
add_action( 'bp_setup_nav', 'profile_new_subnav_item', 10 );
function view_manage_sub_tab_main() {
add_action( 'bp_template_content', 'bp_template_content_sub_function' );
bp_core_load_template( 'template_content' );
}
function bp_template_content_sub_function() {
if ( is_user_logged_in() ) {
//Add shortcode to display content in sub tab
echo do_shortcode( '[membership]' );
} else {
wp_login_form( array( 'echo' => true ) );
}
}
// My Billing Profile Tab
function profile_new_subnav_item_billing() {
global $bp;
bp_core_new_subnav_item( array(
'name' => 'Billing',
'slug' => 'extra_sub_tab_billing',
'parent_url' => $bp->loggedin_user->domain . $bp->bp_nav[ 'extra_tab' ][ 'slug' ] . '/',
'parent_slug' => $bp->bp_nav[ 'my-membership' ][ 'slug' ],
'position' => 20,
'screen_function' => 'view_manage_sub_tab_billing'
) );
}
add_action( 'bp_setup_nav', 'profile_new_subnav_item_billing', 20 );
function view_manage_sub_tab_billing() {
add_action( 'bp_template_content', 'bp_template_content_sub_function_billing' );
bp_core_load_template( 'template_content' );
}
function bp_template_content_sub_function_billing() {
if ( is_user_logged_in() ) {
//Add shortcode to display content in sub tab
echo do_shortcode( '[billing]' );
} else {
wp_login_form( array( 'echo' => true ) );
}
}
You may use this:
// define your parent slug
$parent_slug = 'activity';
bp_core_new_subnav_item( array( .........
'parent_url' => $bp->loggedin_user->domain . $parent_slug.'/',
'parent_slug' => $parent_slug,
It works for me.

how to sign up with different fields in kohana

The Model_Auth_User class in Kohana uses 'username', 'email','password' to create a new user
what if i want it to take only 'email', 'password' and also modify the validation to validate 'email_confirm' instead of 'password_confirm'
Finally i did it, All what I have to doe is to comment some lines which add the rules of validating user input
open C:\xampp\htdocs\kohana\modules\orm\classes\Model\Auth\User.php
and comment lines from 33:38 inclusive as following:
public function rules()
{
return array(
//as we don't have a username we don't need to validate it!
// 'username' => array(
// array('not_empty'),
// array('max_length', array(':value', 32)),
// array(array($this, 'unique'), array('username', ':value')),
// ),
'password' => array(
array('not_empty'),
),
'email' => array(
array('not_empty'),
array('email'),
array(array($this, 'unique'), array('email', ':value')),
),
);
}
You only keep the rules for validating what you need
Avoid changing of the system folder contents. Otherwise your changes will be lost after the next upgrade.
The more correct approach is to override the validation rules.
In file application/classes/Model/user.php:
<?php
class Model_User extends Model_Auth_User
{
public function rules()
{
$rules = parent::rules();
unset($rules['username']);
return $rules;
}
}
?>

Kohana 3.2: Custom error message for a custom validation rule?

I am using a custom method for a validation rule in my model (using Kohana 3.2). I am following the format listed on the documentation.
// Calls A_Class::a_method($value);
array(array('A_Class', 'a_method')),
But I can't seem to figure out how to add a custom error message if the rule fails.
Any help?
For this example we will assume a modal "user" and validating the field "username"
/application/classes/model/user.php
class Model_User extends ORM
{
public function rules()
{
return array(
'username' => array(
array('not_empty'),
array('A_Class::a_method', array(':value')),
)
);
}
}
A_Class
public static function a_method($value)
{
// Validate and return TRUE or FALSE
}
/application/messages/forms/user.php
Added a forms folder so show we can select message file to load with errors. Message file matches model name (user)
return array(
'username' => array(
'not_empty' => 'Custom error message for not_empty method',
'A_Class::a_method' => 'Custom error message for you own validation rule...'
),
);
Now in your controller to validate and display the error messages
class Controller_User extends Controller
{
// User model instance
$model = ORM::factory('user');
// Set some data to the model
$model->username - 'bob';
// Try to validate and save
try
{
$model->save()
}
catch (ORM_Validation_Exception $e)
{
// Loads messages from forms/user.php
$errors = $e->errors('forms');
// See the custom error messages
echo Debug::vars($errors);
)
)

Extending Drupal 7 search

I want to extend default Drupal 7 node search with one additional field.
I alter search form with the following new field:
function mymodule_form_search_form_alter(&$form, &$form_state, $form_id) {
$form['basic']['site'] = array(
'#type' => 'select',
'#options' => array(
'KEY1' => 'TITLE1',
'KEY2' => 'TITLE2',
'KEY3' => 'TITLE3'
)
);
}
I have a field called field_data_field_site.field_site_value which i need to use as a filter in this search.
I've tried to read about hook_search_* functions but didn't get the idea.
My question is the following. How can I extend search form? Anyone have live examples?
The following is the best way I solve this problem.
First of all I need to alter Drupal's search block and search form with my field and define new submit function.
/**
* Implements hook_form_FORM_ID_alter().
*/
function mymodule_form_search_block_form_alter(&$form, &$form_state, $form_id) {
$form['#submit'][] = 'search_form_alter_submit';
$form['site'] = array(
'#type' => 'select',
'#options' => _options(),
'#default_value' => (($_GET['site']) ? $_GET['site'] : '')
);
}
/**
* Implements hook_form_FORM_ID_alter().
*/
function mymodule_form_search_form_alter(&$form, &$form_state, $form_id) {
$form['#submit'][] = 'search_form_alter_submit';
$form['basic']['site'] = array(
'#type' => 'select',
'#options' => _options(),
'#default_value' => (($_GET['site']) ? $_GET['site'] : '')
);
}
function _options() {
return array(
'' => 'Select site',
'site-1' => 'Site 1',
'site-2' => 'Site 2'
);
}
Submit function will forward us to default search/node page but with our query. Page would look like search/node/Our-query-string?site=Our-option-selected.
function search_form_alter_submit($form, &$form_state) {
$path = $form_state['redirect'];
$options = array(
'query' => array(
'site' => $form_state['values']['site']
)
);
drupal_goto($path, $options);
}
Next step is to use hook_search_info (Don't forget to turn it on and set as default on admin/config/search/settings page).
/**
* Implements hook_search_info().
*/
function mymodule_search_info() {
return array(
'title' => 'Content',
'path' => 'node',
'conditions_callback' => '_conditions_callback',
);
}
Conditions callback function defined in hook_search_info. We need to provide additional queries to our search.
function _conditions_callback($keys) {
$conditions = array();
if (!empty($_REQUEST['site'])) {
$conditions['site'] = $_REQUEST['site'];
}
return $conditions;
}
Finally, hook_search_execute will filter our content by our query. I used default code from this hook with modifications I need.
/**
* Implements hook_search_execute().
*/
function mymodule_search_execute($keys = NULL, $conditions = NULL) {
// Build matching conditions
$query = db_select('search_index', 'i', array('target' => 'slave'))
->extend('SearchQuery')
->extend('PagerDefault');
$query->join('node', 'n', 'n.nid = i.sid');
// Here goes my filter where I joined another table and
// filter by required field
$site = (isset($conditions['site'])) ? $conditions['site'] : NULL;
if ($site) {
$query->leftJoin('field_data_field_site', 's', 's.entity_id = i.sid');
$query->condition('s.field_site_value', $site);
}
// End of my filter
$query
->condition('n.status', 1)
->addTag('node_access')
->searchExpression($keys, 'node');
// Insert special keywords.
$query->setOption('type', 'n.type');
$query->setOption('language', 'n.language');
if ($query->setOption('term', 'ti.tid')) {
$query->join('taxonomy_index', 'ti', 'n.nid = ti.nid');
}
// Only continue if the first pass query matches.
if (!$query->executeFirstPass()) {
return array();
}
// Add the ranking expressions.
_node_rankings($query);
// Load results.
$find = $query
->limit(10)
->execute();
$results = array();
foreach ($find as $item) {
// Build the node body.
$node = node_load($item->sid);
node_build_content($node, 'search_result');
$node->body = drupal_render($node->content);
// Fetch comments for snippet.
$node->rendered .= ' ' . module_invoke('comment', 'node_update_index', $node);
// Fetch terms for snippet.
$node->rendered .= ' ' . module_invoke('taxonomy', 'node_update_index', $node);
$extra = module_invoke_all('node_search_result', $node);
$results[] = array(
'link' => url("node/{$item->sid}", array('absolute' => TRUE)),
'type' => check_plain(node_type_get_name($node)),
'title' => $node->title,
'user' => theme('username', array('account' => $node)),
'date' => $node->changed,
'node' => $node,
'extra' => $extra,
'score' => $item->calculated_score,
'snippet' => search_excerpt($keys, $node->body)
);
}
return $results;
}
I'd be happy if anyone would give me a better answer.

Module development: hook_form(), hook_menu() and how to get $_POST

I want to improve my knowledge in module development (which is far away from basic), so I try to develop a perimeter search module.
What I've achieved for now is a block containing a form:
function perimeter_search_block_view($delta = '') {
// Define an empty array for the block output.
$block = array();
switch($delta) {
case 'perimeter_search_box':
$block['subject'] = t('Perimeter search box');
$block['content'] = drupal_get_form('perimeter_search_form');;
break;
}
return $block;
}
/**
* Implementation of the perimeter search form
* #return array with form data
*/
function perimeter_search_form($form, &$form_state) {
$form = array(
'#action' => 'perimeter-search-results',
'keyword' => array(
'#type' => 'textfield'
),
'location' => array(
'#type' => 'textfield'
),
'perimeter' => array(
'#type' => 'select',
'#title' => t('Perimeter'),
'#options' => array('15 km', '30 km', '60 km', '120 km')
),
'submit' => array(
'#type' => 'submit',
'#value' => t('Start search')
)
);
return $form;
}
I also have a function to output the search results:
/**
* Implementation of hook_menu()
* #return defined menu/page items
*/
function perimeter_search_menu() {
$items = array();
// Search results page
$items['perimeter-search-results'] = array(
'title' => t('Perimeter search results'),
'page callback' => 'perimeter_search_results',
'access arguments' => array('view perimeter search'),
'type' => MENU_NORMAL_ITEM
);
return $items;
}
/**
* Processing job search queries
*/
function perimeter_search_results() {
$page_content = t('Search results');
return $page_content;
}
My (simple?) question is: how to get the post data (keyword, location, perimeter) in my perimeter_search_results() function?
Easy, you have to create the _submit function for your form, here an example:
function perimeter_search_form_submit($form, &$form_state) {
/*
* Your data handling goes here on the $form_state['values']['myfieldname']
* variable.
*/
drupal_set_message(t('Awesome, you managed to fill the form!'));
}
And if you need to validate..
function perimeter_search_form_validate($form, &$form_state) {
if($form_state['values'['myfieldname'] == '') {
form_set_error('', t('Hey, it doesn't work like that!'));
}
}
Just remember that if you add the attribute '#required' => TRUE to a form field, the field will be automatically validated to always require that field, so you don't need to use the validator for that field if you just need that it get compiled.

Resources