public function generate()
	{
		$this->import(BackendUser::class, 'User');
		$this->convertValuesToPaths();

		if ($this->extensions != '')
		{
			$this->arrValidFileTypes = StringUtil::trimsplit(',', strtolower($this->extensions));
		}

		/** @var AttributeBagInterface $objSessionBag */
		$objSessionBag = System::getContainer()->get('session')->getBag('contao_backend');

		// Store the keyword
		if (Input::post('FORM_SUBMIT') == 'item_selector')
		{
			$strKeyword = ltrim(Input::postRaw('keyword'), '*');

			// Make sure the regular expression is valid
			if ($strKeyword != '')
			{
				try
				{
					$this->Database->prepare("SELECT * FROM tl_files WHERE name REGEXP ?")
								   ->limit(1)
								   ->execute($strKeyword);
				}
				catch (\Exception $e)
				{
					$strKeyword = '';
				}
			}

			$objSessionBag->set('file_selector_search', $strKeyword);
			$this->reload();
		}

		$tree = '';
		$for = $objSessionBag->get('file_selector_search');
		$arrFound = array();

		// Search for a specific file
		if ($for != '')
		{
			// Wrap in a try catch block in case the regular expression is invalid (see #7743)
			try
			{
				$strPattern = "CAST(name AS CHAR) REGEXP ?";

				if (substr(Config::get('dbCollation'), -3) == '_ci')
				{
					$strPattern = "LOWER(CAST(name AS CHAR)) REGEXP LOWER(?)";
				}

				$strType = '';

				if (strpos($for, 'type:file') !== false)
				{
					$strType = " AND type='file'";
					$for = trim(str_replace('type:file', '', $for));
				}

				if (strpos($for, 'type:folder') !== false)
				{
					$strType = " AND type='folder'";
					$for = trim(str_replace('type:folder', '', $for));
				}

				$objRoot = $this->Database->prepare("SELECT path, type, extension FROM tl_files WHERE $strPattern $strType")
										  ->execute($for);

				if ($objRoot->numRows < 1)
				{
					$GLOBALS['TL_DCA']['tl_files']['list']['sorting']['root'] = array('');
				}
				else
				{
					$arrPaths = array();

					// Respect existing limitations
					if ($this->path != '')
					{
						while ($objRoot->next())
						{
							if (strncmp($this->path . '/', $objRoot->path . '/', \strlen($this->path) + 1) === 0)
							{
								if ($objRoot->type == 'folder' || empty($this->arrValidFileTypes) || \in_array($objRoot->extension, $this->arrValidFileTypes))
								{
									$arrFound[] = $objRoot->path;
								}

								$arrPaths[] = ($objRoot->type == 'folder') ? $objRoot->path : \dirname($objRoot->path);
							}
						}
					}
					elseif ($this->User->isAdmin)
					{
						// Show all files to admins
						while ($objRoot->next())
						{
							if ($objRoot->type == 'folder' || empty($this->arrValidFileTypes) || \in_array($objRoot->extension, $this->arrValidFileTypes))
							{
								$arrFound[] = $objRoot->path;
							}

							$arrPaths[] = ($objRoot->type == 'folder') ? $objRoot->path : \dirname($objRoot->path);
						}
					}
					else
					{
						if (\is_array($this->User->filemounts))
						{
							while ($objRoot->next())
							{
								// Show only mounted folders to regular users
								foreach ($this->User->filemounts as $path)
								{
									if (strncmp($path . '/', $objRoot->path . '/', \strlen($path) + 1) === 0)
									{
										if ($objRoot->type == 'folder' || empty($this->arrValidFileTypes) || \in_array($objRoot->extension, $this->arrValidFileTypes))
										{
											$arrFound[] = $objRoot->path;
										}

										$arrPaths[] = ($objRoot->type == 'folder') ? $objRoot->path : \dirname($objRoot->path);
									}
								}
							}
						}
					}

					$GLOBALS['TL_DCA']['tl_files']['list']['sorting']['root'] = array_unique($arrPaths);
				}
			}
			catch (\Exception $e) {}
		}

		$strNode = $objSessionBag->get('tl_files_picker');

		// Unset the node if it is not within the path (see #5899)
		if ($strNode != '' && $this->path != '')
		{
			if (strncmp($strNode . '/', $this->path . '/', \strlen($this->path) + 1) !== 0)
			{
				$objSessionBag->remove('tl_files_picker');
			}
		}

		// Add the breadcrumb menu
		if (Input::get('do') != 'files')
		{
			Backend::addFilesBreadcrumb('tl_files_picker');
		}

		$rootDir = System::getContainer()->getParameter('kernel.project_dir');

		// Root nodes (breadcrumb menu)
		if (!empty($GLOBALS['TL_DCA']['tl_files']['list']['sorting']['root']))
		{
			$root = $GLOBALS['TL_DCA']['tl_files']['list']['sorting']['root'];

			// Allow only those roots that are within the custom path
			if ($this->path != '')
			{
				$root = array_intersect(preg_grep('/^' . preg_quote($this->path, '/') . '(?:$|\/)/', $root), $root);

				if (empty($root))
				{
					// Set all folders inside the custom path as root nodes
					$root = array_map(function ($el) { return $this->path . '/' . $el; }, scan($rootDir . '/' . $this->path));

					// Hide the breadcrumb
					$GLOBALS['TL_DCA']['tl_file']['list']['sorting']['breadcrumb'] = '';
				}
			}

			$nodes = $this->eliminateNestedPaths($root);

			foreach ($nodes as $node)
			{
				$tree .= $this->renderFiletree($rootDir . '/' . $node, 0, true, true, $arrFound);
			}
		}

		// Show a custom path (see #4926)
		elseif ($this->path != '')
		{
			$tree .= $this->renderFiletree($rootDir . '/' . $this->path, 0, false, $this->isProtectedPath($this->path), $arrFound);
		}

		// Start from root
		elseif ($this->User->isAdmin)
		{
			$tree .= $this->renderFiletree($rootDir . '/' . Config::get('uploadPath'), 0, false, true, $arrFound);
		}

		// Show mounted files to regular users
		else
		{
			$nodes = $this->eliminateNestedPaths($this->User->filemounts);

			foreach ($nodes as $node)
			{
				$tree .= $this->renderFiletree($rootDir . '/' . $node, 0, true, true, $arrFound);
			}
		}

		// Select all checkboxes
		if ($this->fieldType == 'checkbox')
		{
			$strReset = "\n" . '    <li class="tl_folder"><div class="tl_left">&nbsp;</div> <div class="tl_right"><label for="check_all_' . $this->strId . '" class="tl_change_selected">' . $GLOBALS['TL_LANG']['MSC']['selectAll'] . '</label> <input type="checkbox" id="check_all_' . $this->strId . '" class="tl_tree_checkbox" value="" onclick="Backend.toggleCheckboxGroup(this,\'' . $this->strName . '\')"></div><div style="clear:both"></div></li>';
		}
		// Reset radio button selection
		else
		{
			$strReset = "\n" . '    <li class="tl_folder"><div class="tl_left">&nbsp;</div> <div class="tl_right"><label for="reset_' . $this->strId . '" class="tl_change_selected">' . $GLOBALS['TL_LANG']['MSC']['resetSelected'] . '</label> <input type="radio" name="' . $this->strName . '" id="reset_' . $this->strName . '" class="tl_tree_radio" value="" onfocus="Backend.getScrollOffset()"></div><div style="clear:both"></div></li>';
		}

		// Return the tree
		return '<ul class="tl_listing tree_view picker_selector'.(($this->strClass != '') ? ' ' . $this->strClass : '').'" id="'.$this->strId.'" data-callback="reloadFiletree">
    <li class="tl_folder_top"><div class="tl_left">'.Image::getHtml($GLOBALS['TL_DCA']['tl_files']['list']['sorting']['icon'] ?: 'filemounts.svg').' '.$GLOBALS['TL_LANG']['MOD']['files'][0].'</div> <div class="tl_right">&nbsp;</div><div style="clear:both"></div></li><li class="parent" id="'.$this->strId.'_parent"><ul>'.$tree.$strReset.'
  </ul></li></ul>';
	}
