controller.php 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. <?php
  2. namespace Grav\Plugin;
  3. use Grav\Common\File\CompiledYamlFile;
  4. use Grav\Common\Grav;
  5. use Grav\Common\User\User;
  6. use RocketTheme\Toolbox\Session\Message;
  7. class LoginController
  8. {
  9. /**
  10. * @var Grav
  11. */
  12. public $grav;
  13. /**
  14. * @var string
  15. */
  16. public $view;
  17. /**
  18. * @var string
  19. */
  20. public $task;
  21. /**
  22. * @var array
  23. */
  24. public $post;
  25. /**
  26. * @var string
  27. */
  28. protected $redirect;
  29. /**
  30. * @var int
  31. */
  32. protected $redirectCode;
  33. /**
  34. * @param Grav $grav
  35. * @param string $task
  36. * @param array $post
  37. */
  38. public function __construct(Grav $grav, $task, $post)
  39. {
  40. $this->grav = $grav;
  41. $this->task = $task ?: 'display';
  42. $this->post = $this->getPost($post);
  43. }
  44. /**
  45. * Performs a task.
  46. */
  47. public function execute()
  48. {
  49. // Set redirect if available.
  50. if (isset($this->post['_redirect'])) {
  51. $redirect = $this->post['_redirect'];
  52. unset($this->post['_redirect']);
  53. }
  54. $success = false;
  55. $method = 'task' . ucfirst($this->task);
  56. if (!method_exists($this, $method)) {
  57. throw new \RuntimeException('Page Not Found', 404);
  58. }
  59. try {
  60. $success = call_user_func(array($this, $method));
  61. } catch (\RuntimeException $e) {
  62. $this->setMessage($e->getMessage());
  63. }
  64. if (!$this->redirect && isset($redirect)) {
  65. $this->setRedirect($redirect);
  66. }
  67. return $success;
  68. }
  69. public function redirect()
  70. {
  71. if ($this->redirect) {
  72. $this->grav->redirect($this->redirect, $this->redirectCode);
  73. }
  74. }
  75. /**
  76. * Handle login.
  77. *
  78. * @return bool True if the action was performed.
  79. */
  80. public function taskLogin()
  81. {
  82. $t = $this->grav['language'];
  83. $user = $this->grav['user'];
  84. if ($this->authenticate($this->post)) {
  85. $this->setMessage($t->translate('LOGIN_PLUGIN.LOGIN_SUCCESSFUL'));
  86. $referrer = $this->grav['uri']->referrer('/');
  87. $this->setRedirect($referrer);
  88. } else {
  89. if ($user->username) {
  90. $this->setMessage($t->translate('LOGIN_PLUGIN.ACCESS_DENIED'));
  91. } else {
  92. $this->setMessage($t->translate('LOGIN_PLUGIN.LOGIN_FAILED'));
  93. }
  94. }
  95. return true;
  96. }
  97. /**
  98. * Handle logout.
  99. *
  100. * @return bool True if the action was performed.
  101. */
  102. public function taskLogout()
  103. {
  104. $this->grav['session']->invalidate()->start();
  105. $this->setRedirect('/');
  106. return true;
  107. }
  108. /**
  109. * Authenticate user.
  110. *
  111. * @param array $form Form fields.
  112. * @return bool
  113. */
  114. protected function authenticate($form)
  115. {
  116. /** @var User $user */
  117. $user = $this->grav['user'];
  118. if (!$user->authenticated && isset($form['username']) && isset($form['password'])) {
  119. $user = User::load($form['username']);
  120. if ($user->exists()) {
  121. // Authenticate user.
  122. $result = $user->authenticate($form['password']);
  123. if ($result) {
  124. $this->grav['session']->user = $user;
  125. }
  126. }
  127. }
  128. $user->authenticated = $user->authorize('site.login');
  129. return $user->authenticated;
  130. }
  131. /**
  132. * Set redirect.
  133. *
  134. * @param $path
  135. * @param int $code
  136. */
  137. public function setRedirect($path, $code = 303)
  138. {
  139. $this->redirect = '/' . preg_replace('|/+|', '/', trim($path, '/'));
  140. $this->code = $code;
  141. }
  142. /**
  143. * Add message into the session queue.
  144. *
  145. * @param string $msg
  146. * @param string $type
  147. */
  148. public function setMessage($msg, $type = 'info')
  149. {
  150. /** @var Message $messages */
  151. $messages = $this->grav['messages'];
  152. $messages->add($msg, $type);
  153. }
  154. /**
  155. * Prepare and return POST data.
  156. *
  157. * @param array $post
  158. * @return array
  159. */
  160. protected function &getPost($post)
  161. {
  162. unset($post['task']);
  163. // Decode JSON encoded fields and merge them to data.
  164. if (isset($post['_json'])) {
  165. $post = array_merge_recursive($post, $this->jsonDecode($post['_json']));
  166. unset($post['_json']);
  167. }
  168. return $post;
  169. }
  170. /**
  171. * Recursively JSON decode data.
  172. *
  173. * @param array $data
  174. * @return array
  175. */
  176. protected function jsonDecode(array $data)
  177. {
  178. foreach ($data as &$value) {
  179. if (is_array($value)) {
  180. $value = $this->jsonDecode($value);
  181. } else {
  182. $value = json_decode($value, true);
  183. }
  184. }
  185. return $data;
  186. }
  187. }