Fetching and saving data to database at frontend of Joomla 3.x component

Files to create / update

update breedform.php     /site/controllers/breedform.php

update breedform.php     /site/models/breedform.php

 

File Details

site/controllers/breedform.php

public function save()
	{
		JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN'));

		$app   = JFactory::getApplication();
		$model = $this->getModel('BreedForm', 'BreedModel');

		$data = JFactory::getApplication()->input->get('jform', array(), 'array');

		// Validate the posted data.
		$form = $model->getForm();

		if (!$form)
		{
			throw new Exception($model->getError(), 500);
		}

		$data = $model->validate($form, $data);

		// Check for errors.
		if ($data === false)
		{
			$errors = $model->getErrors();

			for ($i = 0, $n = count($errors); $i < $n && $i < 3; $i++)
			{
				if ($errors[$i] instanceof Exception)
				{
					$app->enqueueMessage($errors[$i]->getMessage(), 'warning');
				}
				else
				{
					$app->enqueueMessage($errors[$i], 'warning');
				}
			}

			$input = $app->input;
			$jform = $input->get('jform', array(), 'ARRAY');

			$app->setUserState('com_breed.edit.breed.data', $jform);

			// Redirect back to the edit screen.
			$id = (int) $app->getUserState('com_breed.edit.breed.id');
			$this->setRedirect(JRoute::_('index.php?option=com_breed&view=breedform&layout=edit&id=' . $id, false));
		}

		$return = $model->save($data);

		// Check for errors.
		if ($return === false)
		{
			$app->setUserState('com_breed.edit.breed.data', $data);

			$id = (int) $app->getUserState('com_breed.edit.breed.id');
			$this->setMessage(JText::sprintf('Save failed', $model->getError()), 'warning');
			$this->setRedirect(JRoute::_('index.php?option=com_breed&view=breedform&layout=edit&id=' . $id, false));
		}

		if ($return)
		{
			$model->checkin($return);
		}

		$app->setUserState('com_breed.edit.breed.id', null);

		$this->setMessage(JText::_('COM_BREED_ITEM_SAVED_SUCCESSFULLY'));
		$menu = JFactory::getApplication()->getMenu();
		$item = $menu->getActive();
		$url  = (empty($item->link) ? 'index.php?option=com_breed&view=breeds' : $item->link);
		$this->setRedirect(JRoute::_($url, false));

		// Flush the data from the session.
		$app->setUserState('com_breed.edit.breed.data', null);
	}

In the process of saving data to database, coming from the form, first we are adding a method called “save()” to the breedform.php controller file. This method will then be called in the model, to store the in coming data in the appropriate table. In the controllers save method, first we are going to the check for the token, that whether it is passed or not. Form token is used to eliminate the request frogeries. If no token is found, operation will be terminated right at the first line. If token is set, we will initialize the $app variable and will call the breedform model, associated with this current controller. After that we will get the user data from the form, in the form is an array. In the next step, we are going to validate this data by first getting the form object at line 14 and if form object is not properly set, an exception will be thrown.

Then we are performing the actual validation here, by calling the validate() method of model and passing in the form object and the data array. The data would be checked here against the form rules, which have been set in the form xml file,through which the form in question was created. Then we will iterate the error messages using for loop and they will be shown back to the user by first storing the current form data in the session, so that the user should not have to re-enter the data, which was correct.

If there are no errors, the form data will be attempted to be saved to database. If still any errors are found, user would be redirected to the form edit page and error message will appear above the form, indicating the issues. 

After saving the data to database, previous id value of record will be cleared from the session and user will be redirected to the success page and a message will be thrown, indicating that the record has been saved successfully.

public function cancel()
	{
		$app = JFactory::getApplication();

		$editId = (int) $app->getUserState('com_breed.edit.breed.id');

		// Get the model.
		$model = $this->getModel('BreedForm', 'BreedModel');

		if ($editId)
		{
			$model->checkin($editId);
		}

		$menu = JFactory::getApplication()->getMenu();
		$item = $menu->getActive();
		$url  = (empty($item->link) ? 'index.php?option=com_breed&view=breeds' : $item->link);
		$this->setRedirect(JRoute::_($url, false));
	}

Now, when the user is on the edit form page and he doesnt want to create or edit a record, their would be a cancel button there, along with the submit or save button for him, to go back to the listing page, by pressing that button. The cancel() method in the controller will be called when that cancel button is pressed and what it is doing is straight forward, it is redirecting the user back.

 

