Jump to content

Switch content from one image field to another image field via API


saschapi
 Share

Recommended Posts

Hi guys,

I'm trying to achieve a timed update of posts kind of feature. I'm using a process mentioned here: 

 In short: I have a date field and if the date is in the past I switch content from fields (like "title_change") to the origional fields (like "title"). After that I clear the change fields. Full code here:

		// set date
		date_default_timezone_set("Europe/Berlin");
		$planned_date = $single->sender_change_datetime;
			//check if date is in the past and if so, work your macgic
			if($planned_date < time()) {
					echo "date is overtime" ;
					// stop output formating
					$single->of(false);
				
					// Collect change data
					// Title
					if($single->sender_title_changes_check) {
						//set new field						
						$single->title = $single->sender_title_changes;
						$single->sender_title_changes = false;
						$single->sender_title_changes_check = false;
					}
					// Quality
					if($single->sender_quality_changes_check) {
						//set new field						
						$single->sender_quality = $single->sender_quality_changes;
						$single->sender_quality_changes = false;
						$single->sender_quality_changes_check = false;
					}	
					// Genre
					if($single->sender_genre_changes_check) {
						//set new field						
						$single->sender_genre = $single->sender_genre_changes;
						$single->sender_genre_changes = false;
						$single->sender_genre_changes_check = false;
					}
					// Description
					if($single->sender_description_changes_check) {
						//set new field						
						$single->sender_description = $single->sender_description_changes;
						$single->sender_description_changes = false;
						$single->sender_description_changes_check = false;
					}
					// Pakete
					if($single->sender_paket_changes_check) {
						//set new field						
						$single->sender_paket = $single->sender_paket_changes;
						$single->sender_paket_changes->removeAll();
						$single->sender_paket_changes_check = false;
					}	
					// Logo
					if($single->sender_logo_standard_changes_check) {
						//set new field					
						echo $single->sender_logo_standard_changes->eq(0)->filename;
						$single->sender_logo_standard->removeAll();
						$single->sender_logo_standard->add($single->sender_logo_standard_changes->eq(0)->filename);
						$single->sender_logo_standard_changes->removeAll();
						$single->sender_logo_standard_changes_check = false;
					}				
				
					//remove the changes checkbox and clear date
					$single->sender_change_check = false;
				    $single->sender_change_datetime = false;
				
					//save page
					$single->save();
				
					//flag changes necessary
					$changes_necessary = true;
			} 
		

Works as expected. BUT my issue is with images.

Look at the detailed code here:

					if($single->sender_logo_standard_changes_check) {
						//set new field					
						echo $single->sender_logo_standard_changes->eq(0)->filename;
						$single->sender_logo_standard->removeAll();
						$single->sender_logo_standard->add($single->sender_logo_standard_changes->eq(0)->filename);
						$single->sender_logo_standard_changes->removeAll();
						$single->sender_logo_standard_changes_check = false;
					}	

This works fine, but the image is empty. There are no files present. I guess this is because I clear the "sender_logo_standard_chages" field with "removeAll()"? It automatically deletes the files? 
 

If this is my problem: How do I delete just the file reference in "sender_logo_standard_chages" while keeping the files? 
If this is NOT the problem: How do I achieve what I want to achieve? :)

Thanks guys for any input Sascha

Link to comment
Share on other sites

If you can live with the fact that a counter is inserted into the filename, I'd copy the file to a temp path, then add that to sender_logo_standard and remove the temporary copy after the page was saved.

There's a possibility to intercept the hook method that performs the file system level deletion with your own prioritized hook, but doing so is not completely free of side issues since the original hook removes itself, with doesn't happen if intercepted.

Another idea that comes to mind is wrapping your replacement fields inside a FieldtypeFieldsetPage. This will be editable just like a regular fieldset in the page, though for api access, you have one more level of indirection, i.e. $single->sender_log_standard_changes would become something like $single->changes->sender_logo_standard_changes (but you might re-use the sender_logo_standard there instead of having two different fields, so it could be $single->changes->sender_logo_standard). The advantage is that $single->changes would be a different page behind the scene. The moment you add the image from there to your regular image field, PW sees that this belongs to a different page and creates a copy.

Link to comment
Share on other sites

This sounds about right. I think I will switch to the FieldsetPage structure. 

I used that before but forgot about it ? Question related to FieldsetPage: Usually I do the following. Mark a field as required and have a visibility condition so the field only shows up if needed. This does not give an error on saving is the field is hidden. With FieldsetPage I have an error that the required field cannot be empty. Even adding the condititon to "required only if" does not help. Funny thing is, the visibility condition works as expected otherwise. So, the field only shows if the condition is met, but it is marked as required. Do you have any idea why that is @BitPoet?

In my example above I have "sender_trailer_file1_changes_check=1" as condition.

Link to comment
Share on other sites

On 2/1/2020 at 5:10 PM, saschapi said:

shouldn't the hook fire, regardless if the field is in the fieldsetPage?

Ah, that's the ugliness of Repeater magic once more. Inside the FieldsetPage, the field's name and id change from crondate to crondate_repeaterXXXX (where XXXX is the number of the fieldsetpage item) to prevent collisions. The hook probably should check against preg_match('^/crondate(_repeater\\d+)?$/', $field->name) instead of a straight comparison to work both inside and outside a repeater/fsp. Not exactly sure how the JS part is addressed best.

Link to comment
Share on other sites

On 2/5/2020 at 4:05 AM, BitPoet said:

The hook probably should check against preg_match('^/crondate(_repeater\\d+)?$/', $field->name) instead of a straight comparison to work both inside and outside a repeater/fsp.

The way that I find easiest is to get the Field object that is associated with the Inputfield via hasField and check its name, because the Inputfield object's name changes inside a Repeater but the Field object's name doesn't. So something like this:

$wire->addHookAfter('InputfieldDatetime::processInput', function(HookEvent $event) {
	$inputfield = $event->object;
	$field = $inputfield->hasField;
	if(!$field || $field->name !== 'your_field_name') return;
	// ...
});

 

  • Like 2
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...