public function generate()
	{
		$this->import(BackendUser::class, 'User');
		$this->convertValuesToPaths();

		if ($this->extensions != '')
		{
			$this->arrValidFileTypes = StringUtil::trimsplit(',', strtolower($this->extensions));
		}

		
		$objSessionBag = System::getContainer()->get('session')->getBag('contao_backend');

		
		if (Input::post('FORM_SUBMIT') == 'item_selector')
		{
			$strKeyword = ltrim(Input::postRaw('keyword'), '*');

			
			if ($strKeyword != '')
			{
				try
				{
					$this->Database->prepare("SELECT * FROM tl_files WHERE name REGEXP ?")
								   ->limit(1)
								   ->execute($strKeyword);
				}
				catch (\Exception $e)
				{
					$strKeyword = '';
				}
			}

			$objSessionBag->set('file_selector_search', $strKeyword);
			$this->reload();
		}

		$tree = '';
		$for = $objSessionBag->get('file_selector_search');
		$arrFound = array();

		
		if ($for != '')
		{
			
			try
			{
				$strPattern = "CAST(name AS CHAR) REGEXP ?";

				if (substr(Config::get('dbCollation'), -3) == '_ci')
				{
					$strPattern = "LOWER(CAST(name AS CHAR)) REGEXP LOWER(?)";
				}

				$strType = '';

				if (strpos($for, 'type:file') !== false)
				{
					$strType = " AND type='file'";
					$for = trim(str_replace('type:file', '', $for));
				}

				if (strpos($for, 'type:folder') !== false)
				{
					$strType = " AND type='folder'";
					$for = trim(str_replace('type:folder', '', $for));
				}

				$objRoot = $this->Database->prepare("SELECT path, type, extension FROM tl_files WHERE $strPattern $strType")
										  ->execute($for);

				if ($objRoot->numRows < 1)
				{
					$GLOBALS['TL_DCA']['tl_files']['list']['sorting']['root'] = array('');
				}
				else
				{
					$arrPaths = array();

					
					if ($this->path != '')
					{
						while ($objRoot->next())
						{
							if (strncmp($this->path . '/', $objRoot->path . '/', \strlen($this->path) + 1) === 0)
							{
								if ($objRoot->type == 'folder' || empty($this->arrValidFileTypes) || \in_array($objRoot->extension, $this->arrValidFileTypes))
								{
									$arrFound[] = $objRoot->path;
								}

								$arrPaths[] = ($objRoot->type == 'folder') ? $objRoot->path : \dirname($objRoot->path);
							}
						}
					}
					elseif ($this->User->isAdmin)
					{
						
						while ($objRoot->next())
						{
							if ($objRoot->type == 'folder' || empty($this->arrValidFileTypes) || \in_array($objRoot->extension, $this->arrValidFileTypes))
							{
								$arrFound[] = $objRoot->path;
							}

							$arrPaths[] = ($objRoot->type == 'folder') ? $objRoot->path : \dirname($objRoot->path);
						}
					}
					else
					{
						if (\is_array($this->User->filemounts))
						{
							while ($objRoot->next())
							{
								
								foreach ($this->User->filemounts as $path)
								{
									if (strncmp($path . '/', $objRoot->path . '/', \strlen($path) + 1) === 0)
									{
										if ($objRoot->type == 'folder' || empty($this->arrValidFileTypes) || \in_array($objRoot->extension, $this->arrValidFileTypes))
										{
											$arrFound[] = $objRoot->path;
										}

										$arrPaths[] = ($objRoot->type == 'folder') ? $objRoot->path : \dirname($objRoot->path);
									}
								}
							}
						}
					}

					$GLOBALS['TL_DCA']['tl_files']['list']['sorting']['root'] = array_unique($arrPaths);
				}
			}
			catch (\Exception $e) {}
		}

		$strNode = $objSessionBag->get('tl_files_picker');

		
		if ($strNode != '' && $this->path != '')
		{
			if (strncmp($strNode . '/', $this->path . '/', \strlen($this->path) + 1) !== 0)
			{
				$objSessionBag->remove('tl_files_picker');
			}
		}

		
		if (Input::get('do') != 'files')
		{
			Backend::addFilesBreadcrumb('tl_files_picker');
		}

		$rootDir = System::getContainer()->getParameter('kernel.project_dir');

		
		if (!empty($GLOBALS['TL_DCA']['tl_files']['list']['sorting']['root']))
		{
			$root = $GLOBALS['TL_DCA']['tl_files']['list']['sorting']['root'];

			
			if ($this->path != '')
			{
				$root = array_intersect(preg_grep('/^' . preg_quote($this->path, '/') . '(?:$|\/)/', $root), $root);

				if (empty($root))
				{
					
					$root = array_map(function ($el) { return $this->path . '/' . $el; }, scan($rootDir . '/' . $this->path));

					
					$GLOBALS['TL_DCA']['tl_file']['list']['sorting']['breadcrumb'] = '';
				}
			}

			$nodes = $this->eliminateNestedPaths($root);

			foreach ($nodes as $node)
			{
				$tree .= $this->renderFiletree($rootDir . '/' . $node, 0, true, true, $arrFound);
			}
		}

		
		elseif ($this->path != '')
		{
			$tree .= $this->renderFiletree($rootDir . '/' . $this->path, 0, false, $this->isProtectedPath($this->path), $arrFound);
		}

		
		elseif ($this->User->isAdmin)
		{
			$tree .= $this->renderFiletree($rootDir . '/' . Config::get('uploadPath'), 0, false, true, $arrFound);
		}

		
		else
		{
			$nodes = $this->eliminateNestedPaths($this->User->filemounts);

			foreach ($nodes as $node)
			{
				$tree .= $this->renderFiletree($rootDir . '/' . $node, 0, true, true, $arrFound);
			}
		}

		
		if ($this->fieldType == 'checkbox')
		{
			$strReset = "\n" . '    <li class="tl_folder"><div class="tl_left">&nbsp;</div> <div class="tl_right"><label for="check_all_' . $this->strId . '" class="tl_change_selected">' . $GLOBALS['TL_LANG']['MSC']['selectAll'] . '</label> <input type="checkbox" id="check_all_' . $this->strId . '" class="tl_tree_checkbox" value="" onclick="Backend.toggleCheckboxGroup(this,\'' . $this->strName . '\')"></div><div style="clear:both"></div></li>';
		}
		
		else
		{
			$strReset = "\n" . '    <li class="tl_folder"><div class="tl_left">&nbsp;</div> <div class="tl_right"><label for="reset_' . $this->strId . '" class="tl_change_selected">' . $GLOBALS['TL_LANG']['MSC']['resetSelected'] . '</label> <input type="radio" name="' . $this->strName . '" id="reset_' . $this->strName . '" class="tl_tree_radio" value="" onfocus="Backend.getScrollOffset()"></div><div style="clear:both"></div></li>';
		}

		
		return '<ul class="tl_listing tree_view picker_selector'.(($this->strClass != '') ? ' ' . $this->strClass : '').'" id="'.$this->strId.'" data-callback="reloadFiletree">
    <li class="tl_folder_top"><div class="tl_left">'.Image::getHtml($GLOBALS['TL_DCA']['tl_files']['list']['sorting']['icon'] ?: 'filemounts.svg').' '.$GLOBALS['TL_LANG']['MOD']['files'][0].'</div> <div class="tl_right">&nbsp;</div><div style="clear:both"></div></li><li class="parent" id="'.$this->strId.'_parent"><ul>'.$tree.$strReset.'
  </ul></li></ul>';
	}
