Jump to content

AdminModuleController - Update et New


Recommended Posts

Bonjour,

j'essaie via quelques infos retrouvées sur le net de mettre en place une interface d'administration pour un module sous Prestashop 1.5.6. 

 

Je suis parti de l'excellent tuto de prestaedit (http://www.prestaedit.com/tutoriels/2-canvas-de-module-pour-prestashop-15.html ) et de développements précédents réalisés pour PS 1.4.

 

Mon module est chargé d'afficher un ticker de news à partir d'une liste gérée dans l'administration.

 

J'ai réussi à

  • faire tourner le module en front
  • créer le tabs admin pour le module
  • créer la liste des news (ainsi que les boutons d'actions)

Mon problème est lié au CRUD, puisque je n'arrive pas à  :

  • faire l'update d'un élément, car le formulaire ne reprends pas les valeurs malgré que l'ID de l'élément soit correct dans l'URL d'appel  (index.php?controller=AdminNewsticker&id_news_ticker=1&updatenews_ticker) ???
  • mon champs "text" ne semble pas non plus prendre la valeur du champs après la soumission lors de la création d'un nouvel élément

 

Je vous mets ci-dessous le modèle de l'objet : 

/modules/newsticker/models/NewsTickerData.php

<?php

class NewsTickerData extends ObjectModel{
	
	
	public $id_news;
	public $text;
	public $url;
	public $date_up;
	public $date_down;
	
	public static $definition = array(
			'table' => 'news_ticker',
			'primary' => 'id_news_ticker',
			'multilang' => false,
			
			'fields' => array( 
					'id_news_ticker' => array(
							'type' => self::TYPE_INT,
							),
					'text' => array(
							'type' => self::TYPE_HTML
							),
					'url' =>  array(
							'type' => self::TYPE_STRING,
							'size' =>150
							),
					'date_up' =>  array(
							'type' => self::TYPE_DATE
							),
					'date_down' =>  array(
							'type' => self::TYPE_DATE
							),
					),
			
			
			);
}

Puis le contrôleur (/modules/newsticker/controllers/admin/AdminNewstickerController.php

<?php

class AdminNewstickerController extends ModuleAdminController {

	public function __construct(){
		
		$this->table = 'news_ticker';
		$this->className = 'NewsTicker';
		$this->lang = false;
		$this->edit = true;
		$this->view = false;
		$this->delete = true;
		$this->deleted = false;
		$this->requiredDatabase = false;
		
		$this->fields_list = array(
				'id_news_ticker' => array('title' => $this->l('ID'), 'align' => 'center', 'width' => 25),
				'text' => array('title' => $this->l('Texte'), 'width' => 80),
				'url' => array('title' => $this->l('Lien'), 'width' => 80),
				'date_up' => array('title' => $this->l('Publié le'), 'width' => 30, 'type' => 'date', 'align' => 'right'),
				'date_down' => array('title' => $this->l('Expire le'), 'width' => 30, 'type' => 'date', 'align' => 'right'),
		);
		
	//	$this->identifier = 'id_news';
	//	$this->actions = array('create','edit','update','delete');
		parent::__construct();
	}
	/*
	public function displayForm($isMainTab = true){
		global $currentIndex;
		parent::displayForm();
	
		if (!($obj = $this->loadObject(true)))			return;
	
		Tools::addJs(_PS_JS_DIR_.'jquery/jquery-ui-1.8.10.custom.min.js');
	
		$myForm .= '
		<script type="text/javascript" src="'._PS_JS_DIR_.'jquery/jquery-ui-1.8.10.custom.min.js"></script>
		<script type="text/javascript" src="'._PS_JS_DIR_.'jquery/datepicker/ui/i18n/ui.datepicker-fr.js"></script>
	
		<script>
		$(function() {
		$( "#date_up" ).datepicker({
		prevText:"",
		nextText:"",
		dateFormat:"yy-mm-dd"
	});
	$( "#date_down" ).datepicker({
	prevText:"",
	nextText:"",
	dateFormat:"yy-mm-dd"
	});
	});
	</script>';
	
	
		$myForm .='<form method="post" action="'.$currentIndex.'&submitAdd'.$this->table.'=1&token='.$this->token.'">';
		$myForm .= ($obj->id_news ? '<input type="hidden" name="id_news" value="'.$obj->id_news.'" />' : '');
	
		$myForm .='<div>';
		$myForm .='<label>'.$this->l('Texte').'</label>';
		$myForm .='<input type="text" size="50" name="text" id="text" value="'.$obj->text.'" />';
		$myForm .='</div>';
	
		$myForm .='<div>';
		$myForm .='<label>'.$this->l('Lien').'</label>';
		$myForm .='<input type="text" size="50" name="url" id="url" value="'.$obj->url.'" />';
		$myForm .='</div>';
	
		$myForm .='<div>';
		$myForm .='<label>'.$this->l('Date de publication').'</label>';
		$myForm .='<input type="text" id="date_up" name="date_up" value="'.$obj->date_up.'" />';
		$myForm .='</div>';
	
		$myForm .='<div>';
		$myForm .='<label>'.$this->l('Date d\'expiration').'</label>';
		$myForm .='<input type="text" id="date_down" name="date_down" value="'.$obj->date_down.'" />';
		$myForm .='</div>';
	
		$myForm .= '<input type="submit" value="'.$this->l('Envoyer').'">';
	
		$myForm .= '</form>';
	
	
		echo $myForm;
	
	}
	*/
	
	/**
	 * Function used to render the list to display for this controller
	 */
	public function renderList()
	{
		$this->addRowAction('edit');
		$this->addRowAction('delete');
		$this->addRowAction('details');
	
		$this->bulk_actions = array(
				'delete' => array(
						'text' => $this->l('Delete selected'),
						'confirm' => $this->l('Delete selected items?')
				)
		);
	
		$this->fields_list = array(
				'id_news_ticker' => array(
						'title' => $this->l('ID'),
						'align' => 'center',
						'width' => 25
				),
				'text' => array(
						'title' => $this->l('Text'),
						'width' => 'auto',
				),
				'url' => array(
						'title' => $this->l('Url'),
						'width' => 'auto',
				),
				'date_up' => array(
						'title' => $this->l('Date Up'),
						'width' => 'auto',
				),
				'date_down' => array(
						'title' => $this->l('Date Down'),
						'width' => 'auto',
				),
				
		);
	
		$lists = parent::renderList();
	
		parent::initToolbar();
	
		return $lists;
	}
	
	/**
	 * method call when ajax request is made with the details row action
	 * @see AdminController::postProcess()
	 */
	public function ajaxProcessDetails()
	{
		if (($id = Tools::getValue('id')))
		{
			// override attributes
			$this->display = 'list';
			$this->lang = false;
	
			$this->addRowAction('edit');
			$this->addRowAction('delete');
	
			$this->_select = 'b.*';
			$this->_join = 'LEFT JOIN `'._DB_PREFIX_.'tab_lang` b ON (b.`id_tab` = a.`id_tab` AND b.`id_lang` = '.$this->context->language->id.')';
			$this->_where = 'AND a.`id_parent` = '.(int)$id;
			$this->_orderBy = 'position';
	
			// get list and force no limit clause in the request
			$this->getList($this->context->language->id);
			
			// Render list
			$helper = new HelperList();
			$helper->actions = $this->actions;
			$helper->list_skip_actions = $this->list_skip_actions;
			$helper->no_link = true;
			$helper->shopLinkType = '';
			$helper->identifier = $this->identifier;
			$helper->imageType = $this->imageType;
			$helper->toolbar_scroll = false;
			$helper->show_toolbar = false;
			$helper->orderBy = 'id_news_ticker';
			$helper->orderWay = 'DESC';
			$helper->currentIndex = self::$currentIndex;
			$helper->token = $this->token;
			$helper->table = $this->table;
			$helper->position_identifier = $this->position_identifier;
			// Force render - no filter, form, js, sorting ...
			$helper->simple_header = true;
			$content = $helper->generateList($this->_list, $this->fields_list);
	
			echo Tools::jsonEncode(array('use_parent_structure' => false, 'data' => $content));
		}
	
		die;
	}
	
	public function renderForm()
	{
		$this->fields_form = array(
				'tinymce' => true,
				'legend' => array(
						'title' => $this->l('News Ticker'),
						'image' => '../img/admin/cog.gif'
				),
				'input' => array(
						array(
								'type' => 'text',
								'lang' => true,
								'label' => $this->l('Text:'),
								'name' => 'text',
								'size' => 250
						),
						array(
								'type' => 'text',
								'label' => $this->l('Url:'),
								'name' => 'url',
								'readonly' => false,
								'disabled' => false,
								'size' => 250
						),
						array(
								'type' => 'date',
								'name' => 'date_up',
								'label'=> $this->l('DateUp:')
						),
						array(
								'type' => 'date',
								'name' => 'date_down',
								'label'=> $this->l('DateDown:')
						)
				),
				'submit' => array(
						'title' => $this->l('Save'),
						'class' => 'button'
				)
		);
	
		if (!($obj = $this->loadObject(true)))
			return;
		
		
			
	//	$this->fields_value = array('lorem' => "ipsum");
	
		return parent::renderForm();
	}
	
	public function postProcess()
	{
		if (Tools::isSubmit('submitAdd'.$this->table))
		{
			// Create Object ExampleData
			$obj = new NewsTickerData();
			// Copy From Post
			$this->copyFromPost($obj, 'news_ticker');
			// Save object
			if (!$obj->save())
				$this->errors[] = Tools::displayError('An error has occurred: Can\'t save the current object');
			else
				Tools::redirectAdmin(self::$currentIndex.'&conf=4&token='.$this->token);
		}
	}
}

Link to comment
Share on other sites

  • 2 weeks later...

Bonjour 

un petit UP !

 

j'avance un peu en creusant du côté du CORE.

Dans la class AdminController.php, j'ai fait un var_dump de l'objet chargé avec la méthode loadObject(), et là je me rends compte qu'il ne charge pas les field_values !...

ce qui explique pourquoi mon formulaire de mise à jour est vide (hormis l'ID qu'il charge en variable GET)

 

Donc si je comprends bien, il ne charge pas les valeurs POST (copyFromPost ????)

Edited by EmmanuelTesson (see edit history)
Link to comment
Share on other sites

Bonjour,

 

A mon avis le soucis est le copyFromPost, c'est une méthode généralement utilisée dans le modèle, le but étant de le remplir l'objet utilisant les fonctions de l'ORM avant de save.

 

Si je reprends le code de ton Controller, là ce que tu fais dans le postProcess :

 

- Création de l'objet NewsTickerData

- Alimentation de l'objet $this (= instance de AdminNewstickerController) avec les donnée du post (au passage elle existe la méthode copyFromPost, je ne la vois nulle part dans ce que tu as copié)

- Sauvegarde de l'objet NewsTickerData

 



//Create Object NewsTickerData
$obj = new NewsTickerData();

// Feed with post values
$obj->copyFromPost();

// Save object
if (!$obj->save())
    $this->errors[] = Tools::displayError('An error has occurred: Can\'t save the current object');
else
    Tools::redirectAdmin(self::$currentIndex.'&conf=4&token='.$this->token);

Ps : Le module éditorial utilise cette méthode. Edited by Whoami (see edit history)
Link to comment
Share on other sites

Bonjour,

 

A mon avis le soucis est le copyFromPost, c'est une méthode généralement utilisée dans le modèle, le but étant de le remplir l'objet utilisant les fonctions de l'ORM avant de save.

 

Si je reprends le code de ton Controller, là ce que tu fais dans le postProcess :

 

- Création de l'objet NewsTickerData

- Alimentation de l'objet $this (= instance de AdminNewstickerController) avec les donnée du post (au passage elle existe la méthode copyFromPost, je ne la vois nulle part dans ce que tu as copié)

- Sauvegarde de l'objet NewsTickerData

 

//Create Object NewsTickerData
$obj = new NewsTickerData();

// Feed with post values
$obj->copyFromPost();

// Save object
if (!$obj->save())
    $this->errors[] = Tools::displayError('An error has occurred: Can\'t save the current object');
else
    Tools::redirectAdmin(self::$currentIndex.'&conf=4&token='.$this->token);

Ps : Le module éditorial utilise cette méthode.

 

 

Bonjour

tout d'abord merci pour le coup de main !!

le module éditorial ne comporte pas de contrôleur ? 

De plus il me semblait que cette méthode (postProcess) ne servait que pour le "paramétrage" du module.

je cherche à avoir une tab dans l'administration et utiliser le CRUD normalement disponible.

 

 

J'ai modifié mon contrôleur pour conserver uniquement l'utilisable. Mais malgré cette "simplification" (je me suis basé sur les contrôleurs AdminAdressesController et AdminContactsController), les champs dans la vue "Update" sont toujours désespéremment vide...

<?php

class AdminNewstickerController extends ModuleAdminController {

	public function __construct(){
		
		$this->table = 'news_ticker';
		$this->className = 'NewsTicker';
		
		$this->lang = false;
		$this->requiredDatabase = true;
		$this->addRowAction('edit');
		$this->addRowAction('delete');
			
		$this->bulk_actions = array('delete' => array('text' => $this->l('Delete selected'), 'confirm' => $this->l('Delete selected items?')));
		$this->context = Context::getContext();
		
		$this->fields_list = array(
		'id_news_ticker' => array(
				'title' => $this->l('ID'),
				'align' => 'center',
				'width' => 25
				),
		'text' => array(
				'title' => $this->l('Text'),
				'width' => 'auto',
				),
		'url' => array(
				'title' => $this->l('Url'),
				'width' => 'auto',
				),
		'date_up' => array(
				'title' => $this->l('Date Up'),
				'width' => 'auto',
				),
		'date_down' => array(
				'title' => $this->l('Date Down'),
				'width' => 'auto',
				),
		
		);
		
		parent::__construct();
	}
	
	
	
	public function renderForm()
	{
		$this->fields_form = array(
			'legend' => array(
				'title' => $this->l('News Ticker'),
				'image' => '../img/admin/cog.gif'
				),
			'input' => array(
				array(
					'type' => 'text',
					'label' => $this->l('ID:'),
					'name' => 'id_news_ticker',
					'readonly' => true,
						),
					array(
					'type' => 'text',
					'label' => $this->l('Text:'),
					'name' => 'text',
						),
					array(
					'type' => 'text',
					'label' => $this->l('Url:'),
					'name' => 'url',
					),
					array(
					'type' => 'date',
					'name' => 'date_up',
					'label'=> $this->l('DateUp:')
					),
					array(
					'type' => 'date',
					'name' => 'date_down',
					'label'=> $this->l('DateDown:')
						),
				),
				'submit' => array(
						'title' => $this->l('Save'),
						'class' => 'button'
				)
		);
	
		return parent::renderForm();
	
	} 
Edited by EmmanuelTesson (see edit history)
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...