You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							249 lines
						
					
					
						
							5.9 KiB
						
					
					
				
			
		
		
	
	
							249 lines
						
					
					
						
							5.9 KiB
						
					
					
				<?php | 
						|
 | 
						|
namespace App\Controllers; | 
						|
 | 
						|
use App\Classes\Session; | 
						|
 | 
						|
class CrudController extends PageController { | 
						|
 | 
						|
	public static $pagination = 10; | 
						|
 | 
						|
	//-------------------------------------// | 
						|
 | 
						|
	/** | 
						|
	 * Display a listing of the resource. | 
						|
	 * | 
						|
	 * @return void | 
						|
	 */ | 
						|
	public function indexAction(): void | 
						|
	{ | 
						|
		$modelName = $this->getModelName(); | 
						|
		$model = "\App\Model\\{$modelName}Model"; | 
						|
		$model = new $model; | 
						|
 | 
						|
		// ?page=x | 
						|
		$page = 1; | 
						|
		if (_exists($_GET, 'page') && is_numeric($_GET['page'])) { | 
						|
			$page = $_GET['page']; | 
						|
		} | 
						|
 | 
						|
		$rows = $model->all($page, self::$pagination); | 
						|
 | 
						|
		// Set empty value | 
						|
		if (!_exists($rows)) { | 
						|
			$rows = []; | 
						|
		} | 
						|
 | 
						|
		$this->router->service()->attributes = $model->getAttributesRules(); | 
						|
		$this->router->service()->csrfToken = Session::token(); | 
						|
		$this->router->service()->rows = $rows; | 
						|
		$this->router->service()->title = $modelName; | 
						|
 | 
						|
		// Set page variables | 
						|
		$this->router->service()->page = $page; | 
						|
		$pages = ceil($model->count() / self::$pagination); | 
						|
		$pages > 1 | 
						|
			? $this->router->service()->pages = $pages | 
						|
			: $this->router->service()->pages = 1; | 
						|
 | 
						|
		parent::view("{$this->section}/crud/index"); | 
						|
	} | 
						|
 | 
						|
	/** | 
						|
	 * Show the form for creating a new resource. | 
						|
	 * | 
						|
	 * @return void | 
						|
	 */ | 
						|
	public function createAction(): void | 
						|
	{ | 
						|
		$model = "\App\Model\\{$this->getModelName()}Model"; | 
						|
		$model = new $model; | 
						|
 | 
						|
		$attributes = $model->getAttributesRules(); | 
						|
 | 
						|
		// Get dropdown data | 
						|
		$dropdownData = []; | 
						|
		foreach ($attributes as $key => $attribute) { | 
						|
			if ($attribute[1] == 'dropdown') { | 
						|
				$dropdownData[$key] = $model->getDropdownData($attribute[0]); | 
						|
			} | 
						|
		} | 
						|
 | 
						|
		$this->router->service()->attributes = $attributes; | 
						|
		$this->router->service()->csrfToken = Session::token(); | 
						|
		$this->router->service()->dropdownData = $dropdownData; | 
						|
		parent::view("{$this->section}/crud/create"); | 
						|
	} | 
						|
 | 
						|
	/** | 
						|
	 * Store a newly created resource in storage. | 
						|
	 * | 
						|
	 * @return void | 
						|
	 */ | 
						|
	public function storeAction(): void | 
						|
	{ | 
						|
		$modelName = $this->getModelName(); | 
						|
		$model = "\App\Model\\{$modelName}Model"; | 
						|
		$model = new $model; | 
						|
 | 
						|
		$token = Session::validateToken($_POST); | 
						|
 | 
						|
		$token && $model->fill($_POST) && $model->validate() && $model->save() | 
						|
			? $this->setAlertNext('success', "$modelName successfully created.") | 
						|
			: $this->setAlertNext('danger', "$modelName could not be created!"); | 
						|
 | 
						|
		$this->router->response()->redirect($this->url); | 
						|
	} | 
						|
 | 
						|
	/** | 
						|
	 * Display the specified resource. | 
						|
	 * | 
						|
	 * @param int $id | 
						|
	 * | 
						|
	 * @return void | 
						|
	 */ | 
						|
	public function showAction(int $id): void | 
						|
	{ | 
						|
		$model = "\App\Model\\{$this->getModelName()}Model"; | 
						|
		$model = $model::find($id); | 
						|
 | 
						|
		if (!$model->exists()) { | 
						|
			parent::throw404(); | 
						|
		} | 
						|
 | 
						|
		$this->router->service()->model = $model; | 
						|
		$this->router->service()->attributes = $model->getAttributesRules(); | 
						|
		parent::view("{$this->section}/crud/show"); | 
						|
	} | 
						|
 | 
						|
	/** | 
						|
	 * Show the form for editing the specified resource. | 
						|
	 * | 
						|
	 * @param int $id | 
						|
	 * | 
						|
	 * @return void | 
						|
	 */ | 
						|
	public function editAction(int $id): void | 
						|
	{ | 
						|
		$model = "\App\Model\\{$this->getModelName()}Model"; | 
						|
		$model = $model::find($id); | 
						|
 | 
						|
		if (!$model->exists()) { | 
						|
			parent::throw404(); | 
						|
		} | 
						|
 | 
						|
		$attributes = $model->getAttributesRules(); | 
						|
 | 
						|
		// Get dropdown data | 
						|
		$dropdownData = []; | 
						|
		foreach ($attributes as $key => $attribute) { | 
						|
			if ($attribute[1] == 'dropdown') { | 
						|
				$dropdownData[$key] = $model->getDropdownData($attribute[0]); | 
						|
			} | 
						|
		} | 
						|
 | 
						|
		$this->router->service()->attributes = $attributes; | 
						|
		$this->router->service()->csrfToken = Session::token(); | 
						|
		$this->router->service()->dropdownData = $dropdownData; | 
						|
		$this->router->service()->model = $model; | 
						|
		parent::view("{$this->section}/crud/edit"); | 
						|
	} | 
						|
 | 
						|
	/** | 
						|
	 * Update the specified resource in storage. | 
						|
	 * | 
						|
	 * @param int $id | 
						|
	 * | 
						|
	 * @return void | 
						|
	 */ | 
						|
	public function updateAction(int $id): void | 
						|
	{ | 
						|
		$modelName = $this->getModelName(); | 
						|
		$model = "\App\Model\\{$modelName}Model"; | 
						|
		$model = $model::find($id); | 
						|
 | 
						|
		if (!$model->exists()) { | 
						|
			$this->setAlertNext('danger', "$modelName does not exist!"); | 
						|
		} | 
						|
		else { | 
						|
			// Read PUT request | 
						|
			$this->parsePhpInput($_PUT); | 
						|
 | 
						|
			$token = Session::validateToken($_PUT); | 
						|
 | 
						|
			$token && $model->fill($_PUT) && $model->validate() && $model->save() | 
						|
				? $this->setAlertNext('success', "$modelName successfully updated.") | 
						|
				: $this->setAlertNext('danger', "$modelName could not be updated!"); | 
						|
		} | 
						|
 | 
						|
		echo $this->url; | 
						|
	} | 
						|
 | 
						|
	/** | 
						|
	 * Remove the specified resource from storage. | 
						|
	 * | 
						|
	 * @param int $id | 
						|
	 * | 
						|
	 * @return void | 
						|
	 */ | 
						|
	public function destroyAction(int $id): void | 
						|
	{ | 
						|
		// Read DELETE request | 
						|
		$this->parsePhpInput($_DELETE); | 
						|
 | 
						|
		$token = Session::validateToken($_DELETE); | 
						|
 | 
						|
		$modelName = $this->getModelName(); | 
						|
		$model = "\App\Model\\{$modelName}Model"; | 
						|
 | 
						|
		$token && $model::destroy($id) | 
						|
			? $this->setAlertNext('success', "$modelName successfully deleted.") | 
						|
			: $this->setAlertNext('danger', "$modelName could not be deleted!"); | 
						|
	} | 
						|
 | 
						|
	//-------------------------------------// | 
						|
 | 
						|
	/** | 
						|
	 * Generate the model name from the /section/page url | 
						|
	 * | 
						|
	 * @return string The model name | 
						|
	 */ | 
						|
	private function getModelName(): string | 
						|
	{ | 
						|
		$model = $this->page; | 
						|
		$model = str_replace('-', ' ', $model); | 
						|
		$model = str_replace('_', ' ', $model); | 
						|
		$model = ucwords($model); | 
						|
		$model = str_replace(' ', '', $model); | 
						|
 | 
						|
		return $model; | 
						|
	} | 
						|
 | 
						|
	/** | 
						|
	 * PUT/DELETE requests aren't handled by PHP automatically yet. | 
						|
	 * Parse them from php://input instead. | 
						|
	 * | 
						|
	 * @param ?array &$result Array filled with input data | 
						|
	 * | 
						|
	 * @return void | 
						|
	 */ | 
						|
	private function parsePhpInput(?array &$result): void | 
						|
	{ | 
						|
		// Parse json or form-encoded formatted data | 
						|
		if (strpos($_SERVER['CONTENT_TYPE'], "application/json") !== false) { | 
						|
			$result = json_decode(file_get_contents("php://input"), true); | 
						|
		} | 
						|
		else if (strpos($_SERVER['CONTENT_TYPE'], "application/x-www-form-urlencoded") !== false) { | 
						|
			parse_str(file_get_contents("php://input"), $result); | 
						|
 | 
						|
			// Cleanup & HTML entities | 
						|
			foreach ($result as $key => $value) { | 
						|
				unset($result[$key]); | 
						|
				$result[str_replace('amp;', '', $key)] = $value; | 
						|
			} | 
						|
		} | 
						|
 | 
						|
		$_REQUEST = array_merge($_REQUEST, $result); | 
						|
	} | 
						|
 | 
						|
}
 | 
						|
 |