Jump to content

Import CSV to Repeating Field within a Repeating Field


SoccerGuy3
 Share

Recommended Posts

I am trying to import data to a repeating field. Searching these forums have lead me to various solutions and I think I have a decent grasp of that aspect of what I need to do. Where I am stuck is that the repeater I am importing into is actually a repeater WITHIN another repeater on a page. Looking for some help or direction to get me unstuck. Here's a sample of what I am working with (simplified):

Large Images (page)
	Group Name (Repeater)
		Photo (Repeater)
			Image (um, image field)
			Image Name (text)
			Price (text)

Data looks like (one row): Group, image name, price

So the big question is how to create the outer repeater and then the sub-repeaters. Can it be done? I could manually create the outer repeaters (there are only like 10-15 of them) if that makes it easier, but then, how to address the repeater inside for the import?

Any suggestions (or code samples) welcome. Thanks in advance,

Marc

Link to comment
Share on other sites

15 hours ago, SoccerGuy3 said:

So the big question is how to create the outer repeater and then the sub-repeaters. Can it be done?

Yes, it can be done. The documentation for the Repeater fieldtype shows API code for adding repeater items.

The general approach is that for every row you will look for a "group" repeater item by title and if no item matches that group name you create one. And for every row you create a "photo" repeater item inside the relevant group item.

15 hours ago, SoccerGuy3 said:

Data looks like (one row): Group, image name, price

Not tested but it should work once you have changed $page and any field names to suit your setup:

// Parse the CSV data
$handle = fopen('/path/to/your/file.csv', 'r');
while(($row = fgetcsv($handle)) !== false) {

    // Columns (maybe there are actually more of these)
    list($group_name, $image_name, $price) = $row;

    // Get the group item for this $group_name
    /* @var RepeaterPage $group_item */
    $group_item = $page->groups->get("title=$group_name");
    // If no such item exists, create one
    if(!$group_item->id) {
        $group_item = $page->groups->getNew();
        $group_item->title = $group_name;
        $group_item->save();
        $page->groups->add($group_item);
        $page->save();
    }

    // Create a photo item for this row
    /* @var RepeaterPage $photo_item */
    $photo_item = $group_item->photos->getNew();
    $photo_item->title = $image_name;
    $photo_item->price = $price;
    // If there are more columns deal with them here
    $photo_item->save();
    $group_item->photos->add($photo_item);
    $group_item->save();

    // Perhaps not needed, but save the page for good luck
    $page->save();

}

 

  • Like 2
Link to comment
Share on other sites

Making some progress on this. Two issues:

1) It only runs through the loop once and then errors: 

Error: Uncaught Error: Call to a member function getNewItem() on null in /Library/WebServer/Documents/edwardscurtis/_site/site/templates/page-portfolio-import.php:27
Stack trace:
#0 /Library/WebServer/Documents/edwardscurtis/_site/wire/core/TemplateFile.php(287): require()
#1 /Library/WebServer/Documents/edwardscurtis/_site/wire/core/Wire.php(380): ProcessWire\TemplateFile->___render()
#2 /Library/WebServer/Documents/edwardscurtis/_site/wire/core/WireHooks.php(723): ProcessWire\Wire->_callMethod('___render', Array)
#3 /Library/WebServer/Documents/edwardscurtis/_site/wire/core/Wire.php(442): ProcessWire\WireHooks->runHooks(Object(ProcessWire\TemplateFile), 'render', Array)
#4 /Library/WebServer/Documents/edwardscurtis/_site/wire/modules/PageRender.module(514): ProcessWire\Wire->__call('render', Array)
#5 /Library/WebServer/Documents/edwardscurtis/_site/wire/core/Wire.php(383): ProcessWire\PageRender->___renderPage(Object(ProcessWire\HookEvent))
#6 /Library/WebServer/Documents/edwardscurtis/_site/wire/core/WireHooks.p (line 27 of /Library/WebServer/Documents/edwardscurtis/_site/site/templates/page-portfolio-import.php) 

