Mercurial > hg > isophonics-drupal-site
comparison vendor/psy/psysh/src/ExecutionLoop/RunkitReloader.php @ 13:5fb285c0d0e3
Update Drupal core to 8.4.7 via Composer. Security update; I *think* we've
been lucky to get away with this so far, as we don't support self-registration
which seems to be used by the so-called "drupalgeddon 2" attack that 8.4.5
was vulnerable to.
author | Chris Cannam |
---|---|
date | Mon, 23 Apr 2018 09:33:26 +0100 |
parents | |
children | 129ea1e6d783 |
comparison
equal
deleted
inserted
replaced
12:7a779792577d | 13:5fb285c0d0e3 |
---|---|
1 <?php | |
2 | |
3 /* | |
4 * This file is part of Psy Shell. | |
5 * | |
6 * (c) 2012-2018 Justin Hileman | |
7 * | |
8 * For the full copyright and license information, please view the LICENSE | |
9 * file that was distributed with this source code. | |
10 */ | |
11 | |
12 namespace Psy\ExecutionLoop; | |
13 | |
14 use Psy\Exception\ParseErrorException; | |
15 use Psy\ParserFactory; | |
16 use Psy\Shell; | |
17 | |
18 /** | |
19 * A runkit-based code reloader, which is pretty much magic. | |
20 */ | |
21 class RunkitReloader extends AbstractListener | |
22 { | |
23 private $parser; | |
24 private $timestamps = []; | |
25 | |
26 /** | |
27 * Only enabled if Runkit is installed. | |
28 * | |
29 * @return bool | |
30 */ | |
31 public static function isSupported() | |
32 { | |
33 return extension_loaded('runkit'); | |
34 } | |
35 | |
36 /** | |
37 * Construct a Runkit Reloader. | |
38 * | |
39 * @todo Pass in Parser Factory instance for dependency injection? | |
40 */ | |
41 public function __construct() | |
42 { | |
43 $parserFactory = new ParserFactory(); | |
44 $this->parser = $parserFactory->createParser(); | |
45 } | |
46 | |
47 /** | |
48 * Reload code on input. | |
49 * | |
50 * @param Shell $shell | |
51 * @param string $input | |
52 */ | |
53 public function onInput(Shell $shell, $input) | |
54 { | |
55 $this->reload($shell); | |
56 } | |
57 | |
58 /** | |
59 * Look through included files and update anything with a new timestamp. | |
60 * | |
61 * @param Shell $shell | |
62 */ | |
63 private function reload(Shell $shell) | |
64 { | |
65 clearstatcache(); | |
66 $modified = []; | |
67 | |
68 foreach (get_included_files() as $file) { | |
69 $timestamp = filemtime($file); | |
70 | |
71 if (!isset($this->timestamps[$file])) { | |
72 $this->timestamps[$file] = $timestamp; | |
73 continue; | |
74 } | |
75 | |
76 if ($this->timestamps[$file] === $timestamp) { | |
77 continue; | |
78 } | |
79 | |
80 if (!$this->lintFile($file)) { | |
81 $msg = sprintf('Modified file "%s" could not be reloaded', $file); | |
82 $shell->writeException(new ParseErrorException($msg)); | |
83 continue; | |
84 } | |
85 | |
86 $modified[] = $file; | |
87 $this->timestamps[$file] = $timestamp; | |
88 } | |
89 | |
90 // switch (count($modified)) { | |
91 // case 0: | |
92 // return; | |
93 | |
94 // case 1: | |
95 // printf("Reloading modified file: \"%s\"\n", str_replace(getcwd(), '.', $file)); | |
96 // break; | |
97 | |
98 // default: | |
99 // printf("Reloading %d modified files\n", count($modified)); | |
100 // break; | |
101 // } | |
102 | |
103 foreach ($modified as $file) { | |
104 runkit_import($file, ( | |
105 RUNKIT_IMPORT_FUNCTIONS | | |
106 RUNKIT_IMPORT_CLASSES | | |
107 RUNKIT_IMPORT_CLASS_METHODS | | |
108 RUNKIT_IMPORT_CLASS_CONSTS | | |
109 RUNKIT_IMPORT_CLASS_PROPS | | |
110 RUNKIT_IMPORT_OVERRIDE | |
111 )); | |
112 } | |
113 } | |
114 | |
115 /** | |
116 * Should this file be re-imported? | |
117 * | |
118 * Use PHP-Parser to ensure that the file is valid PHP. | |
119 * | |
120 * @param string $file | |
121 * | |
122 * @return bool | |
123 */ | |
124 private function lintFile($file) | |
125 { | |
126 // first try to parse it | |
127 try { | |
128 $this->parser->parse(file_get_contents($file)); | |
129 } catch (\Exception $e) { | |
130 return false; | |
131 } | |
132 | |
133 return true; | |
134 } | |
135 } |