UserCollection.php 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. <?php
  2. /**
  3. * @package Grav\Common\User
  4. *
  5. * @copyright Copyright (C) 2015 - 2019 Trilby Media, LLC. All rights reserved.
  6. * @license MIT License; see LICENSE file for details.
  7. */
  8. namespace Grav\Common\User\DataUser;
  9. use Grav\Common\Data\Blueprints;
  10. use Grav\Common\File\CompiledYamlFile;
  11. use Grav\Common\Grav;
  12. use Grav\Common\User\Interfaces\UserCollectionInterface;
  13. use Grav\Common\User\Interfaces\UserInterface;
  14. use Grav\Common\Utils;
  15. use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator;
  16. class UserCollection implements UserCollectionInterface
  17. {
  18. /** @var string */
  19. private $className;
  20. /**
  21. * UserCollection constructor.
  22. * @param string $className
  23. */
  24. public function __construct(string $className)
  25. {
  26. $this->className = $className;
  27. }
  28. /**
  29. * Load user account.
  30. *
  31. * Always creates user object. To check if user exists, use $this->exists().
  32. *
  33. * @param string $username
  34. * @return UserInterface
  35. */
  36. public function load($username): UserInterface
  37. {
  38. $grav = Grav::instance();
  39. /** @var UniformResourceLocator $locator */
  40. $locator = $grav['locator'];
  41. // force lowercase of username
  42. $username = mb_strtolower($username);
  43. $filename = 'account://' . $username . YAML_EXT;
  44. $path = $locator->findResource($filename) ?: $locator->findResource($filename, true, true);
  45. $file = CompiledYamlFile::instance($path);
  46. $content = (array)$file->content() + ['username' => $username, 'state' => 'enabled'];
  47. $userClass = $this->className;
  48. $callable = function() {
  49. $blueprints = new Blueprints;
  50. return $blueprints->get('user/account');
  51. };
  52. /** @var UserInterface $user */
  53. $user = new $userClass($content, $callable);
  54. $user->file($file);
  55. return $user;
  56. }
  57. /**
  58. * Find a user by username, email, etc
  59. *
  60. * @param string $query the query to search for
  61. * @param array $fields the fields to search
  62. * @return UserInterface
  63. */
  64. public function find($query, $fields = ['username', 'email']): UserInterface
  65. {
  66. $fields = (array)$fields;
  67. $account_dir = Grav::instance()['locator']->findResource('account://');
  68. $files = $account_dir ? array_diff(scandir($account_dir), ['.', '..']) : [];
  69. // Try with username first, you never know!
  70. if (in_array('username', $fields, true)) {
  71. $user = $this->load($query);
  72. unset($fields[array_search('username', $fields, true)]);
  73. } else {
  74. $user = $this->load('');
  75. }
  76. // If not found, try the fields
  77. if (!$user->exists()) {
  78. foreach ($files as $file) {
  79. if (Utils::endsWith($file, YAML_EXT)) {
  80. $find_user = $this->load(trim(pathinfo($file, PATHINFO_FILENAME)));
  81. foreach ($fields as $field) {
  82. if ($find_user[$field] === $query) {
  83. return $find_user;
  84. }
  85. }
  86. }
  87. }
  88. }
  89. return $user;
  90. }
  91. /**
  92. * Remove user account.
  93. *
  94. * @param string $username
  95. *
  96. * @return bool True if the action was performed
  97. */
  98. public function delete($username): bool
  99. {
  100. $file_path = Grav::instance()['locator']->findResource('account://' . $username . YAML_EXT);
  101. return $file_path && unlink($file_path);
  102. }
  103. public function count(): int
  104. {
  105. // check for existence of a user account
  106. $account_dir = $file_path = Grav::instance()['locator']->findResource('account://');
  107. $accounts = glob($account_dir . '/*.yaml') ?: [];
  108. return count($accounts);
  109. }
  110. }