public function up()
{
$affectedViewHelperClassNames = array();
$allPathsAndFilenames = Files::readDirectoryRecursively($this->targetPackageData['path'], '.php', true);
foreach ($allPathsAndFilenames as $pathAndFilename) {
if (substr($pathAndFilename, -14) !== 'ViewHelper.php') {
continue;
}
$fileContents = file_get_contents($pathAndFilename);
$className = (new PhpAnalyzer($fileContents))->extractFullyQualifiedClassName();
if ($className === null) {
$this->showWarning(sprintf('could not extract class name from file "%s"', $pathAndFilename));
continue;
}
/** @noinspection PhpIncludeInspection */
require_once $pathAndFilename;
if (!class_exists($className)) {
$this->showWarning(sprintf('could not load class "%s" extracted from file "%s"', $className, $pathAndFilename));
continue;
}
$instance = new $className();
$escapeOutput = ObjectAccess::getProperty($instance, 'escapeOutput', true);
if ($escapeOutput !== null) {
continue;
}
$affectedViewHelperClassNames[] = $className;
$this->searchAndReplaceRegex('/\\R\\s*class[^\\{]+\\R?\\{(\\s*)(?=.*?\\})/s', '$0' . "\n\t" . '/**' . "\n\t" . ' * NOTE: This property has been introduced via code migration to ensure backwards-compatibility.' . "\n\t" . ' * @see AbstractViewHelper::isOutputEscapingEnabled()' . "\n\t" . ' * @var boolean' . "\n\t" . ' */' . "\n\t" . 'protected $escapeOutput = FALSE;$1', $pathAndFilename);
}
if ($affectedViewHelperClassNames !== array()) {
$this->showWarning('Added "escapeOutput" property to following ViewHelpers:' . PHP_EOL . ' * ' . implode(PHP_EOL . ' * ', $affectedViewHelperClassNames) . PHP_EOL . PHP_EOL . 'If an affected ViewHelper does not render HTML output, you should set this property TRUE in order to ensure sanitization of the output!');
}
$this->addWarningsForAffectedViewHelpers($this->targetPackageData['path']);
}