Jump to content
GeraldSchmidt

How to get the last item of repeater programmatically after saving the page?

Recommended Posts

Hi,

following scenario:

I have a Single-Page implemented with ProcessWire (So i got only one page in the Backend)

post-3414-0-82860100-1453894135_thumb.pn

The customer wants me to implement a functionality which recognize the current saved item of the repeater and publish it to his facebook-page. But this is my problem. I don't see any possibility to "catch" this last-saved entry of the repeater programmatically.

This here is my repeater

post-3414-0-68434300-1453894160_thumb.pn

The name of the repeater is "referencesList" (the field-name)

post-3414-0-98940200-1453894272_thumb.pn

Do i have to programm a module for this plan?

Thank you very much in advance for your answer :)

Share this post


Link to post
Share on other sites

I think i found a solution to detect the saving of the page but i cannot get the last-saved item. It only works when im not adding an entry to the repeater.

<?php

class RepeaterLastItemCatcher extends WireData implements Module {

	/**
	 * getModuleInfo is a module required by all modules to tell ProcessWire about them
	 *
	 * @return array
	 *
	 */
	public static function getModuleInfo() {

		return array(

			// The module'ss title, typically a little more descriptive than the class name
			'title' => 'RepeaterLastItemCatcher', 

			// version number 
			'version' => 2, 

			// summary is brief description of what this module is
			'summary' => 'Dieses Modul fängt den letzten Eintrag des Repeaters ab.',
			
			// Optional URL to more information about the module
			'href' => 'https://onur-sahin.de',

			// singular=true: indicates that only one instance of the module is allowed.
			// This is usually what you want for modules that attach hooks. 
			'singular' => true, 

			// autoload=true: indicates the module should be started with ProcessWire.
			// This is necessary for any modules that attach runtime hooks, otherwise those
			// hooks won't get attached unless some other code calls the module on it's own.
			// Note that autoload modules are almost always also 'singular' (seen above).
			'autoload' => true, 
		
			// Optional font-awesome icon name, minus the 'fa-' part
			'icon' => 'smile-o', 
			);
	}

	/**
	 * Initialize the module
	 *
	 * ProcessWire calls this when the module is loaded. For 'autoload' modules, this will be called
	 * when ProcessWire's API is ready. As a result, this is a good place to attach hooks. 
	 *
	 */
	public function init() {

		// add a hook after the $pages->save, to issue a notice every time a page is saved
		$this->pages->addHookAfter('save', $this, 'catchLastItem'); 

	}

	public function catchLastItem($event) {
		$page = $event->arguments[0]; 
		$this->message("Nachdem speichern der Seite: " . $page->referencesList->last()->referencesText); 

	}

	
}

sdfsdf

Share this post


Link to post
Share on other sites

Why don't you create separate pages instead? That would simplify things a lot, now and later.

Share this post


Link to post
Share on other sites

Just a guess based on a quick look through the repeater source code, but maybe try hooking: FieldtypeRepeater::savePageField

https://github.com/ryancramerdesign/ProcessWire/blob/master/wire/modules/Fieldtype/FieldtypeRepeater/FieldtypeRepeater.module#L958

Also possibly: InputfieldRepeater::processInput (although this is before the repeater has saved, so not sure if it will be of any help)

https://github.com/ryancramerdesign/ProcessWire/blob/master/wire/modules/Fieldtype/FieldtypeRepeater/InputfieldRepeater.module#L236

  • Like 1

Share this post


Link to post
Share on other sites

Just a guess based on a quick look through the repeater source code, but maybe try hooking: FieldtypeRepeater::savePageField

https://github.com/ryancramerdesign/ProcessWire/blob/master/wire/modules/Fieldtype/FieldtypeRepeater/FieldtypeRepeater.module#L958

Also possibly: InputfieldRepeater::processInput (although this is before the repeater has saved, so not sure if it will be of any help)

https://github.com/ryancramerdesign/ProcessWire/blob/master/wire/modules/Fieldtype/FieldtypeRepeater/InputfieldRepeater.module#L236

Thank you so much for your advice adrian!!!

Now it works!

<?php

class RepeaterLastItemCatcher extends WireData implements Module {

	public static function getModuleInfo() {

		return array(

			// The module'ss title, typically a little more descriptive than the class name
			'title' => 'RepeaterLastItemCatcher', 

			// version number 
			'version' => 2, 

			// summary is brief description of what this module is
			'summary' => 'Dieses Modul fängt den letzten Eintrag des Repeaters "" ab.',
			
			// Optional URL to more information about the module
			'href' => 'https://onur-sahin.de',

			// singular=true: indicates that only one instance of the module is allowed.
			// This is usually what you want for modules that attach hooks. 
			'singular' => true, 

			// autoload=true: indicates the module should be started with ProcessWire.
			// This is necessary for any modules that attach runtime hooks, otherwise those
			// hooks won't get attached unless some other code calls the module on it's own.
			// Note that autoload modules are almost always also 'singular' (seen above).
			'autoload' => true, 
		
			// Optional font-awesome icon name, minus the 'fa-' part
			'icon' => 'smile-o', 

			);
	}

	public function init() {

		// add a hook after the $pages->save, to issue a notice every time a page is saved
		$this->pages->addHookAfter('FieldtypeRepeater::savePageField', $this, 'catchLastItem'); 

	}

