alles ChildrenIDs und unterIDs

Hallo zusammen

Ich würde ein Funktion benötigen die mir von(ab) einem Object alle unterobject IDs in einem Array zurückliefert. Aber nicht nur die von der ersten Ebene wie es IPS_GetChildrenIDs macht, sondern bis HasChildren 0 ist (also alles)
Also Quasi wie IPS_GetObjectList nur das ich die Parent ID angeben kann.

Gibt es sowas schon fertig oder kann mir jemand beim PHP code helfen? Ich habs schon versucht zu scripten aber bin bei den ganzen foreach Schleifen nicht mehr weitgergekommen.

danke und lg Joachim

Probier’s mal damit - Grüße.
jwka


<?
/* ***********************************************************************
	READS OBJECTTREE RECURSIVELY FROM GIVEN START ID(s)

************************************************************************ */
// THIS IS A LIST OF ID's TO START THE SEARCH WITH CAN BE ONE OR MULTIPLE
	$f['start_ids'][]= 54536 /*[.02 Scripts 05 UNDER DEVELOPMENT !!!!!!!!!!!!!!!!!!!!!!!!!!!!!]*/;
//	$f['start_ids'][]= 31234 /*[2-Bajo [EG]]*/;
//	$f['start_ids'][]= 0 /*[2-Bajo [EG]]*/;

// THIS WILL BE THE LIST OF ALL OBJECTS CRAWLED
	//$f['done_ids'] = "";
	//$f['all_ids'] = "";

// THIS WILL BE THE LIST OF ALL OBJECTS CRAWLED AND MATCHING THE SEARCH TYPES LIST
	$f['good_ids'] = NULL;

// DEFINE SEARCHTYPES --> THESE TYPES OF OBJECTS WIL BE IN THE "GOODLIST"
	$f['s_types'][] = 0;
	$f['s_types'][] = 1;
	$f['s_types'][] = 2;
	$f['s_types'][] = 3;
	$f['s_types'][] = 4;
	$f['s_types'][] = 5;

// DEFINE IF LINKS SHALL BE EXECUTED
	$f['link_drill'] = true;


// FUTURE CHANGES
     $DrillCategories=true;
     $DrillLinkedCategories=true;


// CALL COLLECTION FUNCTION
	ACVITI_CollectIDs( &$f );


// REPORT TO SCREEN
	echo " ID    |Type| Name 
";
	foreach( $f['good_ids'] as $act_id)
	{
    	echo " " . $act_id
					. " | " . $f[ $act_id ]['ObjectType']
					. "  | " . $f[ $act_id ]['ObjectName'] . "
";

	};



