<commit_before><?php
namespace Crud\Listener;

use Cake\Core\Configure;
use Cake\Event\Event;
use Cake\Network\Exception\BadRequestException;
use Cake\Network\Request;
use Cake\ORM\Entity;
use Cake\Utility\Hash;
use Cake\Utility\String;
use Crud\Event\Subject;

/**
 * Enabled Crud to respond in a computer readable format like JSON or XML
 *
 * It tries to enforce some REST principles and keep some string conventions
 * in the output format
 *
 * Licensed under The MIT License
 * For full copyright and license information, please see the LICENSE.txt
 */
class ApiListener extends BaseListener {

/**
 * Default configuration
 *
 * @var array
 */
	protected $_defaultConfig = [
		'viewClasses' => [
			'json' => 'Json',
			'xml' => 'Xml'
		],
		'detectors' => [
			'json' => ['ext' => 'json', 'accepts' => 'application/json'],
			'xml' => ['ext' => 'xml', 'accepts' => 'text/xml']
		],
		'exception' => [
			'type' => 'default',
			'class' => 'Cake\Network\Exception\BadRequestException',
			'message' => 'Unknown error',
			'code' => 0
		]
	];

/**
 * Returns a list of all events that will fire in the controller during its lifecycle.
 * You can override this function to add you own listener callbacks
 *
 * We attach at priority 10 so normal bound events can run before us
 *
 * @return array
 */
	public function implementedEvents() {
		$this->setupDetectors();

		if (!$this->_checkRequestType('api')) {
			return [];
		}

		return [
			'Crud.beforeHandle' => ['callable' => [$this, 'beforeHandle'], 'priority' => 10],
			'Crud.setFlash' => ['callable' => [$this, 'setFlash'], 'priority' => 5],

			'Crud.beforeRender' => ['callable' => [$this, 'respond'], 'priority' => 100],
			'Crud.beforeRedirect' => ['callable' => [$this, 'respond'], 'priority' => 100]
		];
	}

/**
 * setup
 *
 * Called when the listener is created
 *
 * @return void
 */
	public function setup() {
		if (!$this->_checkRequestType('api')) {
			return;
		}

		$this->registerExceptionHandler();
	}

/**
 * beforeHandle
 *
 * Called before the crud action is executed
 *
 * @param \Cake\Event\Event $event Event
 * @return void
 */
	public function beforeHandle(Event $event) {
		$this->_checkRequestMethods();
	}

/**
 * Handle response
 *
 * @param \Cake\Event\Event $event Event
 * @return \Cake\Network\Response
 */
	public function respond(Event $event) {
		$key = $event->subject->success ? 'success' : 'error';
		$apiConfig = $this->_action()->config('api.' . $key);

		if (isset($apiConfig['exception'])) {
			return $this->_exceptionResponse($event, $apiConfig['exception']);
		}

		$response = $this->render($event->subject);
		$response->statusCode($apiConfig['code']);

		return $response;
	}

/**
 * Check for allowed HTTP request types
 *
 * @throws \Cake\Network\Exception\BadRequestException
 * @return bool
 */
	protected function _checkRequestMethods() {
		$action = $this->_action();
		$apiConfig = $action->config('api');

		if (!isset($apiConfig['methods'])) {
			return false;
		}

		$request = $this->_request();
		foreach ($apiConfig['methods'] as $method) {
			if ($request->is($method)) {
				return true;
			}
		}

		throw new BadRequestException('Wrong request method');
	}

/**
 * Register the Crud exception handler
 *
 * @return void
 */
	public function registerExceptionHandler() {
		Configure::write('Error.exceptionRenderer', 'Crud\Error\ExceptionRenderer');
	}

/**
 * Throw an exception based on API configuration
 *
 * @param \Cake\Event\Event $Event Event
 * @param array $exceptionConfig Exception config
 * @return void
 * @throws \Exception
 */
	protected function _exceptionResponse(Event $Event, $exceptionConfig) {
		$exceptionConfig = array_merge($this->config('exception'), $exceptionConfig);

		$class = $exceptionConfig['class'];

		// @codingStandardsIgnoreStart
		if ($exceptionConfig['type'] === 'validate') {
			throw new $class($Event->subject->entity);
		}

		throw new $class($exceptionConfig['message'], $exceptionConfig['code']);
		// @codingStandardsIgnoreEnd
	}

/**
 * Selects an specific Crud view class to render the output
 *
 * @param \Crud\Event\Subject $subject Subject
 * @return \Cake\Network\Response
 */
	public function render(Subject $subject) {
		$this->injectViewClasses();
		$this->_ensureSuccess($subject);
		$this->_ensureData($subject);
		$this->_ensureSerialize();

		$controller = $this->_controller();

		if (!empty($controller->RequestHandler->ext)) {
			$controller->RequestHandler->renderAs($controller, $controller->RequestHandler->ext);
		}

		return $controller->render();
	}

/**
 * Ensure _serialize is set in the view
 *
 * @return void<commit_msg>Ignoring lines doesn't seem to work as expected with phpcs 1.5.6<commit_after><?php
namespace Crud\Listener;

use Cake\Core\Configure;
use Cake\Event\Event;
use Cake\Network\Exception\BadRequestException;
use Cake\Network\Request;
use Cake\ORM\Entity;
use Cake\Utility\Hash;
use Cake\Utility\String;
use Crud\Event\Subject;

/**
 * Enabled Crud to respond in a computer readable format like JSON or XML
 *
 * It tries to enforce some REST principles and keep some string conventions
 * in the output format
 *
 * Licensed under The MIT License
 * For full copyright and license information, please see the LICENSE.txt
 */
class ApiListener extends BaseListener {

/**
 * Default configuration
 *
 * @var array
 */
	protected $_defaultConfig = [
		'viewClasses' => [
			'json' => 'Json',
			'xml' => 'Xml'
		],
		'detectors' => [
			'json' => ['ext' => 'json', 'accepts' => 'application/json'],
			'xml' => ['ext' => 'xml', 'accepts' => 'text/xml']
		],
		'exception' => [
			'type' => 'default',
			'class' => 'Cake\Network\Exception\BadRequestException',
			'message' => 'Unknown error',
			'code' => 0
		]
	];

/**
 * Returns a list of all events that will fire in the controller during its lifecycle.
 * You can override this function to add you own listener callbacks
 *
 * We attach at priority 10 so normal bound events can run before us
 *
 * @return array
 */
	public function implementedEvents() {
		$this->setupDetectors();

		if (!$this->_checkRequestType('api')) {
			return [];
		}

		return [
			'Crud.beforeHandle' => ['callable' => [$this, 'beforeHandle'], 'priority' => 10],
			'Crud.setFlash' => ['callable' => [$this, 'setFlash'], 'priority' => 5],

			'Crud.beforeRender' => ['callable' => [$this, 'respond'], 'priority' => 100],
			'Crud.beforeRedirect' => ['callable' => [$this, 'respond'], 'priority' => 100]
		];
	}

/**
 * setup
 *
 * Called when the listener is created
 *
 * @return void
 */
	public function setup() {
		if (!$this->_checkRequestType('api')) {
			return;
		}

		$this->registerExceptionHandler();
	}

/**
 * beforeHandle
 *
 * Called before the crud action is executed
 *
 * @param \Cake\Event\Event $event Event
 * @return void
 */
	public function beforeHandle(Event $event) {
		$this->_checkRequestMethods();
	}

/**
 * Handle response
 *
 * @param \Cake\Event\Event $event Event
 * @return \Cake\Network\Response
 */
	public function respond(Event $event) {
		$key = $event->subject->success ? 'success' : 'error';
		$apiConfig = $this->_action()->config('api.' . $key);

		if (isset($apiConfig['exception'])) {
			return $this->_exceptionResponse($event, $apiConfig['exception']);
		}

		$response = $this->render($event->subject);
		$response->statusCode($apiConfig['code']);

		return $response;
	}

/**
 * Check for allowed HTTP request types
 *
 * @throws \Cake\Network\Exception\BadRequestException
 * @return bool
 */
	protected function _checkRequestMethods() {
		$action = $this->_action();
		$apiConfig = $action->config('api');

		if (!isset($apiConfig['methods'])) {
			return false;
		}

		$request = $this->_request();
		foreach ($apiConfig['methods'] as $method) {
			if ($request->is($method)) {
				return true;
			}
		}

		throw new BadRequestException('Wrong request method');
	}

/**
 * Register the Crud exception handler
 *
 * @return void
 */
	public function registerExceptionHandler() {
		Configure::write('Error.exceptionRenderer', 'Crud\Error\ExceptionRenderer');
	}

/**
 * Throw an exception based on API configuration
 *
 * @param \Cake\Event\Event $Event Event
 * @param array $exceptionConfig Exception config
 * @return void
 * @throws \Exception
 */
	protected function _exceptionResponse(Event $Event, $exceptionConfig) {
		$exceptionConfig = array_merge($this->config('exception'), $exceptionConfig);

		$class = $exceptionConfig['class'];

		if ($exceptionConfig['type'] === 'validate') {
			$exception = new $class($Event->subject->entity);
			throw $exception;
		}

		$exception = new $class($exceptionConfig['message'], $exceptionConfig['code']);
		throw $exception;
	}

/**
 * Selects an specific Crud view class to render the output
 *
 * @param \Crud\Event\Subject $subject Subject
 * @return \Cake\Network\Response
 */
	public function render(Subject $subject) {
		$this->injectViewClasses();
		$this->_ensureSuccess($subject);
		$this->_ensureData($subject);
		$this->_ensureSerialize();

		$controller = $this->_controller();

		if (!empty($controller->RequestHandler->ext)) {
			$controller->RequestHandler->renderAs($controller, $controller->RequestHandler->ext);
		}

		return $controller->render();
	}

/**
 * Ensure _serialize is set in the view
 *
 * @return void
{'fraction_non_alphanumeric': 0.1642610943558811, 'fraction_numerical': 0.002908229211546747, 'mean_word_length': 4.112885462555066, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 121, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 8}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7292925', 'n_tokens_mistral': 3046, 'n_tokens_neox': 2784, 'n_words': 745}