core-bundle/src/Resources/contao/drivers/DC_Folder.php
public function source()
	{
		$this->isValid($this->intId);

		if (is_dir($this->strRootDir .'/'. $this->intId))
		{
			throw new InternalServerErrorException('Folder "' . $this->intId . '" cannot be edited.');
		}
		elseif (!file_exists($this->strRootDir .'/'. $this->intId))
		{
			throw new InternalServerErrorException('File "' . $this->intId . '" does not exist.');
		}

		$objFile = new File($this->intId);

		// Check whether file type is editable
		if (!\in_array($objFile->extension, StringUtil::trimsplit(',', strtolower(Config::get('editableFiles')))))
		{
			throw new AccessDeniedException('File type "' . $objFile->extension . '" (' . $this->intId . ') is not allowed to be edited.');
		}

		$objMeta = null;
		$objVersions = null;

		// Add the versioning routines
		if ($this->blnIsDbAssisted && Dbafs::shouldBeSynchronized($this->intId))
		{
			$objMeta = FilesModel::findByPath($objFile->value);

			if ($objMeta === null)
			{
				$objMeta = Dbafs::addResource($objFile->value);
			}

			$objVersions = new Versions($this->strTable, $objMeta->id);

			if (!$GLOBALS['TL_DCA'][$this->strTable]['config']['hideVersionMenu'])
			{
				// Compare versions
				if (Input::get('versions'))
				{
					$objVersions->compare();
				}

				// Restore a version
				if (Input::post('FORM_SUBMIT') == 'tl_version' && Input::post('version') != '')
				{
					$objVersions->restore(Input::post('version'));

					// Purge the script cache (see #7005)
					if ($objFile->extension == 'css' || $objFile->extension == 'scss' || $objFile->extension == 'less')
					{
						$this->import(Automator::class, 'Automator');
						$this->Automator->purgeScriptCache();
					}

					$this->reload();
				}
			}

			$objVersions->initialize();
		}

		$strContent = $objFile->getContent();

		if ($objFile->extension == 'svgz')
		{
			$strContent = gzdecode($strContent);
		}

		// Process the request
		if (Input::post('FORM_SUBMIT') == 'tl_files')
		{
			$strSource = System::getContainer()->get('request_stack')->getCurrentRequest()->request->get('source');

			// Save the file
			if (md5($strContent) != md5($strSource))
			{
				if ($objFile->extension == 'svgz')
				{
					$strSource = gzencode($strSource);
				}

				// Write the file
				$objFile->write($strSource);
				$objFile->close();

				// Update the database
				if ($this->blnIsDbAssisted && $objMeta !== null)
				{
					/** @var FilesModel $objMeta */
					$objMeta->hash = $objFile->hash;
					$objMeta->save();

					$objVersions->create();
				}

				// Purge the script cache (see #7005)
				if (\in_array($objFile->extension, array('css', 'scss', 'less', 'js')))
				{
					$this->import(Automator::class, 'Automator');
					$this->Automator->purgeScriptCache();
				}
			}

			if (isset($_POST['saveNclose']))
			{
				System::setCookie('BE_PAGE_OFFSET', 0, 0);
				$this->redirect($this->getReferer());
			}

			$this->reload();
		}

		$codeEditor = '';

		// Prepare the code editor
		if (Config::get('useCE'))
		{
			$objTemplate = new BackendTemplate('be_ace');
			$objTemplate->selector = 'ctrl_source';
			$objTemplate->type = $objFile->extension;

			$codeEditor = $objTemplate->parse();
		}

		// Versions overview
		if ($GLOBALS['TL_DCA'][$this->strTable]['config']['enableVersioning'] && !$GLOBALS['TL_DCA'][$this->strTable]['config']['hideVersionMenu'] && $this->blnIsDbAssisted && $objVersions !== null)
		{
			$version = $objVersions->renderDropdown();
		}
		else
		{
			$version = '';
		}

		// Submit buttons
		$arrButtons = array();
		$arrButtons['save'] = '<button type="submit" name="save" id="save" class="tl_submit" accesskey="s">'.$GLOBALS['TL_LANG']['MSC']['save'].'</button>';
		$arrButtons['saveNclose'] = '<button type="submit" name="saveNclose" id="saveNclose" class="tl_submit" accesskey="c">'.$GLOBALS['TL_LANG']['MSC']['saveNclose'].'</button>';

		// Call the buttons_callback (see #4691)
		if (\is_array($GLOBALS['TL_DCA'][$this->strTable]['edit']['buttons_callback']))
		{
			foreach ($GLOBALS['TL_DCA'][$this->strTable]['edit']['buttons_callback'] as $callback)
			{
				if (\is_array($callback))
				{
					$this->import($callback[0]);
					$arrButtons = $this->{$callback[0]}->{$callback[1]}($arrButtons, $this);
				}
				elseif (\is_callable($callback))
				{
					$arrButtons = $callback($arrButtons, $this);
				}
			}
		}

		if (\count($arrButtons) < 3)
		{
			$strButtons = implode(' ', $arrButtons);
		}
		else
		{
			$strButtons = array_shift($arrButtons) . ' ';
			$strButtons .= '<div class="split-button">';
			$strButtons .= array_shift($arrButtons) . '<button type="button" id="sbtog">' . Image::getHtml('navcol.svg') . '</button> <ul class="invisible">';

			foreach ($arrButtons as $strButton)
			{
				$strButtons .= '<li>' . $strButton . '</li>';
			}

			$strButtons .= '</ul></div>';
		}

		// Add the form
		return $version . Message::generate() . '
<div id="tl_buttons">
<a href="'.$this->getReferer(true).'" class="header_back" title="'.StringUtil::specialchars($GLOBALS['TL_LANG']['MSC']['backBTTitle']).'" accesskey="b" onclick="Backend.getScrollOffset()">'.$GLOBALS['TL_LANG']['MSC']['backBT'].'</a>
</div>
<form action="'.ampersand(Environment::get('request'), true).'" id="tl_files" class="tl_form tl_edit_form" method="post">
<div class="tl_formbody_edit">
<input type="hidden" name="FORM_SUBMIT" value="tl_files">
<input type="hidden" name="REQUEST_TOKEN" value="'.REQUEST_TOKEN.'">
<div class="tl_tbox">
  <div class="widget">
    <h3><label for="ctrl_source">'.$GLOBALS['TL_LANG']['tl_files']['editor'][0].'</label></h3>
    <textarea name="source" id="ctrl_source" class="tl_textarea monospace" rows="12" cols="80" style="height:400px" onfocus="Backend.getScrollOffset()">' . "\n" . htmlspecialchars($strContent) . '</textarea>' . ((Config::get('showHelp') && \strlen($GLOBALS['TL_LANG']['tl_files']['editor'][1])) ? '
    <p class="tl_help tl_tip">'.$GLOBALS['TL_LANG']['tl_files']['editor'][1].'</p>' : '') . '
  </div>
</div>
</div>
<div class="tl_formbody_submit">
<div class="tl_submit_container">
  ' . $strButtons . '
</div>
</div>
</form>' . "\n\n" . $codeEditor;
	}