2) If I put in the ->save commands in your original code, then I get this error: 

Error: Exception: Can’t save page 10368: /prints/large-prints/: Call $page->of(false); before getting/setting values that will be modified and saved. [portfolio_repeater] (in /Library/WebServer/Documents/edwardscurtis/_site/wire/core/PagesEditor.php line 515)

#0 /Library/WebServer/Documents/edwardscurtis/_site/wire/core/Pages.php(411): ProcessWire\PagesEditor->save(Object(ProcessWire\Page), Array)
#1 /Library/WebServer/Documents/edwardscurtis/_site/wire/core/Wire.php(386): ProcessWire\Pages->___save(Object(ProcessWire\Page), Array)
#2 /Library/WebServer/Documents/edwardscurtis/_site/wire/core/WireHooks.php(723): ProcessWire\Wire->_callMethod('___save', Array)
#3 /Library/WebServer/Documents/edwardscurtis/_site/wire/core/Wire.php(442): ProcessWire\WireHooks->runHooks(Object(ProcessWire\Pages), 'save', Array)
#4 /Library/WebServer/Documents/edwardscurtis/_site/wire/core/Page.php(2409): ProcessWire\Wire->__call('save', Array)
#5 /Library/WebServer/Documents/edwardscurtis/_site/site/templates/page-portfolio-import.ph

Here's my current code, what am I missing?

	// Parse the CSV data
	$handle = fopen('data/inventorylist.csv', 'r') or die('Cannot open file.');

	$prevportname = '';

	while(($row = fgetcsv($handle)) !== false) {

	    list($port_name, $port_num, $plate_num, $plate_name, $year, $price) = $row;

	    // Get the portfolio name for this $group_name
	    /* @var RepeaterPage $group_item */
	    $group_item = $page->portfolio_repeater->get("text=$port_name");
	    // If no such item exists, create one

	    if($prevportname != $port_name) {
	        $group_item = $page->portfolio_repeater->getNewItem();
	        $group_item->text = $port_name;
	        $group_item->save();
	        $page->portfolio_repeater->add($group_item);
	        $page->save();
	    }

	    // Create a photo item for this row
	    /* @var RepeaterPage $photo_item */
	    $photo_item = $group_item->print_info->getNewItem();
	    $photo_item->title = $plate_name;
	    $photo_item->port_name = $port_name;
	    $photo_item->port_num = $port_num;
	    $photo_item->plate_num = $plate_num;
	    $photo_item->print_year = $year;
	    $photo_item->print_price = $price;
	    // If there are more columns deal with them here
	    $photo_item->save();
	    $group_item->print_info->add($photo_item);
	    $group_item->save();

	    $prevportname = $port_name;
	}

 

Link to comment
Share on other sites

GOT IT!! 🙂

See the commented out "save" on the fourth to last line of code. That was the ticket.

	// Parse the CSV data
	$handle = fopen('data/inventorylist.csv', 'r') or die('Cannot open file.');

	$prevportname = '';

	while(($row = fgetcsv($handle)) !== false) {

	    list($port_name, $port_num, $plate_num, $plate_name, $year, $price) = $row;

	    // Get the portfolio name for this $group_name
	    $group_item = $page->portfolio_repeater->get("port_num=$port_num");
	    // If no such item exists, create one
	    if(!$group_item) {
	        $group_item = $page->portfolio_repeater->getNewItem();
	        $group_item->text = $port_name;
	        $group_item->port_num = $port_num;
	        $group_item->save();
	        $page->portfolio_repeater->add($group_item);
	    }

	    // Create a photo item for this row
	    $photo_item = $group_item->print_info->getNewItem();
	    $photo_item->title = $plate_name;
	    $photo_item->port_name = $port_name;
	    $photo_item->port_num = $port_num;
	    $photo_item->plate_num = $plate_num;
	    $photo_item->print_year = $year;
	    $photo_item->print_price = $price;
//	    $photo_item->save();
	    $group_item->print_info->add($photo_item);
	    $group_item->save();
	}

 

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