public function generate ( ) { $ this -> import ( BackendUser :: class , 'User' ) ; $ this -> convertValuesToPaths ( ) ; if ( $ this -> extensions != '' ) { $ this -> arrValidFileTypes = StringUtil :: trimsplit ( ',' , strtolower ( $ this -> extensions ) ) ; } /** @var AttributeBagInterface $objSessionBag */ $ objSessionBag = System :: getContainer ( ) -> get ( 'session' ) -> getBag ( 'contao_backend' ) ; // Store the keyword if ( Input :: post ( 'FORM_SUBMIT' ) == 'item_selector' ) { $ strKeyword = ltrim ( Input :: postRaw ( 'keyword' ) , '*' ) ; // Make sure the regular expression is valid if ( $ strKeyword != '' ) { try { $ this -> Database -> prepare ( "SELECT * FROM tl_files WHERE name REGEXP ?" ) -> limit ( 1 ) -> execute ( $ strKeyword ) ; } catch ( \ Exception $ e ) { $ strKeyword = '' ; } } $ objSessionBag -> set ( 'file_selector_search' , $ strKeyword ) ; $ this -> reload ( ) ; } $ tree = '' ; $ for = $ objSessionBag -> get ( 'file_selector_search' ) ; $ arrFound = array ( ) ; // Search for a specific file if ( $ for != '' ) { // Wrap in a try catch block in case the regular expression is invalid (see #7743) try { $ strPattern = "CAST(name AS CHAR) REGEXP ?" ; if ( substr ( Config :: get ( 'dbCollation' ) , - 3 ) == '_ci' ) { $ strPattern = "LOWER(CAST(name AS CHAR)) REGEXP LOWER(?)" ; } $ strType = '' ; if ( strpos ( $ for , 'type:file' ) !== false ) { $ strType = " AND type='file'" ; $ for = trim ( str_replace ( 'type:file' , '' , $ for ) ) ; } if ( strpos ( $ for , 'type:folder' ) !== false ) { $ strType = " AND type='folder'" ; $ for = trim ( str_replace ( 'type:folder' , '' , $ for ) ) ; } $ objRoot = $ this -> Database -> prepare ( "SELECT path, type, extension FROM tl_files WHERE $strPattern $strType" ) -> execute ( $ for ) ; if ( $ objRoot -> numRows < 1 ) { $ GLOBALS [ 'TL_DCA' ] [ 'tl_files' ] [ 'list' ] [ 'sorting' ] [ 'root' ] = array ( '' ) ; } else { $ arrPaths = array ( ) ; // Respect existing limitations if ( $ this -> path != '' ) { while ( $ objRoot -> next ( ) ) { if ( strncmp ( $ this -> path . '/' , $ objRoot -> path . '/' , \ strlen ( $ this -> path ) + 1 ) === 0 ) { if ( $ objRoot -> type == 'folder' || empty ( $ this -> arrValidFileTypes ) || \ in_array ( $ objRoot -> extension , $ this -> arrValidFileTypes ) ) { $ arrFound [ ] = $ objRoot -> path ; } $ arrPaths [ ] = ( $ objRoot -> type == 'folder' ) ? $ objRoot -> path : \ dirname ( $ objRoot -> path ) ; } } } elseif ( $ this -> User -> isAdmin ) { // Show all files to admins while ( $ objRoot -> next ( ) ) { if ( $ objRoot -> type == 'folder' || empty ( $ this -> arrValidFileTypes ) || \ in_array ( $ objRoot -> extension , $ this -> arrValidFileTypes ) ) { $ arrFound [ ] = $ objRoot -> path ; } $ arrPaths [ ] = ( $ objRoot -> type == 'folder' ) ? $ objRoot -> path : \ dirname ( $ objRoot -> path ) ; } } else { if ( \ is_array ( $ this -> User -> filemounts ) ) { while ( $ objRoot -> next ( ) ) { // Show only mounted folders to regular users foreach ( $ this -> User -> filemounts as $ path ) { if ( strncmp ( $ path . '/' , $ objRoot -> path . '/' , \ strlen ( $ path ) + 1 ) === 0 ) { if ( $ objRoot -> type == 'folder' || empty ( $ this -> arrValidFileTypes ) || \ in_array ( $ objRoot -> extension , $ this -> arrValidFileTypes ) ) { $ arrFound [ ] = $ objRoot -> path ; } $ arrPaths [ ] = ( $ objRoot -> type == 'folder' ) ? $ objRoot -> path : \ dirname ( $ objRoot -> path ) ; } } } } } $ GLOBALS [ 'TL_DCA' ] [ 'tl_files' ] [ 'list' ] [ 'sorting' ] [ 'root' ] = array_unique ( $ arrPaths ) ; } } catch ( \ Exception $ e ) { } } $ strNode = $ objSessionBag -> get ( 'tl_files_picker' ) ; // Unset the node if it is not within the path (see #5899) if ( $ strNode != '' && $ this -> path != '' ) { if ( strncmp ( $ strNode . '/' , $ this -> path . '/' , \ strlen ( $ this -> path ) + 1 ) !== 0 ) { $ objSessionBag -> remove ( 'tl_files_picker' ) ; } } // Add the breadcrumb menu if ( Input :: get ( 'do' ) != 'files' ) { Backend :: addFilesBreadcrumb ( 'tl_files_picker' ) ; } $ rootDir = System :: getContainer ( ) -> getParameter ( 'kernel.project_dir' ) ; // Root nodes (breadcrumb menu) if ( ! empty ( $ GLOBALS [ 'TL_DCA' ] [ 'tl_files' ] [ 'list' ] [ 'sorting' ] [ 'root' ] ) ) { $ root = $ GLOBALS [ 'TL_DCA' ] [ 'tl_files' ] [ 'list' ] [ 'sorting' ] [ 'root' ] ; // Allow only those roots that are within the custom path if ( $ this -> path != '' ) { $ root = array_intersect ( preg_grep ( '/^' . preg_quote ( $ this -> path , '/' ) . '(?:$|\/)/' , $ root ) , $ root ) ; if ( empty ( $ root ) ) { // Set all folders inside the custom path as root nodes $ root = array_map ( function ( $ el ) { return $ this -> path . '/' . $ el ; } , scan ( $ rootDir . '/' . $ this -> path ) ) ; // Hide the breadcrumb $ GLOBALS [ 'TL_DCA' ] [ 'tl_file' ] [ 'list' ] [ 'sorting' ] [ 'breadcrumb' ] = '' ; } } $ nodes = $ this -> eliminateNestedPaths ( $ root ) ; foreach ( $ nodes as $ node ) { $ tree .= $ this -> renderFiletree ( $ rootDir . '/' . $ node , 0 , true , true , $ arrFound ) ; } } // Show a custom path (see #4926) elseif ( $ this -> path != '' ) { $ tree .= $ this -> renderFiletree ( $ rootDir . '/' . $ this -> path , 0 , false , $ this -> isProtectedPath ( $ this -> path ) , $ arrFound ) ; } // Start from root elseif ( $ this -> User -> isAdmin ) { $ tree .= $ this -> renderFiletree ( $ rootDir . '/' . Config :: get ( 'uploadPath' ) , 0 , false , true , $ arrFound ) ; } // Show mounted files to regular users else { $ nodes = $ this -> eliminateNestedPaths ( $ this -> User -> filemounts ) ; foreach ( $ nodes as $ node ) { $ tree .= $ this -> renderFiletree ( $ rootDir . '/' . $ node , 0 , true , true , $ arrFound ) ; } } // Select all checkboxes if ( $ this -> fieldType == 'checkbox' ) { $ strReset = "\n" . '    <li class="tl_folder"><div class="tl_left">&nbsp;</div> <div class="tl_right"><label for="check_all_' . $ this -> strId . '" class="tl_change_selected">' . $ GLOBALS [ 'TL_LANG' ] [ 'MSC' ] [ 'selectAll' ] . '</label> <input type="checkbox" id="check_all_' . $ this -> strId . '" class="tl_tree_checkbox" value="" onclick="Backend.toggleCheckboxGroup(this,\'' . $ this -> strName . '\')"></div><div style="clear:both"></div></li>' ; } // Reset radio button selection else { $ strReset = "\n" . '    <li class="tl_folder"><div class="tl_left">&nbsp;</div> <div class="tl_right"><label for="reset_' . $ this -> strId . '" class="tl_change_selected">' . $ GLOBALS [ 'TL_LANG' ] [ 'MSC' ] [ 'resetSelected' ] . '</label> <input type="radio" name="' . $ this -> strName . '" id="reset_' . $ this -> strName . '" class="tl_tree_radio" value="" onfocus="Backend.getScrollOffset()"></div><div style="clear:both"></div></li>' ; } // Return the tree return '<ul class="tl_listing tree_view picker_selector' . ( ( $ this -> strClass != '' ) ? ' ' . $ this -> strClass : '' ) . '" id="' . $ this -> strId . '" data-callback="reloadFiletree">
    <li class="tl_folder_top"><div class="tl_left">' . Image :: getHtml ( $ GLOBALS [ 'TL_DCA' ] [ 'tl_files' ] [ 'list' ] [ 'sorting' ] [ 'icon' ] ? : 'filemounts.svg' ) . ' ' . $ GLOBALS [ 'TL_LANG' ] [ 'MOD' ] [ 'files' ] [ 0 ] . '</div> <div class="tl_right">&nbsp;</div><div style="clear:both"></div></li><li class="parent" id="' . $ this -> strId . '_parent"><ul>' . $ tree . $ strReset . '
  </ul></li></ul>' ; }
Generate the widget and return it as string

@return string
Generate the widget and return it as string