public function source()
	{
		$this->isValid($this->intId);

		if (is_dir($this->strRootDir .'/'. $this->intId))
		{
			throw new InternalServerErrorException('Folder "' . $this->intId . '" cannot be edited.');
		}
		elseif (!file_exists($this->strRootDir .'/'. $this->intId))
		{
			throw new InternalServerErrorException('File "' . $this->intId . '" does not exist.');
		}

		$objFile = new File($this->intId);

		// Check whether file type is editable
		if (!\in_array($objFile->extension, StringUtil::trimsplit(',', strtolower(Config::get('editableFiles')))))
		{
			throw new AccessDeniedException('File type "' . $objFile->extension . '" (' . $this->intId . ') is not allowed to be edited.');
		}

		$objMeta = null;
		$objVersions = null;

		// Add the versioning routines
		if ($this->blnIsDbAssisted && Dbafs::shouldBeSynchronized($this->intId))
		{
			$objMeta = FilesModel::findByPath($objFile->value);

			if ($objMeta === null)
			{
				$objMeta = Dbafs::addResource($objFile->value);
			}

			$objVersions = new Versions($this->strTable, $objMeta->id);

			if (!$GLOBALS['TL_DCA'][$this->strTable]['config']['hideVersionMenu'])
			{
				// Compare versions
				if (Input::get('versions'))
				{
					$objVersions->compare();
				}

				// Restore a version
				if (Input::post('FORM_SUBMIT') == 'tl_version' && Input::post('version') != '')
				{
					$objVersions->restore(Input::post('version'));

					// Purge the script cache (see #7005)
					if ($objFile->extension == 'css' || $objFile->extension == 'scss' || $objFile->extension == 'less')
					{
						$this->import(Automator::class, 'Automator');
						$this->Automator->purgeScriptCache();
					}

					$this->reload();
				}
			}

			$objVersions->initialize();
		}

		$strContent = $objFile->getContent();

		if ($objFile->extension == 'svgz')
		{
			$strContent = gzdecode($strContent);
		}

		// Process the request
		if (Input::post('FORM_SUBMIT') == 'tl_files')
		{
			$strSource = System::getContainer()->get('request_stack')->getCurrentRequest()->request->get('source');

			// Save the file
			if (md5($strContent) != md5($strSource))
			{
				if ($objFile->extension == 'svgz')
				{
					$strSource = gzencode($strSource);
				}

				// Write the file
				$objFile->write($strSource);
				$objFile->close();

				// Update the database
				if ($this->blnIsDbAssisted && $objMeta !== null)
				{
					/** @var FilesModel $objMeta */
					$objMeta->hash = $objFile->hash;
					$objMeta->save();

					$objVersions->create();
				}

				// Purge the script cache (see #7005)
				if (\in_array($objFile->extension, array('css', 'scss', 'less', 'js')))
				{
					$this->import(Automator::class, 'Automator');
					$this->Automator->purgeScriptCache();
				}
			}

			if (isset($_POST['saveNclose']))
			{
				System::setCookie('BE_PAGE_OFFSET', 0, 0);
				$this->redirect($this->getReferer());
			}

			$this->reload();
		}

		$codeEditor = '';

		// Prepare the code editor
		if (Config::get('useCE'))
		{
			$objTemplate = new BackendTemplate('be_ace');
			$objTemplate->selector = 'ctrl_source';
			$objTemplate->type = $objFile->extension;

			$codeEditor = $objTemplate->parse();
		}

		// Versions overview
		if ($GLOBALS['TL_DCA'][$this->strTable]['config']['enableVersioning'] && !$GLOBALS['TL_DCA'][$this->strTable]['config']['hideVersionMenu'] && $this->blnIsDbAssisted && $objVersions !== null)
		{
			$version = $objVersions->renderDropdown();
		}
		else
		{
			$version = '';
		}

		// Submit buttons
		$arrButtons = array();
		$arrButtons['save'] = '<button type="submit" name="save" id="save" class="tl_submit" accesskey="s">'.$GLOBALS['TL_LANG']['MSC']['save'].'</button>';
		$arrButtons['saveNclose'] = '<button type="submit" name="saveNclose" id="saveNclose" class="tl_submit" accesskey="c">'.$GLOBALS['TL_LANG']['MSC']['saveNclose'].'</button>';

		// Call the buttons_callback (see #4691)
		if (\is_array($GLOBALS['TL_DCA'][$this->strTable]['edit']['buttons_callback']))
		{
			foreach ($GLOBALS['TL_DCA'][$this->strTable]['edit']['buttons_callback'] as $callback)
			{
				if (\is_array($callback))
				{
					$this->import($callback[0]);
					$arrButtons = $this->{$callback[0]}->{$callback[1]}($arrButtons, $this);
				}
				elseif (\is_callable($callback))
				{
					$arrButtons = $callback($arrButtons, $this);
				}
			}
		}

		if (\count($arrButtons) < 3)
		{
			$strButtons = implode(' ', $arrButtons);
		}
		else
		{
			$strButtons = array_shift($arrButtons) . ' ';
			$strButtons .= '<div class="split-button">';
			$strButtons .= array_shift($arrButtons) . '<button type="button" id="sbtog">' . Image::getHtml('navcol.svg') . '</button> <ul class="invisible">';

			foreach ($arrButtons as $strButton)
			{
				$strButtons .= '<li>' . $strButton . '</li>';
			}

			$strButtons .= '</ul></div>';
		}

		// Add the form
		return $version . Message::generate() . '
<div id="tl_buttons">
<a href="'.$this->getReferer(true).'" class="header_back" title="'.StringUtil::specialchars($GLOBALS['TL_LANG']['MSC']['backBTTitle']).'" accesskey="b" onclick="Backend.getScrollOffset()">'.$GLOBALS['TL_LANG']['MSC']['backBT'].'</a>
</div>
<form action="'.ampersand(Environment::get('request'), true).'" id="tl_files" class="tl_form tl_edit_form" method="post">
<div class="tl_formbody_edit">
<input type="hidden" name="FORM_SUBMIT" value="tl_files">
<input type="hidden" name="REQUEST_TOKEN" value="'.REQUEST_TOKEN.'">
<div class="tl_tbox">
  <div class="widget">
    <h3><label for="ctrl_source">'.$GLOBALS['TL_LANG']['tl_files']['editor'][0].'</label></h3>
    <textarea name="source" id="ctrl_source" class="tl_textarea monospace" rows="12" cols="80" style="height:400px" onfocus="Backend.getScrollOffset()">' . "\n" . htmlspecialchars($strContent) . '</textarea>' . ((Config::get('showHelp') && \strlen($GLOBALS['TL_LANG']['tl_files']['editor'][1])) ? '
    <p class="tl_help tl_tip">'.$GLOBALS['TL_LANG']['tl_files']['editor'][1].'</p>' : '') . '
  </div>
</div>
</div>
<div class="tl_formbody_submit">
<div class="tl_submit_container">
  ' . $strButtons . '
</div>
</div>
</form>' . "\n\n" . $codeEditor;
	}
Load the source editor

@return string

@throws InternalServerErrorException