Jump to content

Page cloning issue (with bespoke fieldtype)


Rob
 Share

Recommended Posts

I've upgraded to 2.2 to see what's new and one of the useful things for us is page cloning.

Unfortunately there seems to be a problem when I try to clone a page that has fields that are of a custom type I have created myself.

When I try to clone the page I get the following message "Unknown column 'url' in 'field list'" and having turned on debugging I can see that the code is trying to create a new DB record with a 'url' column which doesn't exist. My custom field uses the standard 'data' column for storing the URL and it loads and saves fine ordinarily.

Can anyone suggest if there is some extra method that I need to implement in my custom FieldType so that the clone functionality knows exactly how to clone the data?

It is worth mentioning that this is a custom FieldType and InputField that has multiple parts and is repeatable. Basically a field that holds a piece of text and a URL to represent a link, and you can add multiple sets of these links.

Thanks is advance.

p.s. upcoming repeating fields functionality looks very exciting, and very powerful., based on the video Ryan posted.

Link to comment
Share on other sites

Check to make sure that your custom Fieldtype isn't maintaining it's own $page state. Fieldtypes are a sort of module where only one copy is held in memory and different fields and pages are passed into its methods. So if your Fieldtype is keeping a copy of $page or $field somewhere beyond the scope of a function's execution, then it's taken on a state that fieldtypes aren't meant to. That could create a problem with cloning.

I'm also curious about the 'url' column you mentioned. What does your Fieldtype::getDatabaseSchema function look like? If possible, post your whole fieldtype module (or email it to me) as it's probably not possible to do anything other than suggest things to look at, without seeing the actual code.

Link to comment
Share on other sites

As requested Ryan, the code to my FieldType.

I wonder now if it's got anything to do wit hthe fact that IO am converting the data slightly (change array key) on wakeupValue() before it gets handed to the InputField, but if the two are totally separate and they only pass data back and forth, this shouldn't have anything to do with the clone.

The clone is a purely data-related operation, so should have nothing to do with display or input, correct?

class FieldtypeLinkMulti extends FieldtypeMulti {

public static function getModuleInfo() {
	return array(
		'title'	 =>  'Multiple Link Field',
		'version' => 001,
  'summary' => 'Field that stores multiple links with URL and link text'
	);
}

public function getDatabaseSchema(Field $field) {
	$schema = parent::getDatabaseSchema($field);
	$schema['data'] = "varchar(255) NOT NULL";
	$schema['text'] = "varchar(255) NOT NULL";
	return $schema;
}

public function getInputfield(Page $page, Field $field) {
	$inputfield = $this->fuel('modules')->get('InputfieldLinkMulti');
	if(!$inputfield) return null;
	return $inputfield;
}

public function ___sleepValue(Page $page, Field $field, $value) {
	return $value;
}

public function ___wakeupValue(Page $page, Field $field, $value) {
	$links = array();
	foreach($value as $link) {
		$links[] = array(
			'url'   => $link['data'],
			'text'  => $link['text']
		);
	}
	return $links;
}

public function sanitizeValue(Page $page, Field $field, $value) {
	return $value;
}

}
Link to comment
Share on other sites

Rob, the issue here is that your sleepValue has a 'url' field in each item of the $value (the one that was created from 'data' by your wakeupValue function). You'll want to have your sleepValue do the opposite of wakeupValue. So it should create a new array containing 'data' and 'text' for each record, rather than 'url' and 'text'. Then it should return that array. I would think that the way it's setup right now, there would be problems maintaining the url/data value on any page save, not just cloning. But luckily the fix here is simple.

Link to comment
Share on other sites

Thanks for the pointer Ryan.

My pages save fine, probably because I'm returning the data from the InputField with the data converted back to the right key/value pairs in the array.

I suppose in the case of a page save when the data to be saved has been set from the recently submitted InputField then it doesn't matter (because of the above point), but when the page clone takes place PW has loaded the data which alters the array keys, then gets confused when it tries to save into columns that don't exist.

Link to comment
Share on other sites

I've just realised a potential problem.

When I was first looking at this repeatable field stuff, I did a workaround to the hard-coded one-dimensional array limit that was in the code. When I upgraded to 2.2 I probably overwrote that so now the WireInputData class isn't even returning the data from the field.

I can easily just us _POST but it seems like a kludge when there is a sanitising input class in the PW core.

I didn't ever submit a pull request as I thought it'd be best to leave you (Ryan) to make the change yourself. You said at the time that if I needed multi-dimensional array support, others probably would too.

http://processwire.c...nal-arrays-why/

Is this still on the agenda?

Link to comment
Share on other sites

Definitely still on the agenda. But if you need something today, I would just use $_POST. The version that PW has ($input->post) is only normalized for PHP's magic_quotes setting, not sanitized for anything in particular. So if you are dealing with something where slashes would not be an issue (like numbers) it really doesn't matter whether you use $_POST or $input->post. My opinion is that it's never bad to keep close to the tools that PHP provides for you and that's reflected in ProcessWire. I know there are those out there that think there should be abstracted layers on top of abstracted layers on top of things like $_POST, but I am definitely not one of them. I don't believe in trying to redo or layer on top of something PHP already does well unless I need it to do something different. The closer we stick to PHP, the closer we are to the faster C++ code behind it and more familiar code is to other folks. Then again, I love PHP. But I know there are also those that would like to abstract away most of PHP, and I think that's silly. You'll occasionally see me use $_POST and $input->post interchangeably, depending on whether I'm dealing with input that may have escaped quotes.

Link to comment
Share on other sites

It's always an interesting debate regarding the relative merits of PHP. I think it's probably the easiest language to pick up and get developing with for the web, but it's hard to argue against some of the criticisms from other more "pure" OO languages like Python or Ruby. I think PHP is flawed and it has the unfortunate legacy of a procedural language that has had OO bolted on.

For that reason I'm always glad of frameworks and CMS' that have great design and best practise behind them, like Symfony2, because it makes me a better developer by standing on the shoulders of others! But I think I agree with you that there's no need to abstract everything, especially when it's something simple.

If I'm totally honest, when I look at Python I'm jealous of how clean and terse the syntax is. But It'd take me a long time to transfer all my PHP knowledge across and get up to speed! I digress...

Link to comment
Share on other sites

I think PHP is flawed and it has the unfortunate legacy of a procedural language that has had OO bolted on.

That applies to PHP4 which did actually have OO bolted on. But PHP5 is a different beast that's been built around OO. PHP4 and PHP5 are like two different languages when it comes to OO.

I can't say as though I agree of being jealous of Python (or Ruby) syntax. Nice languages, but we just didn't make a connection despite a lot of effort. Ruby especially left me tired... felt like working in a cubicle. This is my experience, but I know everyone is different. PHP is such a workhorse and seems to be the language of people who get stuff done, more than any other. Something about PHP also seems to drive creativity that the others don't. Still, it's not for everyone and thankfully there's much to choose from.

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