3434namespace GlpiPlugin \Advancedforms \Tests \Front ;
3535
3636use DbTestCase ;
37+ use DOMElement ;
3738use Glpi \Exception \RedirectException ;
39+ use LogicException ;
40+ use RuntimeException ;
3841use Session ;
3942use Symfony \Component \DomCrawler \Crawler ;
4043
@@ -47,7 +50,6 @@ public function get(string $url, array $params = []): Crawler
4750 $ _GET = $ params ;
4851
4952 try {
50- $ this ->login ();
5153 ob_start ();
5254 $ _SERVER ['REQUEST_URI ' ] = GLPI_ROOT . $ url ;
5355 require (GLPI_ROOT . $ url );
@@ -59,23 +61,81 @@ public function get(string $url, array $params = []): Crawler
5961 return new Crawler ($ html );
6062 }
6163
62- public function post (string $ url , array $ payload ): void
64+ public function post (string $ url , array $ payload, bool $ add_token = true ): void
6365 {
6466 $ old_POST = $ _POST ;
6567 $ _POST = $ payload ;
6668
6769 try {
68- $ this ->login ();
69- $ _POST ['_glpi_csrf_token ' ] = Session::getNewCSRFToken ();
70+ if ($ add_token ) {
71+ $ _POST ['_glpi_csrf_token ' ] = Session::getNewCSRFToken ();
72+ }
7073
7174 ob_start ();
7275 $ _SERVER ['REQUEST_URI ' ] = GLPI_ROOT . $ url ;
7376 require (GLPI_ROOT . $ url );
77+ ob_get_clean ();
7478 } catch (RedirectException ) {
7579 // In legacy files redirect exception mean success.
7680 ob_get_clean ();
7781 } finally {
7882 $ _POST = $ old_POST ;
7983 }
8084 }
85+
86+ public function sendForm (
87+ string $ form_content_url ,
88+ array $ query_params ,
89+ array $ form_values ,
90+ ): void {
91+ // Get form html content
92+ $ form_crawler = $ this ->get ($ form_content_url , $ query_params );
93+ $ form = $ form_crawler ->filter ('form ' )->getNode (0 );
94+ if (!$ form instanceof DOMElement) {
95+ throw new RuntimeException ("Failed to find form " );
96+ }
97+
98+ // Parse form attributes
99+ $ url = $ form ->getAttribute ('action ' );
100+ $ method = $ form ->getAttribute ('method ' );
101+ if (strtolower ($ method ) !== "post " ) {
102+ throw new RuntimeException ("Only POST forms are supported " );
103+ }
104+
105+ // Compute default payload from html
106+ $ payload = [];
107+ foreach ($ form_crawler ->filter ('input ' ) as $ input ) {
108+ if (!$ input instanceof DOMElement) {
109+ throw new LogicException (); // Impossible
110+ }
111+
112+ // Skip unchecked checkboxes
113+ $ type = strtolower ($ input ->getAttribute ('type ' ));
114+ if ($ type === 'checkbox ' && !$ input ->hasAttribute ('checked ' )) {
115+ continue ;
116+ }
117+
118+ // Add value to payload
119+ $ payload [$ input ->getAttribute ('name ' )] = $ input ->getAttribute ('value ' );
120+ }
121+
122+ // Load submit button value
123+ $ submits = $ form_crawler ->filter ('button[type=submit] ' );
124+ if (count ($ submits ) > 1 ) {
125+ throw new RuntimeException ("Only forms with a single submit are supported " );
126+ }
127+ $ submit = $ submits ->getNode (0 );
128+ if (!$ submit instanceof DOMElement) {
129+ throw new LogicException (); // Impossible
130+ }
131+ $ payload [$ submit ->getAttribute ('name ' )] = $ submit ->getAttribute ('value ' );
132+
133+
134+ // Insert specified payload values
135+ foreach ($ form_values as $ key => $ value ) {
136+ $ payload [$ key ] = $ value ;
137+ }
138+
139+ $ this ->post ($ url , $ payload , add_token: false );
140+ }
81141}
0 commit comments