<?php
class User_PutController extends Library_Controller {
	public function __call($methodName, $arguments) {
		//naparsovani objektu
		$objectInfo = $this->_parseActionName($methodName);

		//kontorla formatu
		if ($objectInfo["format"] != "html") {
			//pozadovany format neni html, vypne se layout
			$this->_helper->layout()->disableLayout();
		}
		
		//vyhodnoceni id objektu
		if (strtolower($objectInfo["id"]) == "list") {
			$this->_list($objectInfo["format"]);
			return;
		}
		
		//vytvoreni odpovedi
		$response = new Library_Response();
		
		//nacteni informaci o uzivateli
		/* @var $user Application_Model_Row_User */
		$user = $this->_tableUsers->fetchRow($this->_tableUsers->select(false)
			->where("username like ?", $objectInfo["id"])->orWhere("id = ?", $objectInfo["id"]));
		
		$response["user"] = $user;
		
		//kontorla, jestli je uzivatel nacten
		if (!$user) {
			//uzivatel nebyl nalezen
			$response->setStatus("USER_NOT_FOUND", 404);
			$this->_sendToRender($response, $objectInfo["format"]);
			return;
		}
		
		//nacteni roli
		$roleList = $this->_user->findManyToManyRowset("Application_Model_UsersRoles", "Application_Model_UsersHasManyUsersRoles", "user", "role");
		$roles = array();
		
		foreach ($roleList as $role) {
			$roles[$role->id] = $role->role_name;
		}
		
		//kontrola pozadavku na nastaveni skupin
		if (isset($_REQUEST["user"]["group"])) {
			//pozadavek na zmenu skupin existuje
			
			//kontorla jestli je uzivatel opravnen menit skupiny
			if ($this->_user->id == 1 || in_array("GROUP_MANAGER", $roles)) {
				//uzivatel je opravnen menit data skupin
				$groups = $_REQUEST["user"]["group"];
				
				if (!is_array($groups)) {
					//seznam skupin neni pole, preede se na pole
					$groups = (array) $groups;
				}
				
				//vymazani aktualnich skupin uzivatele
				$tableUsersGroups = new Application_Model_UsersHasManyUsersGroups();
				$tableUsersGroups->delete(array("user_id" => $user->id));
				
				//zapsani novych dat
				$data = array(
					"user_id" => $user->id,
					"user_group_id" => 0
				);
				
				foreach ($groups as $groupId => $toWrite) {
					//kontorla jestli ej skupina oznacena k zapsani
					if ($toWrite) {
						//skupina je oznacena ke smazani, zapise se tedy
						$data["user_group_id"] = $groupId;
						
						$tableUsersGroups->insert($data);
					}
				}
			} else {
				//uzivatel neni opravnen, zapise se chybove hlaseni
				$response->setStatus("NOT_PERMISION_TO_CHANGE_GROUPS", 403);
				$this->_sendToRender($response, $objectInfo["format"]);
				return;
			}
		}
		
		//konotrla pozadavku na zmenu roli
		if (isset($_REQUEST["user"]["role"])) {
			//pozadavek na zmenu roli existuje, zkotroluje se opravneni
			$newRoles = $_REQUEST["user"]["role"];
			
			if (!is_array($roles)) {
				//seznam roli neni pole, prevede se na pole
				$roles = (array) $roles;
			}
			
			if (in_array("USER_MANAGER", $roles) || $this->_user->id == 1) {
				//uzivatel je opravnen provadet zmeny roli
				
				//vymazani starych roli
				$tableUsersRoles = new Application_Model_UsersHasManyUsersRoles();
				$tableUsersRoles->delete(array("user_id" => $user->id));
				
				//zapsani novych roli
				$data = array(
					"user_id" => $user->id,
					"user_role_id" => 0
				);
				
				foreach ($newRoles as $roleId => $toWrite) {
					//kontrola jestli ma byt role zapsana
					if ($toWrite) {
						//role ma byt zapsana
						$data["user_role_id"] = $roleId;
						$tableUsersRoles->insert($data);
					}
				}
			} else {
				//uzivatel neni opravnen, zapise se chybove hlaseni
				$response->setStatus("NOT_PERMISION_TO_CHANGE_ROLES", 403);
				$this->_sendToRender($response, $objectInfo["format"]);
				return;
			}
		}
		
		//vyhodnoceni jestli je uzivatel opravnen menit obecna data
		$permited = ($user->id == $this->_user->id) || ($this->_user->id == 1) || in_array("USER_MANAGER", $roles);
		
		//kontrola pozadavku na zmenu emailove adresy
		if (isset($_REQUEST["user"]["email"])) {
			//pozadavek na zmenu existuje, zkotroluje se opravneni
			if ($permited) {
				//uzivatel je opravnen delat zmeny
				$user->email = $_REQUEST["user"]["email"];
			} else {
				//uzivatel neni opravnen
				$response->setStatus("NOT_PERMISION_TO_CHANGE_EMAIL", 403);
				$this->_sendToRender($response, $objectInfo["format"]);
				return;
			}
		}
		
		//kontorla jestli existuje pozadavek zmenit heslo
		if (isset($_REQUEST["user"]["password_old"], $_REQUEST["user"]["password"], $_REQUEST["user"]["password_check"])) {
			//data jsou odelana, kontrola jestli nejsou prazdna
			if (!empty($_REQUEST["user"]["password"])) {
				//nove heslo neni pradne, zkonstroluje se opravneni
				if ($permited) {
					//uzivatel je opravnen delat zmeny
					
					//pokud je upravovany uzivatel stejny jako upravujici uzivatel, zkontroluje se stare heslo
					if ($user->id == $this->_user->id) {
						//uzivatel je stejny, ztkontroluje se stare heslo
						$oldHash = $user->hashPassword($_REQUEST["user"]["password_old"]);
						
						if ($oldHash != $user->password) {
							//stare heslo nesouhlasi
							$response->setStatus("OLD_PASSWORD_INVALID", 400);
							$this->_sendToRender($response, $objectInfo["format"]);
							return;
						}
						
						//hash noveho hesla a kontroly
						$newHash = $user->hashPassword($_REQUEST["user"]["password"]);
						$checkHash = $user->hashPassword($_REQUEST["user"]["password_check"]);
						
						if ($newHash != $checkHash) {
							//heslo nesouhlasi s kontrolou
							$response->setStatus("NEW_PASSWORD_NOT_EQUAL_WITH_CHECK", 400);
							$this->_sendToRender($response, $objectInfo["format"]);
							return;
						}
						
						//zapsani noveho hesla
						$user->password = $newHash;
					}
				} else {
					//uzivatel neni opravnen delat zmeny
					$response->setStatus("NOT_PERMISION_TO_CHANGE_PASSWORD", 403);
					$this->_sendToRender($response, $objectInfo["format"]);
					return;
				}
			}
		}
		
		//ulozeni zmen
		$user->save();
		
		$response->setOk();
		
		$this->_sendToRender($response, $objectInfo["format"]);
	}
	
	protected function _sendToRender(Library_Response $response, $format) {
		//zapsani do view
		$this->view->response = $response;
		$response->sendHeader();
		
		if ($format != "html") {
			$this->_helper->layout()->disableLayout();
		}
		
		//vyhodnoceni formatu
		switch ($format) {
			case "html":
				$this->_helper->viewRenderer("put-html");
				break;
			
			case "json":
			
			default:
				$this->_helper->viewRenderer("put-json");
		}
	}
}
