Jump to content

remove all repeater items and add new items


Vinnie
 Share

Recommended Posts

Hi everyone! 

I'm using the api to remove my old repeater items and add new ones.
It uses a reapeater where one of the fields is also a repeater, a repeater thats holds dates, and in the dates a repeater that holds times.
For this im using the following code:
 

// foreach ($movieInfo as $movie) {
        $p = $this->pages->get("template=film,title=" . $this->sanitizer->selectorValue($movieInfo[1]->title));
        $p->of(false);

        //create a new page if it doesn't exist yet
        if (!$p->id) {
            $p = new ProcessWire\Page();

            $p->template = 'film';
            $p->parent = $this->pages->get('template=films');
            $p->title = $movieInfo[1]->title;


            echo "created page: " . $p->title . "<br>";
            $p->save();
        }
        //remove all the old data
        if (!is_null($p->film_days)) {
            if (!is_null($p->film_days->film_times)) {
                $p->film_days->film_times->removeAll();
                $p->save();
            }


            $p->film_days->removeAll();
            $p->save();
        }

        // die;

        //add the new data
        if (!is_null($movieInfo[1]->shows)) {
            foreach ($movieInfo[1]->shows as $date => $show) {
                $repeaterDay = $p->film_days->getNew();
                $repeaterDay->film_day = $date;
                $repeaterDay->save();
                foreach ($movieInfo[1]->shows[$date] as $time) {
                    $repeaterTime = $repeaterDay->film_times->getNew();
                    $repeaterTime->film_time = $time->startTime;
                    $repeaterTime->save();
                }
            }
        }
        echo "edited page: " . $p->title . "<br>";
        $p->save();


        // }

 

This works fine on a fresh database, my movies have several dates with several times added, but when the script is run again, (and the remove code comes into action) I get the following error:
Can’t save page 0: /1543400391-5324-2/: It has no parent assigned.

The thing i dont understand i when u uncomment that die in the middle, run the code, all items are deleted correctly, when i then comment it and run the script agian it runs without errors.

Does anyone know why this cant be run in 1 go? I suspect something with cache or temporary pages the repeater adds, but cant seem t find anything

Hope you guys can help!
Vincent van Wijk

Link to comment
Share on other sites

completly OT, but are you sure that this concept, a repeater in a repaeter in a repeater, is a good way to go?

At least the (starting ?) times could be handled by page references, I think. Not knowing anything of your data, but A day can have max 24 hours and each a max of 60 minutes, results in 2 pagereference fields or two option fields. And maybe if you can work with a more limited amount of (starting ?) times, you only need one field with a list of fix / predefined times.

And to your question:

1 hour ago, Vinnie said:

Can’t save page 0:

Debug your code by inspecting why your page 0 has no parent page, starting by inspecting what template it is assigned to. This way you will find where your logic is not practicable and need to be changed.

Edited by horst
  • Like 1
Link to comment
Share on other sites

Hi @horst, thank for your reply.

It's only 2 repeaters ? , 1 for dates, and inside 1 for times.
It's for a movie theater so they can set viewing dates/times for different movies.
So to clarify:  movie page -> date-repeater -> time-repeater.
 

But the strange thing is that on a fresh db, everything works as it should.
It is only when the script is run for the second time, and the data needs to be deleted first, that i get the no parent error   (if (!is_null($p->film_days)) .
The error happens on the line with:  $repeaterTime->save();

However when i place a die() after the code that removes the items, all data is deleted from the database, en when editing the page, the repeaters are empty.
When i then run the script normally again, no errors are thrown.
 

So it seems to only generate errors when both the deleting of items, and the adding of items, happens in the same request.

Link to comment
Share on other sites

16 minutes ago, flydev said:

Sorry for the short answer, i am on mobile. Shouldn't be :  $repeaterDay->save('film_times'); ? 

Hi, @flydev i already tried that, i get the same results, also if i just call $p->save() every time.
the weird thing is still that it works on fresh database, so the removing code must have something to do with it

Link to comment
Share on other sites

2 hours ago, Vinnie said:

To confirm my suspicions i seperated to delete snippet into a different file, and when i run that script first, and then the script to add the data it always works with no errors, so why cant this happen in a single request? 

Am I right in assuming that a call to $pages->uncacheAll() between the two parts makes it work?

  • Like 1
Link to comment
Share on other sites

This part doesn't look quite right for a couple of reasons...

10 hours ago, Vinnie said:

//remove all the old data
if (!is_null($p->film_days)) {
	if (!is_null($p->film_days->film_times)) {
		$p->film_days->film_times->removeAll();
		$p->save();
	}
	
    $p->film_days->removeAll();
    $p->save();
}

 

Firstly, the value of a repeater field is a PageArray even if the field is empty, so is_null() is never going to return true regardless of whether there are any repeater items.

Secondly, if film_days is a repeater then you have to loop over its value - you can't get a field value of a child repeater item with $p->film_days->film_times

So for that section of code I think you want something like:

// remove all the old data (verbose)
if($p->film_days->count()) {
	foreach($p->film_days as $film_day) {
		if($film_day->film_times->count()) {
			$film_day->of(false);
			$film_day->film_times->removeAll();
			$film_day->save();
		}
	}
	$p->film_days->removeAll();
	$p->save();
}

...and to shorten it I don't think you need to worry about removing film times in film days you are about to also remove - just remove the film days and the film times will be gone too:

// remove all the old data
if($p->film_days->count()) {
	$p->film_days->removeAll();
	$p->save();
}

 

  • Like 1
Link to comment
Share on other sites

17 hours ago, BitPoet said:

Am I right in assuming that a call to $pages->uncacheAll() between the two parts makes it work?

Hi @BitPoet, thank you for your reply,
unfortunately that does not work, I still get the same results.
The only way i have made it work so far is to split the code into 2 files/requests, be it via manually executing the 2 files one after the other,
or by doing a curl/exec request and executing the second file in the first one.

Link to comment
Share on other sites

13 hours ago, Robin S said:

This part doesn't look quite right for a couple of reasons...

Firstly, the value of a repeater field is a PageArray even if the field is empty, so is_null() is never going to return true regardless of whether there are any repeater items.

Secondly, if film_days is a repeater then you have to loop over its value - you can't get a field value of a child repeater item with $p->film_days->film_times

So for that section of code I think you want something like:


// remove all the old data (verbose)
if($p->film_days->count()) {
	foreach($p->film_days as $film_day) {
		if($film_day->film_times->count()) {
			$film_day->of(false);
			$film_day->film_times->removeAll();
			$film_day->save();
		}
	}
	$p->film_days->removeAll();
	$p->save();
}

...and to shorten it I don't think you need to worry about removing film times in film days you are about to also remove - just remove the film days and the film times will be gone too:


// remove all the old data
if($p->film_days->count()) {
	$p->film_days->removeAll();
	$p->save();
}

 

hi @Robin S , You are right, the is_null() will always returns false, and i dont need to remove the times seperately, i edited my code to your last example and it still works fine, thank you for your input.

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