Security update for permissions_by_term
[yaffs-website] / vendor / behat / behat / src / Behat / Behat / Context / Snippet / Appender / ContextSnippetAppender.php
1 <?php
2
3 /*
4  * This file is part of the Behat.
5  * (c) Konstantin Kudryashov <ever.zet@gmail.com>
6  *
7  * For the full copyright and license information, please view the LICENSE
8  * file that was distributed with this source code.
9  */
10
11 namespace Behat\Behat\Context\Snippet\Appender;
12
13 use Behat\Behat\Snippet\AggregateSnippet;
14 use Behat\Behat\Snippet\Appender\SnippetAppender;
15 use Behat\Testwork\Filesystem\FilesystemLogger;
16 use ReflectionClass;
17
18 /**
19  * Appends context-related snippets to their context classes.
20  *
21  * @author Konstantin Kudryashov <ever.zet@gmail.com>
22  */
23 final class ContextSnippetAppender implements SnippetAppender
24 {
25     /**
26      * @const PendingException class
27      */
28     const PENDING_EXCEPTION_CLASS = 'Behat\Behat\Tester\Exception\PendingException';
29
30     /**
31      * @var FilesystemLogger
32      */
33     private $logger;
34
35     /**
36      * Initializes appender.
37      *
38      * @param null|FilesystemLogger $logger
39      */
40     public function __construct(FilesystemLogger $logger = null)
41     {
42         $this->logger = $logger;
43     }
44
45     /**
46      * {@inheritdoc}
47      */
48     public function supportsSnippet(AggregateSnippet $snippet)
49     {
50         return 'context' === $snippet->getType();
51     }
52
53     /**
54      * {@inheritdoc}
55      */
56     public function appendSnippet(AggregateSnippet $snippet)
57     {
58         foreach ($snippet->getTargets() as $contextClass) {
59             $reflection = new ReflectionClass($contextClass);
60             $content = file_get_contents($reflection->getFileName());
61
62             foreach ($snippet->getUsedClasses() as $class) {
63                 if (!$this->isClassImported($class, $content)) {
64                     $content = $this->importClass($class, $content);
65                 }
66             }
67
68             $generated = rtrim(strtr($snippet->getSnippet(), array('\\' => '\\\\', '$' => '\\$')));
69             $content = preg_replace('/}\s*$/', "\n" . $generated . "\n}\n", $content);
70             $path = $reflection->getFileName();
71
72             file_put_contents($path, $content);
73
74             $this->logSnippetAddition($snippet, $path);
75         }
76     }
77
78     /**
79      * Checks if context file already has class in it.
80      *
81      * @param string $class
82      * @param string $contextFileContent
83      *
84      * @return Boolean
85      */
86     private function isClassImported($class, $contextFileContent)
87     {
88         $classImportRegex = sprintf(
89             '@use[^;]*%s.*;@ms',
90             preg_quote($class, '@')
91         );
92
93         return 1 === preg_match($classImportRegex, $contextFileContent);
94     }
95
96     /**
97      * Adds use-block for class.
98      *
99      * @param string $class
100      * @param string $contextFileContent
101      *
102      * @return string
103      */
104     private function importClass($class, $contextFileContent)
105     {
106         $replaceWith = "\$1" . 'use ' . $class . ";\n\$2;";
107
108         return preg_replace('@^(.*)(use\s+[^;]*);@m', $replaceWith, $contextFileContent, 1);
109     }
110
111     /**
112      * Logs snippet addition to the provided path (if logger is given).
113      *
114      * @param AggregateSnippet $snippet
115      * @param string           $path
116      */
117     private function logSnippetAddition(AggregateSnippet $snippet, $path)
118     {
119         if (!$this->logger) {
120             return;
121         }
122
123         $steps = $snippet->getSteps();
124         $reason = sprintf("`<comment>%s</comment>` definition added", $steps[0]->getText());
125
126         $this->logger->fileUpdated($path, $reason);
127     }
128 }