Jump to content

[SOLVED] How to save fields on a Process page of a module?


PWaddict
 Share

Recommended Posts

Hello! I'm trying to create a Process module where the fields need to be on the custom Process page (under Setup) instead of the module screen.

Here is my code so far and the problem is that the value on the field doesn't getting saved. Any help?

<?php namespace ProcessWire;

class ProcessModuleTest extends Process {

	public static function getModuleInfo() {

		return array(
			'title' => 'My Process Module',
			'summary' => 'Setup My Process Module',
			'version' => 100,
			'page' => array(
				'name' => 'my-process-module',
				'title' => 'My Process Module',
				'parent' => 'setup',
			)
		);

	}

	public function ___execute() {
		
		$form = $this->buildForm();

		if($this->input->post('submit_save')) {
			$this->processForm($form);
			$this->session->redirect('./');
		}
		
		return $form->render();

	}

	protected function ___processForm(InputfieldForm $form) {
	
		$input = $this->wire('input');
		$form->processInput($input->post);
		$this->message($this->_('Saved!'));

	}

	protected function ___buildForm() {
		
		$modules = $this->wire()->modules;

		$form = $modules->get('InputfieldForm');
		$form->attr('id', 'ProcessModuleTest');
		$form->attr('method', 'post');
		$form->attr('action', './'); 
	
		$field = $modules->get('InputfieldText');
		$field->attr('name', 'my_text_field');
		$field->label = $this->_('My Text Field');
		$form->add($field);

		$submit = $modules->get('InputfieldSubmit');
		$submit->attr('value', $this->_('Submit'));
		$submit->attr('id+name', 'submit_save');
		$form->add($submit);
		
		return $form;

	}

}

 

Link to comment
Share on other sites

Hi @PWaddict,

You are missing any means of dealing with your data. I don't mean to be rude, but you might have misunderstood what the processInput() call does on the form. All it does is take any input provided via GET or POST and fill the form fields with this data. This allows for further processing and re-rendering the same form with the prefilled data (e.g. when there was a validation error). You can find a hint of this in InputfieldWrapper, the parent class of InputfieldForm. Specifically, take a look at it's processInput() method.

Any other action you want to take with the data provided is up to you.

As an example, the core module ProcessModule does much of the same you are doing in your module when processing config fields for modules. You can find the method which takes care of the edit form here. It builds a form, processes it's input and renders the form exactly like your module does.

But the key part is that it does something with the data, it saves it in the modules config right here after checking if there has been any changes to the data.

Process doesn't provide any automatic means "configuring the process" like a ConfigurableModule provides in my example above. This is because most Process modules deal with data present in the database by other means. You must create your own database schema and save your data there if that is what you are after.

Edited by poljpocket
  • Like 3
Link to comment
Share on other sites

22 hours ago, poljpocket said:

You must create your own database schema and save your data there if that is what you are after.

As an alternative, but which also involves some coding: you can also create fields + fieldgroup + template + a "storage" page in your module's install method. Then, in your processForm method, you can fetch that page and assign the form values there, or you just display a modal link to the page editor in your buildForm method and let PW take care of saving the values. That approach can get a bit involved (double so if you want to clean up in your uninstall method), but it can have some advantages (retaining the values after module uninstall, straight forward use of arbitrary field types).

Link to comment
Share on other sites

Thank you for the replies.

@poljpocket yep I misunderstood it indeed but I figured it out. I had to make the Process module as ConfigurableModule even with no config fields so I can save the values from my programmatically fields of buildForm() to module's database field "data" by using getConfig() and saveConfig().

Here is a full code sample:

<?php namespace ProcessWire;

class ProcessModuleTest extends Process implements ConfigModule {

	public static function getModuleInfo() {

		return array(
			'title' => 'My Process Module',
			'summary' => 'Setup My Process Module',
			'version' => 100,
			'icon' => 'cog'
		);

	}

	public function __construct() {
		parent::__construct();
		$this->set('my_text_field_1', '');
		$this->set('my_text_field_2', '');
	}

	public function ___execute() {
		
		$form = $this->buildForm();

		if($this->input->post('submit_save')) {
			$this->processForm($form);
			$this->session->redirect('./');
		}
		
		return $form->render();

	}

	protected function ___processForm(InputfieldForm $form) {
	
		$input = $this->wire('input');
		$data = $this->wire('modules')->getConfig($this);
		$form->processInput($input->post);
		
		$data['my_text_field_1'] = $form->getChildByName('my_text_field_1')->val();
		$data['my_text_field_2'] = $form->getChildByName('my_text_field_2')->val();

		if(count($form->getErrors())) return;

        $this->wire('modules')->saveConfig($this, $data);
		$this->message($this->_('Saved My Process Module Settings'));

	}

	protected function ___buildForm() {
		
		$modules = $this->wire()->modules;

		$form = $modules->get('InputfieldForm');
		$form->attr('id', 'ProcessModuleTest');
		$form->attr('method', 'post');
		$form->attr('action', './');
	
		$field = $modules->get('InputfieldText');
		$field->attr('name', 'my_text_field_1');
		$field->label = $this->_('My Text Field 1');
		$field->attr('value', $this->my_text_field_1);
		$form->add($field);

		$field = $modules->get('InputfieldText');
		$field->attr('name', 'my_text_field_2');
		$field->label = $this->_('My Text Field 2');
		$field->attr('value', $this->my_text_field_2);
		$form->add($field);

		$submit = $modules->get('InputfieldSubmit');
		$submit->attr('value', $this->_('Submit'));
		$submit->attr('id+name', 'submit_save');
		$form->add($submit);
		
		return $form;

	}

	protected function getInstalledPage() {

		$admin = $this->pages->get($this->config->adminRootPageID);
		$parent = $admin->child("name=setup");
		if(!$parent->id) $parent = $admin;
		$name = 'my-process-module';
		$page = $parent->child("name=$name");

		if(!$page->id) {
			$info = ProcessModuleTest::getModuleInfo();
			$page = new Page();
			$page->parent = $parent;
			$page->template = 'admin';
			$page->name = $name;
			$page->title = $info['title'];
			$page->icon = $info['icon'];
			$page->process = $this;
			$page->sort = $parent->numChildren;
			$page->save();
		}

		return $page;
	
	}

	public function ___install() {

		parent::___install(); // Process modules must call parent method
		$page = $this->getInstalledPage();
		$this->message(sprintf($this->_('Installed to %s'), $page->path));
		
	}

	public function ___uninstall() {

		parent::___uninstall(); // Process modules must call parent method
		$page = $this->getInstalledPage();
		if(!$page->id) return;
		$this->message(sprintf($this->_('Removed %s'), $page->path));
		$this->pages->delete($page);

	}

}

Then on the frontend I can get a field value like that:

echo $modules->getConfig('ProcessModuleTest', 'my_text_field_1');

 

Edited by PWaddict
Edited code
Link to comment
Share on other sites

  • PWaddict changed the title to [SOLVED] How to save fields on a Process page of a module?

Indeed, that is also an option.

For your exact use case, there is the ConfigModule interface. It allows you to load/save exactly as you are doing but the differenc is, you don't need the getModuleConfigInputfields() method.

I am on my phone so can't look up the code as easily.

Edit: Here you go https://github.com/processwire/processwire/blob/3cc76cc886a49313b4bfb9a1a904bd88d11b7cb7/wire/core/ConfigurableModule.php#L40

Edited by poljpocket
add link
  • Like 1
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...