I have a Joomla 3 installed in my local machine.
I've edited the default registration page to hide the Name field, wherein instead of using the full name as a field, I've divided it into First Name, Middle Name and Last Name.
Fortunately, the records being saved is successful and I can update them too.
The problem is when the administrator starts managing the list of users, there's no link to proceed. This means the field with the link, which is the Name field (the full one) is blank.
My objective is that upon registration, I can fill that field out with a concatenated first, middle and last name.
How can I do this in Joomla 3?
Thanks.
You would need to develop a custom user plugin to manage this properly. In addition, if you are going to write the plugin you should go ahead incorporate the entire use case into. Below is a quick draft of how your main plugin file would look:
<?php
defined('_JEXEC') or die;
class plgUserCustom extends JPlugin
{
public function __construct(& $subject, $config)
{
parent::__construct($subject, $config);
}
// Called while Joomla is loading the form for the view
// This is where you would remove or alter fields
// and load your custom xml form definition for the
// first, middle and last names
public function onContentPrepareForm($form, $data)
{
// Confirm valid JForm object or exit
if (!($form instanceof JForm))
{
$this->_subject->setError('JERROR_NOT_A_FORM');
return false;
}
// Check we are manipulating a valid form.
// If the active view isn't listed in array exit as plugin not needed
//
// com_users.registration = front end registration form
// com_users.profile = front end edit profile form
// com_users.user = back end administrators form
if (!in_array($form->getName(), array('com_users.registration', 'com_users.profile', 'com_users.user'))) {
return true;
}
// The core JForm object for the view will be loaded
// manipulate the fields any way you like
// In below example, the name field will be removed
// from the users registration, profile and admin user manager view
if (in_array($form->getName(), array('com_users.registration', 'com.users.profile', 'com_users.user'))) {
$form->removeField('name');
// Now add the form xml path for your custom name fields
// In this example the plugin has a forms directory
JForm::addFormPath(dirname(__FILE__) . '/forms');
$form->loadFile("custom", false);
}
return true;
}
// This is where Joomla loads any existing data into the form field
// and where you would take the standard name field and separate
// into first, middle and last name values and attach to data object.
// The data object property names must match the field name in your
// xml form definition file.
public function onContentPrepareData($context, $data) {
// Verify you are in the correct form before manipulating data
if (!in_array($context, array('com_users.profile','com_users.user', 'com_users.registration'))) {
return true;
}
// explode core name field into parts, attach to core data object
// as first, middle and last name and unset name data.
// CAUTION: You should implement check to verify middle name entered
// or not by verifying if parts array length is 2 or 3
$parts = explode(" ", $data->name);
$data->first_name = $parts[0];
$data->middle_name = $parts[1];
$data->last_name = $parts[2];
unset($data->name);
}
return true;
}
// This method fires before Joomla save the user data and is where
// you should combine the first, middle and last names into one name
// and attach to data object and remove references to first, middle and
// last names.
public function onUserBeforeSave($user, $isNew, $data) {
// Manicure data before save, implode first, middle and last name
// into one field and add to data object, unset first, middle and last
// name from data object
$data->name = implode(" ", array($data->first_name, $data->middle_name, $data->last_name));
unset($data->first_name);
unset($data->middle_name);
unset($data->last_name);
return true;
}
public function onUserAfterSave($data, $isNew, $result, $error)
{
return true;
}
public function onUserAfterDelete($user, $succes, $msg)
{
return true;
}
public function onUserLogin($user, $options)
{
return true;
}
public function onUserLogout($credentials, $options) {
return true;
}
}
I added links to writing a plugin to help you in creating and packaging the installation ZIP to install the plugin. I also attached a link for creating xml form definitions.
Good Luck!
http://docs.joomla.org/J3.x:Creating_a_Plugin_for_Joomla
http://docs.joomla.org/XML_JForm_form_definitions
You can manage/manipulate user data using a User Plugin. This link will show you how to use example.php (which, I believe, is included with the Joomla installation). You're probably most interested in function onUserBeforeSave, and may not even need your module changes if you manipulate their input before Joomla saves it.
Related
So I have a License model created through the octoberCMS builder with the List and Form views.
The license model contains one relation to School model.
Under the Form view there is a dropdown list with schools and an input field (type=number) which defines how many Licenses to create for the chosen school.
The default behaviour creates only 1 license
How to create the entered amount of licenses instead?
You need to override default behaviour.
Note: This task require programming knowledge of OctoberCMS.
In your controller you need to add this method.
use Flash;
use Backend;
// ...
public function create_onSave($context = null)
{
// 1. init form for your modal and get input data from it
$model = $this->asExtension('FormController')->formCreateModelObject();
$model = $this->asExtension('FormController')->formExtendModel($model) ?: $model;
$this->asExtension('FormController')->initForm($model);
$form = $this->asExtension('FormController')->formGetWidget();
$data = $form->getSaveData();
// 2. get proper count field here and convert to int for loop
$count = intval($data['license_to_create']);
// 3. validation step
// if($validationFailed) {
// Flash::error('Something Went Wrong.');
// return;
// }
// 4. loop
foreach ($i = 1; $i <= $count; $i++) {
$licenseModel = new LicenseModel;
// you can add other data
// you can access $data['school_id'] here
// $licenseModel->school_id = $data['school_id'];
$licenseModel->save();
}
// 5. success message
Flash::success($count . ' License Added');
// 6. just redirect it to desired location
return Backend::redirect('/hardiksatasiya/sotest/skills');
}
Explanation
here we initialise required variables so we can get data which were filled in text box, this is default code so i just copied it from core code.
once we have our $data variable we can access filled data we use $data['license_to_create'] in your case its 100, and $data['school_id'] for which school you need to create license,
Note: you may have different fields please change accordingly.
validation step *optional, you can add some checks here and stop flow if something is not correct with error message.
loop to create new records for license modal ,[ default code will create only 1 record], but here we create it based on given count $data['license_to_create']
just normal success message.
redirect where we need to redirect normally you need to redirect it to /author-name/plugin-name/license-controller Note: you may have different url please change accordingly.
please add comment if you have any doubt.
Well actually I solved it already also by writing a custom create_onSave function for Licenses controller:
public function create_onSave(){
$quantity = post('License[_quantity]');
$school_id = post('License[school]');
for($i = 1; $i <= $quantity; $i++){
# Create License
$license = new \Acme\Plugin\Models\License();
$license->school_id = $school_id;
$license->save();
}
\Flash::success('Added '.$quantity.' Licenses');
}
I am new to OpenCart 2. By default OpenCart provides the customer registration form uit of the box. I would like to create another registration form for company as user which has different input fields than the customer registration form.
I copied the following files and renamed them properly.
- catalog/controller/account/register.php
- catalog/model/account/customer.php
- template/account/register.tpl
I have created a new database table for registering companies. When I looked in the addCustomer($data) function in the ModelAccountCustomer model I stuck with the following line of code.
$this->event->trigger('pre.customer.add', $data);
I want to change it into $this->event->trigger('pre.company.add', $data); in my addCompany($data) function of my ModelAccountCompany model. But it causes error. How can I solve it?
Another issue is the following line of code inside of my ControllerAccountRegisterCustomer controller.
$this->customer->isLogged()
and
$this->customer->login();
I want to place the similarly code in my ControllerAccountRegisterCompany controller as follows.
$this->company->isLogged()
and
$this->company->login();
But the $this->company does not return a company object to call its' functions. How can I solve it?
If you want to create custom event handler like $this->event->trigger('pre.company.add', $data);. First you need to install this event in database. Please check following sample.
<?php class ControllerModuleA2bizz extends Controller {
public function install() {
$this->load->model('extension/event');
$this->model_extension_event->addEvent('a2bizz', 'pre.admin.store.delete', 'module/a2bizz/on_store_delete');
$this->model_extension_event->addEvent('a2bizz', 'post.customer.add', 'module/a2bizz/on_customer_add');
}
public function uninstall() {
$this->load->model('extension/event');
$this->model_extension_event->deleteEvent('a2bizz');
}
public function on_store_delete($store_id) {
$this->load->model('setting/store');
$store_info = $this->model_setting_store->getStore($store_id);
$admin_mail = $this->config->get('config_email');
mail($admin_mail, "A store has been deleted", "The store " . $store_info['url'] . " was deleted.");
}
}
To more about event handler in opencart 2.x. Read Here
I have a model in Yii that contains an array of another model type. I am then trying to validate that no duplicate emails are filled out in a form, where you can fill out for n number of persons at the same time.
My current approach is to trigger a custom validation of the "outer" model that holds all the entrants, however, that model is not accessible in the view, only the array of entrants is, and if I then trigger the error on the "outer" model, it will not be displayed to the user. Therefore I would like to trigger it for the first entrant that violates the rule, but how do I go about doing that?
My code that attempts this, looks like this so far:
/*
* Custom validation rule to hinder the same e-mail being used twice.
*/
public function noRepeatingEmails($attribute, $params)
{
if (!isset($attribute)) return;
$emails = array();
foreach($this->$attribute as $user)
{
if (isset($user) && strlen(trim($user->email)) != 0)
{
$emailToAdd = strtolower(trim($user->email));
if (in_array($emailToAdd, $emails))
{
$this->addError($user, '<my error message>');
return;
}
else
{
$emails[] = $emailToAdd;
}
}
}
}
This only results in a code 500 error though:
Illegal offset type
I presume that is because it is looking for the property "user" in my model, rather than adding an error to "$user" object.
How do I best accomplish this?
I have a .NET background, so I am probably doing loads wrong here however.
If I understood correctly from your comment, you want to validate your model before saving it. For this purpose, CActiveRecord provides beforeSave() method. You need to put this method inside your model:
protected function beforeSave()
{
if(parent::beforeSave())
{
if(/* Your validation goes here*/)
return true;
else
return false
}
else
return false;
}
When the result of this method is true, save() method will be called. Otherwise save() method won't be called and therefore no record will be saved into your database.
I would like to filter some fields in my form with strtolower() function. Unfortunately I can't find any example of doing that.
How can I write such filter, that will lowercase the input, check the database if element exists and then decide wheter to add the record or not?
1) new project custom validator (we will use it like value filter here):
/lib/validator/MyProjectStringLowerCase.class.php
<?php
class MyProjectStringLowerCase extends sfValidatorBase
{
/**
* #see sfValidatorBase
*/
protected function doClean($value)
{
return strtolower($value);
}
}
2) bound it to field:
$this->setWidget('my_field_name', new sfWidgetFormInputText());
$this->validatorSchema['my_field_name'] = new MyProjectStringLowerCase();
If you have some validator on that field already, you can merge them into combined validators this way:
$this->validatorSchema['my_field_name'] = new sfValidatorAnd(array(
$this->validatorSchema['my_field_name'], // the original field validator
new MyProjectStringLowerCase(),
));
The combined validators order influent how value will flow trough them, so if you want to have value filtrated in second validation, set MyProjectStringLowerCase as the first one.
There are 2 differences between this approach and using post processing (like doSave() for instance):
the value here will be filtered after each send (and will show
filtered in displaying of form errors)
You can reuse it very cleanly and easily in other fields or forms in
your project
In your Form, you can override the doSave() method to do any manual interventions that you need to do that aren't completed by the form validation methods.
For example:
public function doSave($con = null) {
$employee = $this->getObject();
$values = $this->getValues();
// do your filter
$this->values['name'] = strtolower($values['name']);
parent::doSave($con);
}
I'm building my first site with drupal. And I made a custom user field: Full name.
Now I want to get the value of this fild in my template to say “Hello, %username%”.
How do I do that?
Clive's answer is correct except that you should use field_get_items to get the values for a field. It will handle the language for you. You should also sanitize the value.
function THEME_preprocess_page() {
global $user;
$user = user_load($user->uid); // Make sure the user object is fully loaded
$full_names = field_get_items('user', $user, 'field_full_name');
if ($full_names) {
$vars['full_name'] = check_plain($full_names[0]['value']);
}
}
If your site uses the Entity API module, you can also use a entity metadata wrapper like this
function THEME_preprocess_page() {
global $user;
$user = user_load($user->uid); // Make sure the user object is fully loaded
$wrapper = entity_metadata_wrapper('user', $user);
$vars['full_name'] = $wrapper->field_full_name->get(0)->value(array('sanitize' => TRUE));
}
See also Writing robust code that uses fields, in Drupal 7
Depending on your setup/field name, something like this in template.php (preprocess function for the template file):
function mytheme_preprocess_page() {
global $user;
$user = user_load($user->uid); // Make sure the user object is fully loaded
$vars['full_name'] = $user->field_full_name[LANGUAGE_NONE][0]['value'];
}
Then something like this in page.tpl.php:
if (isset($full_name) && !empty($full_name)) :
echo 'Hello ' . $full_name;
endif;
Note that LANGUAGE_NONE may need to be changed if you're running a multi-lingual site.
I know this question was asked quite a while ago, but I wanted to post an alternative. It looks like you want to change the field in the $variables array that is $variables['name'] to what you have in your custom field that I've called field_real_name. If you are using a preprocess function, there is no need to pull in the global $user object. You have access to the $variables array, so you can get the user information with this - it will load the information associated with the uid (see template_preprocess_username):
function mythemename_preprocess_username(&$variables) {
$account = user_load($variables['account']->uid);
...more code will go here in a moment
}
If you dpm($account) (or kpr($account) if you aren't using devel) you will see that you have access to all of the user information, without using the global $user object.
Then you can change the output of $variables['name'] to be your field_real_name as follows:
function mythemename_preprocess_username(&$variables) {
// Load user information with user fields
$account = user_load($variables['account']->uid);
// See if user has real_name set, if so use that as the name instead
$real_name = $account->field_real_name[LANGUAGE_NONE][0]['safe_value'];
if (isset($real_name)) {
$variables['name'] = $real_name;
}
}
We can add the below code anywhere in the template file.
<?php
global $user;
$user = user_load($user->uid);
print $user->name;
?>