/** * Construct a new write guard for a request. Only one write guard may be * active at a time. You must explicitly call @{method:dispose} when you are * done with a write guard: * * $guard = new AphrontWriteGuard($callback); * // ... * $guard->dispose(); * * Normally, you do not need to manage guards yourself -- the Aphront stack * handles it for you. * * This class accepts a callback, which will be invoked when a write is * attempted. The callback should validate the presence of a CSRF token in * the request, or abort the request (e.g., by throwing an exception) if a * valid token isn't present. * * @param callable CSRF callback. * @return this * @task manage */ public function __construct($callback) { if (self::$instance) { throw new Exception('An AphrontWriteGuard already exists. Dispose of the previous guard ' . 'before creating a new one.'); } if (self::$allowUnguardedWrites) { throw new Exception('An AphrontWriteGuard is being created in a context which permits ' . 'unguarded writes unconditionally. This is not allowed and indicates ' . 'a serious error.'); } if (!self::$abruptExitlistenerIsInstalled) { self::$abruptExitlistenerIsInstalled = true; $event_listener = new AphrontWriteGuardExitEventListener(); $event_listener->register(); } $this->callback = $callback; self::$instance = $this; }