/site/models/breedform.php

	public function &getData($id = null)
	{
		if ($this->item === null)
		{
			$this->item = false;

			if (empty($id))
			{
				$id = $this->getState('breed.id');
			}

			$table = $this->getTable();

			// Attempt to load the row.
			if ($table !== false && $table->load($id))
			{
				$user = JFactory::getUser();
				$id   = $table->id;
				
				if ($published = $this->getState('filter.published'))
				{
					if ($table->state != $published)
					{
						return $this->item;
					}
				}

				// Convert the JTable to a clean JObject.
				$properties  = $table->getProperties(1);
				$this->item = ArrayHelper::toObject($properties, 'JObject');
			}
		}

		return $this->item;
	}


	public function getItemIdByAlias($alias)
	{
		$table = $this->getTable();
		$table->load(array('alias' => $alias));
		return $table->id;
	}
	

	protected function loadFormData()
	{
	    $data = JFactory::getApplication()->getUserState('com_breed.edit.breed.data', array());
		if (empty($data))
		{
			$data = $this->getData();
		}

		return $data;
	}


	protected function populateState()
	{
		$app = JFactory::getApplication('com_breed');

		if (JFactory::getApplication()->input->get('layout') == 'edit')
		{
			$id = JFactory::getApplication()->getUserState('com_breed.edit.breed.id');
		}
		else
		{
			$id = JFactory::getApplication()->input->get('id');
			JFactory::getApplication()->setUserState('com_breed.edit.breed.id', $id);
		}

		$this->setState('breed.id', $id);

		// Load the parameters.
		$params       = $app->getParams();
		$params_array = $params->toArray();

		if (isset($params_array['item_id']))
		{
			$this->setState('breed.id', $params_array['item_id']);
		}

		$this->setState('params', $params);
	}


	public function save($data)
	{
		$id    = (!empty($data['id'])) ? $data['id'] : (int) $this->getState('breed.id');
		$state = (!empty($data['state'])) ? 1 : 0;
		$user  = JFactory::getUser();

		$table = $this->getTable();

		if ($table->save($data) === true)
		{
			return $table->id;
		}
		else
		{
			return false;
		}
	}	

   Now in the breedform.php model file,we have created a new function called getData() which basic purpose is to get a query and on the basis of that, retrieve the records from the database. It receives the id of the record as an argument and if no id is provided, it tries to access the id through the model state variable. After that the proper id of the record to access is provided, the getTable() is called through the $table property. Then we are checking the published state of the record and in last we are converting the JTable to a clean JObject and then returned back the item object through which we are going to access each column of the record.

   The next method we have created in this file is getItemIdByAlias(). Its purpose is to access the id of the record on the basis of unique alias. I will be covering this in detail, in the Access Control List section of the tutorial.

  The loadFormData() method is responsible for getting the data which will then be injected in the form. It first tries toload the data from user state, for example, if a user tries to submit the form and he left a compulsory field to fill up, the newly filled form field data will be returned back and the proper fields would be filled with that in this instance, rather than fetching data from database. But if this is not the case and user wants to edit a record, the data from the getData() method would be used.

  The purpose of populateState() methoid is to auto populate the model state. In this method, first we are geting the state of the id of record either from the user state or the provided or from the passed variable on default. Then we are accessing the parameters we have provided in the previous step, so that a single edit form could be associated with a menu item. And at the time of creating that menu, the item id parameter is provided at this point of the populateState method, we are trying to load the provided id from the paramaters and if there is any provided there, it will surpass any previous provided ids either through user state or passed variable and a new user state will be set on the basis of this id.  

  Next, the purpose of save method is to just save the data. It first checks that the $id is empty or not, meaning, ifit has to create a new record or update the previous one. It then calls the save() method of JTable class to save the data.    

 

Download Code

 

Add a Comment

Your email address will not be published. Required fields are marked *

Enjoy best web development services at an affordable price. Looking forward to build a good relationship and serve you better...

ABOUT CODINGACE

My name is Nohman Habib and I am a web developer with over 10 years of experience, programming in Joomla, Wordpress, WHMCS, vTiger and Hybrid Apps. My plan to start codingace.com is to share my experience and expertise with others. Here my basic area of focus is to post tutorials primarily on Joomla development, HTML5, CSS3 and PHP.

Nohman Habib

CEO: codingace.com

Request a Quote