	public function catchLastItem($event) {
		
		/*
			Die Argumente sind die Parameterübergaben folgender Methode -> ___savePageField
			https://github.com/ryancramerdesign/ProcessWire/blob/master/wire/modules/Fieldtype/FieldtypeRepeater/FieldtypeRepeater.module#L958
		*/
		$page = $event->arguments[0]; 

		// Der zuletzt hinzugefügte Text des Referenz-Repeaters
		$lastSavedReferencesText = $page->referencesList->last()->referencesText;

		// Das zuletzt hinzugefügte Bild des Referenz-Repeaters
		$lastSavedReferencesImage = $_SERVER['SERVER_NAME'].$page->referencesList->last()->referencesImage->first()->url;

		// Testweise mal ausgeben im Backend
		$this->message("lastSavedReferencesText: " . $lastSavedReferencesText);
		$this->message("lastSavedReferencesImage: " . $lastSavedReferencesImage);

		// Ab dieser Stelle kommt dann die Facebook-SDK zum Einsatz...

	}

}

  • Like 1

Share this post


Link to post
Share on other sites

Glad that worked for. Just in case you don't know you can avoid the need for an entire module to add simple hooks like this.

You can place the hook and method in site/templates/admin.php

There are also site/init.php site/ready.php and site/finished.php files that you can make use of. More reading here: https://processwire.com/blog/posts/processwire-2.6.7-core-updates-and-more/#new-core-files-for-site-hooks

  • Like 2

Share this post


Link to post
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

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By ICF Church
      Hi 👋
      Anyone else having this problem?
      Requirements:
      - Repeater (matrix & normal) with mutlilanguage fields (text, textarea…) 
      - Backend language set to something other than default (ie. German) 
      Reproduce:
      - Add a new repeater Item (ajax, I found no way to possible to disable it with matrix)

      (Notice how the default language tab is active instead of the backend language…)
      - Write something into the (default language) field
      - Try to save, if field is required, this will not work. If not required, then when reloading, the content will be inside the backend language field, instead of the default language field who was (presumably) active
      Analysis:
      When  loading  a new repeater element with ajax, the default langue tab is active, but the backend language inputfield is visible (with no visual indication). When writing into the field, it will populate the backend language. When manually clicking on the default language tab (which is already active), the field will switch to the actual default language field (which is [now] empty) (that can now be populated…)
      Also Notice, the labels of the elements to be added are in default language as well instead of the translated label (images instead of Bilder)…
      ProcessWire 3.0.148, Profields 0.0.5…
      Is it my system configuration, or does anyone else have the same issue? This is a screen recording of the problem:
      Issue: https://github.com/processwire/processwire-issues/issues/1179

      Screen Recording 2020-02-25 at 14.18.31.mov
    • By neonwired
      I have a front end form for creating new pages, repeater and repeater matrix field don't seem to save any data. I was considering handling the data manually but can't seem to get anything useful from the post data, are there any methods i can use?
    • By neophron
      Hi,
      I'm having trouble with a maybe simple code:
      I created a repeater (gallery_logos_links) and a repeater matrix (RepeaterMatrix_unternehmen). The repeater (gallery_logos_links) is inside the matrix repeater as a matrix type.
      The repeater matrix type is: gallery_logos_links and the image filed from the repeater is single_image.
       
      This my code:
      <?php foreach ($page->RepeaterMatrix_unternehmen as $item) { if ($item->type == 'gallery_logos_links') { echo " {foreach($item->repeater_logos_links as $logo)} <img src='{$logo->single_image->url}' alt='{$logo->single_image->description}' width='400'> {endforeach} "; } else if ($item->type == 'some_stuff') { echo"  
       
    • By shadowkyogre
      [EDIT]: After sitting down and planning out my site according to the ragged hierarchy information, I settled on the following schematics.
      /$world/$template/$content_of_template_type/... for my pretty URLs /roster/$character for my characters a generic Repeater field with depth on most content types for custom positions for child pages to connect to instead of it directly a few Repeater fields on each content that have (PageReference[1], other fields) to establish associations A few FieldsetGroups to help me manage the fields that I needed to copy across a bunch of content types. Kept the original post below for context and tagged the OP for searchability.
      ---
      Hi everyone! I'm working on a personalized worldbuilding wiki to host my art and story stuff.
      Right now my site architecture looks like...
      /$world/cosmology/$cosmology /$world/locations/$location /$world/factions/$faction /$world/history/$history /$world/species/$species /roster/$character So far the layout works, but there's one problem. I need to make sub-sections for an organization. Organizations can appear under cosmology, locations, and factions. Sounds straightforward until... I run into the problem of figuring out how to represent subfactions.
      Key factors in this are...
      Characters should be able to be part of multiple organizations Characters should have an explicit role assigned to their membership. Character pages should be able to query the organization pages to display their ranks across organizations. Editing an organization's hierarchical layout should be visible while editing the root organization page. From what I've read of the ProcessWire documentation, the best use case for each way of representing the organization's subsections are...
      Child Pages:: Works best for menu presentation and dedicated editing. PageTables:: Works if you want control over where to place the PageTable fields, but requires opening a modal for the pages you want to edit. It's also kind of like normal pages. Repeaters:: Works great for inline editing and easy control over hierarchy, but the page urls become obscure. Sections in the body field:: Works for copypasting from my note files. But it doesn't expose relationships for easy querying. It looks like my best case for this is child pages since it allows displaying suborganization in the URL easily. But also I lose out on quickly reordering and editing the child pages. Any advice for people running into similar use cases?
×
×
  • Create New...