<commit_before><?php

App::uses('CrudListener', 'Crud.Controller/Crud');

/**
 * 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
 * Redistributions of files must retain the above copyright notice.
 *
 * @copyright <NAME>, 2013
 */
class ApiListener extends CrudListener {

/**
 * Returns a list of all events that will fire in the controller during it's 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() {
		return array(
			'Crud.init' => array('callable' => 'init', 'priority' => 10),
			'Crud.recordNotFound' => array('callable' => 'recordNotFound', 'priority' => 100),
			'Crud.invalidId' => array('callable' => 'invalidId', 'priority' => 100),
			'Crud.beforeRender' => array('callable' => 'beforeRender', 'priority' => 100),
			'Crud.afterSave' => array('callable' => 'afterSave', 'priority' => 100),
			'Crud.afterDelete' => array('callable' => 'afterDelete', 'priority' => 100)
		);
	}

/**
 * Init
 *
 * Called when the listener is started
 *
 * @param CakeEvent $event
 * @return void
 */
	public function init(CakeEvent $event) {
		// Configure a few useful CakeRequest detectors
		$this->_setupDetectors();

		// Don't do anything if we aren't in an API request
		if (!$this->_request->is('api')) {
			return;
		}

		// Make sure that exceptions output in standard Crud format
		App::uses('CrudExceptionRenderer', 'Crud.Error');
		Configure::write('Exception.renderer', 'Crud.CrudExceptionRenderer');

		// Enforce a few REST rules before we do any heavy lifting
		$this->_enforceRequestType($event->subject->action, $event->subject->request);
	}

/**
 * afterSave callback
 *
 * @param CakeEvent $event
 * @return void|CakeResponse
 */
	public function afterSave(CakeEvent $event) {
		// Don't do anything if we aren't in an API request
		if (!$this->_request->is('api')) {
			return;
		}

		// Publish the success based on the CrudSubject's property
		$this->_controller->set('success', $event->subject->success);

		$model = $event->subject->model;
		// If we had an error in our save
		if (!$event->subject->success) {
			$event->subject->response->statusCode(400);
			// Set the data to be the validationErrors from the model
			$this->_controller->set('data', $model->validationErrors);
			return;
		}

		// Push the model ID back as response body if it's not set already
		if (empty($this->_controller->viewVars['data'])) {
			$this->_controller->set('data', array($model->alias => array($model->primaryKey => $event->subject->id)));
		}

		// Render the view
		$this->beforeRender($event);
		$response = $this->_controller->render();

		// REST says newly created objects should get a "201 Created" response code back
		if ($event->subject->created) {
			$response->statusCode(201);
		} else {
			$response->statusCode(301);
		}

		// Send a redirect header for the 'view' action
		$response->header('Location', Router::url(array('action' => 'view', $event->subject->id), true));
		return $response;
	}

/**
 * afterDelete
 *
 * @param CakeEvent $event
 * @return void
 */
	public function afterDelete(CakeEvent $event) {
		// Don't do anything if we aren't in an API request
		if (!$this->_request->is('api')) {
			return;
		}

		$event->stopPropagation();

		$this->beforeRender($event);

		$this->_controller->set('success', $event->subject->success);
		$this->_controller->set('data', null);

		return $this->_controller->render();
	}

/**
 * recordNotFound
 *
 * Always send a HTTP 404 response if something can't be found
 *
 * @param CakeEvent $event
 * @return void
 * @throws NotFoundException If record not found
 */
	public function recordNotFound(CakeEvent $event) {
		if (!$this->_request->is('api')) {
			return;
		}

		throw new NotFoundException();
	}

/**
 * invalidId
 *
 * If the id is invalid, simply send a HTTP 400 response
 *
 * @param CakeEvent $event
 * @return void
 * @throws BadRequestException If invalid id provided
 */
	public function invalidId(CakeEvent $event) {
		if (!$this->_request->is('api')) {
			return;
		}

		throw new BadRequestException('Invalid id');
	}

/**
 * Selects an specific Crud view class to render the output
 *
 * @param CakeEvent $event
 * @return void
 */
	public function beforeRender(CakeEvent $event) {
		if (!$this->_request->is('api')) {
			return;
		}

		// Copy the _serialize configuration from the CrudAction config
		$action = $event->subject->crud->action();
		$serialize = $action->config('serialize');

		$serialize[] = 'success';
		if (method_exists($action, 'viewVar')) {
			$serialize[$action->viewVar()] = 'data';
		} else {
			$serialize[] = 'data';
		}
		$this->_controller->set('_serialize', $serialize);

		// Make sure to use Cruds own View renderer for json and xml
		// @TODO: make the viewClassMap configurable
		$this->_controller->RequestHandler->viewClassMap('json', 'Crud.CrudJson');
		$this->_controller->RequestHandler->viewClassMap('xml', 'Crud.CrudXml');
		$this->_controller->RequestHandler->renderAs($this->_controller, $this->_controller->RequestHandler->ext);
	}

/**
 * Setup detectors for JSON and XML
 *
 * Both detects on two signals:
 *  1) The extension in the request (e.g. /users/index.json)
 *  2) The accepts header from the client
 *
 * There is a combined request detector for both 'json' and 'xml' called
 * 'api'
 *
 * @return void
 */
	protected function _setupDetectors() {<commit_msg>krsort _serialize so success and data always is first in response<commit_after><?php

App::uses('CrudListener', 'Crud.Controller/Crud');

/**
 * 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
 * Redistributions of files must retain the above copyright notice.
 *
 * @copyright <NAME>, 2013
 */
class ApiListener extends CrudListener {

/**
 * Returns a list of all events that will fire in the controller during it's 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() {
		return array(
			'Crud.init' => array('callable' => 'init', 'priority' => 10),
			'Crud.recordNotFound' => array('callable' => 'recordNotFound', 'priority' => 100),
			'Crud.invalidId' => array('callable' => 'invalidId', 'priority' => 100),
			'Crud.beforeRender' => array('callable' => 'beforeRender', 'priority' => 100),
			'Crud.afterSave' => array('callable' => 'afterSave', 'priority' => 100),
			'Crud.afterDelete' => array('callable' => 'afterDelete', 'priority' => 100)
		);
	}

/**
 * Init
 *
 * Called when the listener is started
 *
 * @param CakeEvent $event
 * @return void
 */
	public function init(CakeEvent $event) {
		// Configure a few useful CakeRequest detectors
		$this->_setupDetectors();

		// Don't do anything if we aren't in an API request
		if (!$this->_request->is('api')) {
			return;
		}

		// Make sure that exceptions output in standard Crud format
		App::uses('CrudExceptionRenderer', 'Crud.Error');
		Configure::write('Exception.renderer', 'Crud.CrudExceptionRenderer');

		// Enforce a few REST rules before we do any heavy lifting
		$this->_enforceRequestType($event->subject->action, $event->subject->request);
	}

/**
 * afterSave callback
 *
 * @param CakeEvent $event
 * @return void|CakeResponse
 */
	public function afterSave(CakeEvent $event) {
		// Don't do anything if we aren't in an API request
		if (!$this->_request->is('api')) {
			return;
		}

		// Publish the success based on the CrudSubject's property
		$this->_controller->set('success', $event->subject->success);

		$model = $event->subject->model;
		// If we had an error in our save
		if (!$event->subject->success) {
			$event->subject->response->statusCode(400);
			// Set the data to be the validationErrors from the model
			$this->_controller->set('data', $model->validationErrors);
			return;
		}

		// Push the model ID back as response body if it's not set already
		if (empty($this->_controller->viewVars['data'])) {
			$this->_controller->set('data', array($model->alias => array($model->primaryKey => $event->subject->id)));
		}

		// Render the view
		$this->beforeRender($event);
		$response = $this->_controller->render();

		// REST says newly created objects should get a "201 Created" response code back
		if ($event->subject->created) {
			$response->statusCode(201);
		} else {
			$response->statusCode(301);
		}

		// Send a redirect header for the 'view' action
		$response->header('Location', Router::url(array('action' => 'view', $event->subject->id), true));
		return $response;
	}

/**
 * afterDelete
 *
 * @param CakeEvent $event
 * @return void
 */
	public function afterDelete(CakeEvent $event) {
		// Don't do anything if we aren't in an API request
		if (!$this->_request->is('api')) {
			return;
		}

		$event->stopPropagation();

		$this->beforeRender($event);

		$this->_controller->set('success', $event->subject->success);
		$this->_controller->set('data', null);

		return $this->_controller->render();
	}

/**
 * recordNotFound
 *
 * Always send a HTTP 404 response if something can't be found
 *
 * @param CakeEvent $event
 * @return void
 * @throws NotFoundException If record not found
 */
	public function recordNotFound(CakeEvent $event) {
		if (!$this->_request->is('api')) {
			return;
		}

		throw new NotFoundException();
	}

/**
 * invalidId
 *
 * If the id is invalid, simply send a HTTP 400 response
 *
 * @param CakeEvent $event
 * @return void
 * @throws BadRequestException If invalid id provided
 */
	public function invalidId(CakeEvent $event) {
		if (!$this->_request->is('api')) {
			return;
		}

		throw new BadRequestException('Invalid id');
	}

/**
 * Selects an specific Crud view class to render the output
 *
 * @param CakeEvent $event
 * @return void
 */
	public function beforeRender(CakeEvent $event) {
		if (!$this->_request->is('api')) {
			return;
		}

		// Copy the _serialize configuration from the CrudAction config
		$action = $event->subject->crud->action();
		$serialize = $action->config('serialize');

		$serialize[] = 'success';
		if (method_exists($action, 'viewVar')) {
			$serialize[$action->viewVar()] = 'data';
		} else {
			$serialize[] = 'data';
		}

		krsort($serialize);

		$this->_controller->set('_serialize', $serialize);

		// Make sure to use Cruds own View renderer for json and xml
		// @TODO: make the viewClassMap configurable
		$this->_controller->RequestHandler->viewClassMap('json', 'Crud.CrudJson');
		$this->_controller->RequestHandler->viewClassMap('xml', 'Crud.CrudXml');
		$this->_controller->RequestHandler->renderAs($this->_controller, $this->_controller->RequestHandler->ext);
	}

/**
 * Setup detectors for JSON and XML
 *
 * Both detects on two signals:
 *  1) The extension in the request (e.g. /users/index.json)
 *  2) The accepts header from the client
 *
 * There is a combined request detector for both 'json' and 'xml' called
 * 'api'
 *
 * @return void
 */
	protected function _setupDetectors() {
{'fraction_non_alphanumeric': 0.15128566396618529, 'fraction_numerical': 0.007573089115885875, 'mean_word_length': 4.003083700440529, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 207, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 6}, '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': '398329', 'n_tokens_mistral': 3717, 'n_tokens_neox': 3363, 'n_words': 1051}