* @copyright 2010-2023 Ignas Rudaitis * @license http://www.opensource.org/licenses/mit-license.html */ namespace Patchwork\CodeManipulation; require __DIR__ . '/CodeManipulation/Source.php'; require __DIR__ . '/CodeManipulation/Stream.php'; require __DIR__ . '/CodeManipulation/Actions/Generic.php'; require __DIR__ . '/CodeManipulation/Actions/CallRerouting.php'; require __DIR__ . '/CodeManipulation/Actions/CodeManipulation.php'; require __DIR__ . '/CodeManipulation/Actions/Namespaces.php'; require __DIR__ . '/CodeManipulation/Actions/RedefinitionOfInternals.php'; require __DIR__ . '/CodeManipulation/Actions/RedefinitionOfLanguageConstructs.php'; require __DIR__ . '/CodeManipulation/Actions/ConflictPrevention.php'; require __DIR__ . '/CodeManipulation/Actions/RedefinitionOfNew.php'; require __DIR__ . '/CodeManipulation/Actions/Arguments.php'; use Patchwork\Exceptions; use Patchwork\Config; const OUTPUT_DESTINATION = 'php://memory'; const OUTPUT_ACCESS_MODE = 'rb+'; function transform(Source $s) { foreach (State::$actions as $action) { $action($s); } } function transformString($code) { $source = new Source($code); transform($source); return (string) $source; } function transformForEval($code) { $prefix = "file), 'w', false); Stream::fwrite($handle, $source); Stream::fclose($handle); } function availableCached($file) { if (!cacheEnabled()) { return false; } $cached = getCachedPath($file); return file_exists($cached) && filemtime($file) <= filemtime($cached) && Config\getTimestamp() <= filemtime($cached); } function internalToCache($file) { if (!cacheEnabled()) { return false; } return strpos($file, Config\getCachePath() . '/') === 0 || strpos($file, Config\getCachePath() . DIRECTORY_SEPARATOR) === 0; } function getContents($file) { $handle = Stream::fopen($file, 'r', true); if ($handle === false) { return false; } $contents = ''; while (!Stream::feof($handle)) { $contents .= Stream::fread($handle, 8192); } Stream::fclose($handle); return $contents; } function transformAndOpen($file) { foreach (State::$importListeners as $listener) { $listener($file); } if (!internalToCache($file) && availableCached($file)) { return Stream::fopen(getCachedPath($file), 'r', false); } $code = getContents($file); if ($code === false) { return false; } $source = new Source($code); $source->file = $file; transform($source); if (!internalToCache($file) && cacheEnabled()) { storeInCache($source); return transformAndOpen($file); } $resource = fopen(OUTPUT_DESTINATION, OUTPUT_ACCESS_MODE); if ($resource) { fwrite($resource, $source); rewind($resource); } return $resource; } function prime($file) { Stream::fclose(transformAndOpen($file)); } function shouldTransform($file) { return !Config\isBlacklisted($file) || Config\isWhitelisted($file); } function register($actions) { State::$actions = array_merge(State::$actions, (array) $actions); } function onImport($listeners) { State::$importListeners = array_merge(State::$importListeners, (array) $listeners); } class State { static $actions = []; static $importListeners = []; static $cacheIndex = []; static $cacheIndexFile; }