Перейти к содержимому


Сохранение данных в БД согласно принципам MVC


  • Вы не можете ответить в тему
В этой теме нет ответов

#1 Glebson

    Новичок

  • Премиум клиент WebForMySelf
  • Pip
  • 9 сообщений
Репутация: 0

Отправлено 05 Ноябрь 2019 - 08:53

Здравствуйте. Задачу я худо бедно решил, но хотелось бы узнать мнение профессионалов. Насколько верно понял саму MVC. Пока писал вопрос, постарался максимально добавить комментариев в код, для самого себя.

Итак, глобальная задача - пытаюсь сделать онлайн игру. Пользователь проходит некоторые задания, за это на его счет приходят очки экспириенса и левелапа.

Как я это вижу - в виде "Упражнения" пользователь проходит задание, паралельно джава скриптом подсчитываются очки согласно сложности и проценту прохождения. Далее, как надоело, пользователь жмет кнопку "Завершить" на форме вида. Формируется строка запроса.Пользователь перенаправляется в вид "Поздравлений". Здесь его очки добавляются в БД к заработанным ранее. И на экран выводится форма - "Позравляем, вы набрали Х-очков и достигли Н-го уровня"

Вот как я решил.

В шаблоне Exersice/tmpl/default.php кнопка
<?php  $link = 'index.php?option=com_listen&view=congratulation&task=congratulation.progress&expirience=20&level=10'  ?>
<a href="<?php echo $link;?>"> Завершить </a>


через точку входа перенаправляется в субКонтроллер Congratulation.php в задачу progressю
Вот код:
<?php
defined("_JEXEC") or die();
class ListenControllerCongratulation extends JControllerForm {
public function progress(){  $input = $this->input;
  $source = $input->getArray(array('expirience' => '','level' => ''));
  // здесь запрос к модели на сохранение данных $source
  $model = $this->getModel();
  $success = $model->progress($source);  

// ************************************
// ******* какие то проверки над $success
// ************************************

  // очищение строки запроса от лишних данных
  // и обращение к виду ListenViewCongratulation
  $this->setRedirect(
	\JRoute::_(
	 'index.php?option=' . $this->option . '&view=' . $this->view_item
	 . $this->getRedirectToListAppend(), false
	)
   );
}}
?>


оттуда запрос к модели на получение, обработку и перезапись данных
Вот код:
<?php
public function progress($prog=NULL){
  // Запрос к БД по полям пользователя
  $userProgress = $this->getProgressUser();  

// ******************************
// ** здесь какие то проверки $userProgress
// ******************************

// ******************************
// ** здесь какие то проверки $prog
// ******************************

  $userProgress->expPoints += $prog['expirience'];
  $userProgress->levPoints += $prog['level'];  // обновление поля опыта пользователя
  $success = $this->updateProgress($userProgress->expPoints,2);
  if (!$success) { return FALSE;}

  // обновление поля опыта пользователя
  $success = $this->updateProgress($userProgress->levPoints,3);
  if (!$success) { return FALSE;}
  return $success;
}
protected function getProgressUser(){
  $userId = JFactory::getUser()->id;  $db = jFactory::getDbo();
  $query = $db->getQuery(TRUE);
  // при составлении запроса много бился головой о стенку
  $query->select('item_id,  MAX(if(field_id = 1, value,0)) AS level,
		 MAX(if(field_id = 2, value,0)) AS expPoints,
		 MAX(if(field_id = 3, value,0)) AS levPoints');
		
  $query->from($db->quoteName('#__fields_values','v'));
  $query->where('v.item_id ='.$userId);
  $query->group('item_id');

  $db->setQuery($query);
  $result = $db->loadObject();//  echo('<pre>');

//   echo('progress result = ');
//   print_r($result);
//  echo('</pre>');

  return $result;
}

protected function updateProgress($val,$fieldId){
  $userId = JFactory::getUser()->id;  $db = jFactory::getDbo();
  $query = $db->getQuery(true);
  $fields = array(
	  $db->quoteName('value') . ' = ' . $val
  );

$conditions = array(
	  $db->quoteName('item_id') . '=' . $userId,
	  $db->quoteName('field_id') .'='. $db->quote($fieldId)
  );
  
  $query->update($db->quoteName('#__fields_values'))
	  ->set($fields)
	  ->where($conditions);
  $db->setQuery($query)
	  ->execute();

// ******************************
// ** здесь какие то проверки результатов обновления БД
// ******************************	

return TRUE;
}
?>


далее из контроллера обращенние к виду ListenViewCongratulation, а уже оттуда снова обращение к модели, снова обращение к БД и вывод на экран.

вот код вида
<?php
defined("_JEXEC") or die();
class ListenViewCongratulation extends JViewLegacy {

protected $form;
protected $item;
protected $state;

public function display($tmpl = null) {

  // обращение к модели
  $this->item = $this->get('Item');//getItem()
  // обращение к сессии
  $this->state = $this->get('State');
  $this->setDocument();
  parent::display($tmpl);
}

protected function setDocument () {
  // $document = JFactory::getDocument();
  // $document->setTitle(JText::_('COM_DOSKA_MANEGER_TYPE_NEW_PAGE_TITLE'));
  // $document->addStyleSheet(JUri::root(true).'/media/com_doska/css/style.css');
}
}
?>

вот отрывок кода из модели
<?php
public function getItem($pk = NULL) {
  $data = $this->getProgressUser();
  if($data) {
   $params = new JRegistry;
   $params->loadString($data->params);
   $data->params = $params;
  
   $params = clone $this->getState('params');
   $params->merge($data->params);
   $data->params = $params;
   return $data;
  }
  else {
   return FALSE;
  }
}
?>


смущает что я дважды по одному поводу обращался к БД.

а ещё пока писал, подумал что Дополнительные поля пользователей и материалов выполнены неудобно, наверное в силу своей универсальности. Наверно сделаю две таблички конкретно для моих целей. Но не повредит ли это самой Джумле?





Количество пользователей, читающих эту тему: 1

0 пользователей, 1 гостей, 0 анонимных