Jump to content

$this scope in modules


Roope
 Share

Recommended Posts

Hello all!

I have a little problem with my custom csv importer module. There is public array available for field names and types that I use for looping:

public $fieldTypes = array(
	'product_number' => 'string', 
	'product_group' => 'page', 
	'product_family' => 'page'
);

Then later I have setter, that takes Page as first parameter. Here problem is that I would need to acces $fieldTypes array but when dealing with pages, $this seems to reference to Page and breaks my code:

protected function setValue(Page $page, $name, $value) { 
	// here I receive warning for Undefined offset
	// since $this is referencing to Page
	if ($this->fieldTypes[$name] == 'page') {
		$page->set($name, explode(',', $value));
	}
}

How could I have acces to $fieldTypes array in setValue method?

Link to comment
Share on other sites

$this always refers to the class , which is your module (e.g. instance of WireData / Process...).

Are your sure that $name holds a string of your 3 keys?

if (!isset($this->fieldTypes[$name])) die("Bad bad $name, this key does not exist in my array!");
Link to comment
Share on other sites

OK, thanks Wanze!

I actually had error in my loop. I was passing numerical key as $type. I didn't even think about it since I got titles imported just fine.

@kongondo

Yes, thats true when working with functions, but this is method from importer module - just copy-pasted two pieces for example. We're using Ryans CSV Importer as base for this module but it's gonna be simpler cause we don't need any options and it should be simple enough fo everyday use for our customer.

Link to comment
Share on other sites

There's just one I don't understand here: when $this refers always to module itself, how can this work in Ryans CSV Importer:

protected function modifyPage(Page $page, array $fieldNames) {

	$p = $this->parent->child("name={$page->name}, include=all"); 
	$id = $p->id; 

	...
}

How can you get that $p under module parent->child?

So just out of curiosity I tried in my module:

die(var_dump($this->parent->name));

And got: Notice: Trying to get property of non-object.

Link to comment
Share on other sites

You're welcome Roope.

In ryans module, parent is an instance variable of the module. That's why he can refer to $this->parent.

See here:

/**
* Instance of Page, representing the parent Page for imported pages
*
*/
protected $parent = null;

// Later in code...
$this->parent = $this->pages->get($this->session->csvParent); 
Link to comment
Share on other sites

OK, I didn't noticed that $parent was set as variable there. Thanks for support Wance!

Speaking about Ryans CSV Importer, there's also var $pageName that's used inside importPage() method but I don't see it defined anywhere?

protected function importPage(array $data, InputfieldForm $form) {

	...

	if(!$page->id) { 

		if($this->session->csvDuplicate == self::csvDuplicateNew) {
			$page->name = $this->getUniquePageName($pageName); // here
			$page = $this->savePage($page);

		} else if($this->session->csvDuplicate == self::csvDuplicateModify) { 
			$page = $this->modifyPage($page, $fieldNames); 
			
		} else {
			$this->message("Skipping row with duplicate name '$pageName'"); // and here
		}
	}

	...

}
Link to comment
Share on other sites

I think you found a bug, that variable is nowhere defined. It won't really show up unless a duplicate is found and it would at max throw a warning, but still works. 

Link to comment
Share on other sites

True that. Looks like peole can organize their csv files decently since this hasn't pop up before ;)

My importer is about ready and it has quite similar functions than in Ryans. There's one oddity though: when modifying existing page, my module complained about not setting $page->setOutputFormatting(false). Still it's not needed in Ryans module either. Functions are almost identical:

/**
 * Modify an existing page with CSV data
 */
protected function modifyPage(Page $page, $data, $fields) {

	$p = $this->parent->child("name={$page->name}, include=all"); 
	$id = $p->id; 

	if(!$id) {
		$this->error("Unable to load {$this->parent->path}{$page->name}/ for modification."); 
		return false;
	}

	if($p->template != $page->template) {
		$this->error("Unable to modify '{$p->name}' because it uses a different template '{$p->template}'"); 
		return false;
	}
	
	$p->setOutputFormatting(false); 
	
	foreach ($fields as $key => $field) {
		$value = $data[$key]; 
		$this->setValue($p, $field, $value); 
	}

	return $this->savePage($p);
}

Is there any problem like this - shoud I set output formatting back to false?

Link to comment
Share on other sites

I've used Ryans CSV Importer couple of times when migrating MODX sites to PW and more than once noticed that all reported rows are not actually imported. My module does this also. I have 4210 rows of data in my csv and receive no errors during import. Counter confirms 4210 rows. But when I look to the parent folder in admin I see there's only 4187 pages inside.

Maybe I should raise this question in ImportPagesCSV thread instead or am I missing something here? Again, functions are almost identical, at leat the part where errors are set:

if (!$page->name) {
	if (!empty($pageName)) {
		$this->error("Unable to import product '{$pageName}'. It has no required 'title' field or it is blank."); 
	} else {
		$this->error("Unable to import product. It has no required 'product_number' field or it is blank."); 
	}
	return false;
}

$page = $this->savePage($page, false);

if (!$page->id) { 
	
	if ($this->options['csvDuplicate'] == 'new') {
		$page->name = $this->getUniquePageName($pageName); 
		$page = $this->savePage($page);

	} else if($this->options['csvDuplicate'] == 'modify') { 
		$page = $this->modifyPage($page, $data, $fields); 
		
	} else {
		$this->message("Skipping row with duplicate product number '{$pageName}'"); 
	}
}

I also print out success messages as rows in ordered list and after import, the last number in list is 4210. Wtf! What happend to those 13 pages?

Link to comment
Share on other sites

I also print out success messages as rows in ordered list and after import, the last number in list is 4210. Wtf! What happend to those 13 pages?

Chances are there were duplicate rows. Check what column you are assigning to your 'name' field of the page and see if there are any duplicates in your CSV. If the CSV import module comes across the same one, it'll attempt to update the existing one already there rather than add a new one. 

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