Security update for permissions_by_term
[yaffs-website] / vendor / behat / behat / src / Behat / Testwork / Call / Handler / RuntimeCallHandler.php
1 <?php
2
3 /*
4  * This file is part of the Behat Testwork.
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\Testwork\Call\Handler;
12
13 use Behat\Testwork\Argument\Validator;
14 use Behat\Testwork\Call\Call;
15 use Behat\Testwork\Call\CallResult;
16 use Behat\Testwork\Call\Exception\CallErrorException;
17 use Exception;
18
19 /**
20  * Handles calls in the current runtime.
21  *
22  * @author Konstantin Kudryashov <ever.zet@gmail.com>
23  */
24 final class RuntimeCallHandler implements CallHandler
25 {
26     /**
27      * @var integer
28      */
29     private $errorReportingLevel;
30     /**
31      * @var bool
32      */
33     private $obStarted = false;
34     /**
35      * @var Validator
36      */
37     private $validator;
38
39     /**
40      * Initializes executor.
41      *
42      * @param integer $errorReportingLevel
43      */
44     public function __construct($errorReportingLevel = E_ALL)
45     {
46         $this->errorReportingLevel = $errorReportingLevel;
47         $this->validator = new Validator();
48     }
49
50     /**
51      * {@inheritdoc}
52      */
53     public function supportsCall(Call $call)
54     {
55         return true;
56     }
57
58     /**
59      * {@inheritdoc}
60      */
61     public function handleCall(Call $call)
62     {
63         $this->startErrorAndOutputBuffering($call);
64         $result = $this->executeCall($call);
65         $this->stopErrorAndOutputBuffering();
66
67         return $result;
68     }
69
70     /**
71      * Used as a custom error handler when step is running.
72      *
73      * @see set_error_handler()
74      *
75      * @param integer $level
76      * @param string  $message
77      * @param string  $file
78      * @param integer $line
79      *
80      * @return Boolean
81      *
82      * @throws CallErrorException
83      */
84     public function handleError($level, $message, $file, $line)
85     {
86         if ($this->errorLevelIsNotReportable($level)) {
87             return false;
88         }
89
90         throw new CallErrorException($level, $message, $file, $line);
91     }
92
93     /**
94      * Executes single call.
95      *
96      * @param Call $call
97      *
98      * @return CallResult
99      */
100     private function executeCall(Call $call)
101     {
102         $reflection = $call->getCallee()->getReflection();
103         $callable = $call->getBoundCallable();
104         $arguments = $call->getArguments();
105         $return = $exception = null;
106
107         try {
108             $this->validator->validateArguments($reflection, $arguments);
109             $return = call_user_func_array($callable, $arguments);
110         } catch (Exception $caught) {
111             $exception = $caught;
112         }
113
114         $stdOut = $this->getBufferedStdOut();
115
116         return new CallResult($call, $return, $exception, $stdOut);
117     }
118
119     /**
120      * Returns buffered stdout.
121      *
122      * @return null|string
123      */
124     private function getBufferedStdOut()
125     {
126         return ob_get_length() ? ob_get_contents() : null;
127     }
128
129     /**
130      * Starts error handler and stdout buffering.
131      *
132      * @param Call $call
133      */
134     private function startErrorAndOutputBuffering(Call $call)
135     {
136         $errorReporting = $call->getErrorReportingLevel() ? : $this->errorReportingLevel;
137         set_error_handler(array($this, 'handleError'), $errorReporting);
138         $this->obStarted = ob_start();
139     }
140
141     /**
142      * Stops error handler and stdout buffering.
143      */
144     private function stopErrorAndOutputBuffering()
145     {
146         if ($this->obStarted) {
147             ob_end_clean();
148         }
149         restore_error_handler();
150     }
151
152     /**
153      * Checks if provided error level is not reportable.
154      *
155      * @param integer $level
156      *
157      * @return Boolean
158      */
159     private function errorLevelIsNotReportable($level)
160     {
161         return !(error_reporting() & $level);
162     }
163 }