function ACVITI_CollectIDs(&$f ) {
	//#######################################################################
	// THIS FUNCTION READS THE OBJECT TREE FROM A GIVEN ENTRY POINT OR
	// ENTRY POINTS (IF FIRST PARAMETER IS A TRUE ARRAY INSTAED OF ARRY
	// WITH ONLY ONE ITEM) AND FINDS OUT IF, WITHIN THE TREE:
	// - an object is of a defined Type ($SerachTypes)
	// - an object is a Link
	// - an object is a Category
	// IF an object IS A LINK, the linked element is checked if it is of the
	// defined Type, IF $DrillLinks is TRUE.
	
	// FUTURE ENHANCEMENTS:
	// IF an object IS A CATEGORY, the structure below the category will be
	// searched	IF $DrillCategories is TRUE.
	// IF an object IS A LINK AND the linked object is a CATEGORY, the structure
	// below that category will be searched IF $DrillLinkedCategories is TRUE.
	//#######################################################################

	$f['done'][] = "X";
	$f['alltodo'] = $f['start_ids'];

//	echo "FUNCTION " . __FUNCTION__ . " BEGINN 
";


	reset( $f['alltodo'] );
	$f['act_id'] = current( $f[ 'alltodo'] );

	while( !($f['act_id'] === false ) )
	{

		// IF ACTUAL ID FROM LIST WAS ALLREADY DONE, GET NEXT & CONTINUE
		// REMARK: SHOULD NEVER TAKE PLACE !!
		if( in_array( $f['act_id'], $f['done'], true ) )
		{
			$f['act_id'] = next( $f[ 'alltodo'] );
			$i++;
			continue;
		};

		// PUT ACTUAL IN DONELIST
			$f['done'][] = $f['act_id'];

		// GET ACTUAL OBJECT
			$f['act_obj'] = IPS_GetObject( $f['act_id'] );
			$f[ $f['act_id'] ]['ObjectType'] = $f['act_obj']['ObjectType'];
			$f[ $f['act_id'] ]['ObjectName'] = $f['act_obj']['ObjectName'];

		// COLLECT THE SERACHTYPED ONES IN SEPARATE ARRAY
		   if( in_array( $f[ $f['act_id'] ]['ObjectType']  , $f['s_types'] ) )
		   {
				$f['good_ids'][] = $f['act_id'];
		   };

		// GET THE CHILDREN
	  	$f['act_children'] = IPS_GetChildrenIDs( $f['act_id'] );

		// SINCE WE ARE RECURSIVE HERE, PUT ALL THE NEW ITEMS INTO THE TODO LIST
		// DO THAT THRU LOOP IN STEAD OF ARRAY_MERGE DUE TO POINTER MOVEMENT IN MERGE
  		   $f['new'] = array_diff( $f['act_children'], $f['alltodo'], $f['done'] );
  		   foreach( $f['new'] as $f['newi'])
				{ $f['alltodo'][] = $f['newi']; };

		// SPECIAL TREATMENT FOR LINKS
		   if( ($f['act_obj']['ObjectType'] == 6) AND $f['link_drill']  )
		   {
      		// GET LINK OBJECT FOR CONNECTION
			      $f['link'] = IPS_GetLink( $f['act_id'] );

           		// GET LINKED OBJECT
			      $f['new'] = $f['link']['LinkChildID'];
			      
					// PUT IN LIST IF NOT ALREADY IN
					   if( !in_array( $f['new'], $f['alltodo'] ) )
				      {
	                 $f['alltodo'][] = $f['new'];
				      };
		   };

		$f['act_id'] = next( $f[ 'alltodo'] );
	};
	return(true);
};

?>

Hat zwar nicht die Features von jwka, ist aber ein wenig kompakter.

print_r(GetObjectList(44014 /*[Büro]*/));

function GetObjectList($parent) {
	$ids = IPS_GetChildrenIDs($parent);
	foreach($ids as $id)
	{
		$ids = array_merge($ids, GetObjectList($id));
	}
	return $ids;
}

paresy

PS: Wir nutzen aus, dass die foreach Bedingung nicht neu ausgewertet wird, wenn sich das Quell-Array ändert. Beiweis:

$arr = Array(0, 1, 2, 3, 4);
$arr2 = Array(5);

foreach($arr as $id) {
 echo $id;
 if($id == 0) {
  $arr = array_merge($arr, $arr2);
 }
}

WoW ihr seit die besten, funktioniert super… da wäre ich nie draufgekommen. Mein Code wär schon um einiges länger und hat nicht funktioniert :mad:

Danke für die Hilfe!

Yep. Simple vs. Features. Wie immer bei Software.

Wenn noch folgende Am´nmerkung erlaubt ist:

Paresy’s Script nimmt keine Verzweigungen via Link in die Liste der „Children“ auf (und hat damit natürlich auch nicht das Problem der ggf. entstehenden Endlosschleife).

In „meiner“ Denke sehe ich den Baum dort fortgesetzt, wo ein Link hinzeigt, denn das ist ja ein Stück weit Sinn eines Links. Das ist dann (leider) nicht mehr mit wenigen Zeilen zu machen, meie ich.

jwka

Das sind dann 3 Zeilen mehr. Du musst nur in der foreach Schleife checken, ob es ein Link ist, und wenn ja, dann $id auf die $linkID umbiegen.

paresy

Naja … und wie handelst Du dann Endlosschleifen, die ja durchaus mit Links passieren können?

jwka