Jump to content

Unusual behavior when saving pages


zoaked
 Share

Recommended Posts

First of all, I am somewhat new to processwire so forgive me if I don't explain things quite right...  The actual requirement is more involved so I have attempted to simplify things down to a basic proof-of-concept starting point.

For my current project we want to make an audit trail of all the changes made to any page that is using a given template. (say "company" as an example)  The easy part was making the company template and its pages.  So far I have made an audit template with a text field (let's call it "action") and a text area field. ("summary")  Action is used to know what kind of action was being taken (created, saved, trashed, restore, etc) and summary holds a string version of the changes array as provided by the Page class.  By default, the changes array only holds the names of the fields that have been changed and not the values.  To get around this, we enabled advanced mode in the site config file ($config->advanced = true;) and set a custom class name ("PageWithHistory" - complete code is included below for reference) in the System tab of the company template. (viewing page settings confirms that it detects this change and was able to locate the class)  Then we created a hook in the init file to intercept things as they are being saved.  This works fine for changes to any of the company fields except one.  When changes are made to the page reference field via the admin backend UI, the audit page is silently created and saved successfully and the company page gives a notice at the top of the screen that the company was saved successfully too.  The issue that has shown up is that even though the company says it was saved successfully, the changes that were being made were not actually saved.  There are no new entries in any of the log files so I don't think an error is occurring.  If the last line of the hook (audit save) is commented out then the problem goes away and company is able to be saved once more.

Over the last few days we have performed several troubleshooting steps to try to narrow down what the issue could be:

  • Uninstalled all site modules
  • Removed all other logic from init and ready files
  • Moved hook and function from init to ready
  • Switched which method is being hooked (from before saveReady to before save, for example)
  • Renamed troublesome field
  • Changed the which template the field is filtering on
  • Changed from ASM select to checkboxes
  • Tested adding audit trail to a different template and its page reference no longer actually saves

 

One interesting twist is that I have a separate, local, installation of a brand new processwire site and this code works fine there.  They are both running the same version (latest stable) and have the same template configurations.  There is one big difference in their setups in that a starting profile was imported during the configuration of our dev site and my local site is a clean copy without that profile.  I wouldn't think that would matter at this point as the modules it included have been uninstalled and the other items (such as fields & templates) are not involved.  Does anyone have any thoughts on what the issue might be or how to go about troubleshooting this further?

 

<?php namespace ProcessWire;
$wire->addHookBefore('Pages::saveReady', 'actionManager');

function actionManager(HookEvent $event) {
	$page = $event->arguments('page');
	$template = $page->template->name;
	// check what kind of page is being saved and if anything has actually changed
	if($template !== 'company' || !$page->isChanged()) {
		// don't record these changes
		return;
	}
	
	$audit = wire(new Page());
	$audit->template = 'audit';
	$audit->of(false);
	$audit->name = $page->name.'-'.microtime();
	$audit->action = $event->method;
	$audit->parent = $event->pages->get('/audit/');
	// this line is a simple way to convert the changes array to a string during testing - more will be needed prior to release
	$audit->summary = json_encode($page->getChanges(true), JSON_FORCE_OBJECT);
	$audit->save();
}

 

<?php namespace ProcessWire;
/**
 * Thin wrapper around the built-in class that enables tracking
 * changed values in addition to the default of just tracking the keys
 */
class PageWithHistory extends Page {
	/**
	 * {@inheritDoc}
	 * @see \ProcessWire\Page::__construct()
	 */
	public function __construct(Template $tpl = null) {
		parent::__construct($tpl);
		// turn on tracking changes - this is default, but do it anyway to be sure
		$this->setTrackChanges(Wire::trackChangesOn);
		// enable storing of values too
		$this->setTrackChanges(Wire::trackChangesValues);
	}
}

 

  • Like 1
Link to comment
Share on other sites

@zoaked and I are working on this project together. There is one other important quirk that I don't think was mentioned above, and that is that the only fields that are not being saved when the hook is in place are Page fields (FieldtypePage). It does not matter which Inputfield type (asmselect, checkboxes, etc.) the Page field is using.

So, to very broadly summarize:

  1. Page 1 is saved
  2. Hook before Pages::saveReady() is fired
  3. New page (Page 2) is created and saved inside the hook (there is a template check to prevent recursion)
  4. Hook finishes and the save on Page 1 is allowed to complete

Page 2 is created as expected, no problem. The unexpected result is that any changes made to any FieldtypePage fields on Page 1 are not saved. All other field types (text inputs, at least) save correctly. If the hook is removed, Page 1 saves everything correctly again.

I have tested this on another one of our sites which uses the same site profile (our own custom profile we have created) and the same issue is present.

I can also confirm zoaked's finding that the issue is not present on a fresh ProcessWire installation using the Minimal Site Profile.

Could this be caused by some sort of database difference between a fresh install and an older profile which has undergone a few upgrades? We are on the verge of having to start from scratch on this project.

  • Like 1
Link to comment
Share on other sites

No ideas about the cause of this issue sorry.

8 hours ago, thetuningspoon said:

We are on the verge of having to start from scratch on this project.

This may not be as bad as it sounds.

  • Export/import fields via core feature
  • Export/import templates via core feature
  • Export/import modules and module settings via Module Toolkit
  • Copy PHP files: templates, config, ready, etc
  • Here's where it gets a bit experimental: Export/import pages via new core feature. @horst has had some success with it.
  • Like 1
Link to comment
Share on other sites

  • 4 months later...

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...