Initial commit
This commit is contained in:
450
references/ddev.md
Normal file
450
references/ddev.md
Normal file
@@ -0,0 +1,450 @@
|
||||
# DDEV Commands Reference
|
||||
|
||||
Comprehensive DDEV command reference for Drupal development. DDEV is a Docker-based local development environment.
|
||||
|
||||
## Project Initialization
|
||||
|
||||
```bash
|
||||
# Initialize DDEV in current directory
|
||||
ddev config
|
||||
|
||||
# Initialize with Drupal specific settings
|
||||
ddev config --project-type=drupal10 --docroot=web --create-docroot
|
||||
|
||||
# Initialize Drupal 9
|
||||
ddev config --project-type=drupal9 --docroot=web
|
||||
|
||||
# Initialize Drupal 11
|
||||
ddev config --project-type=drupal --docroot=web
|
||||
|
||||
# Configure project name and PHP version
|
||||
ddev config --project-name=myproject --php-version=8.2
|
||||
```
|
||||
|
||||
## Project Management
|
||||
|
||||
```bash
|
||||
# Start project
|
||||
ddev start
|
||||
|
||||
# Stop project
|
||||
ddev stop
|
||||
|
||||
# Restart project
|
||||
ddev restart
|
||||
|
||||
# Delete project (keeps files, removes containers)
|
||||
ddev delete
|
||||
|
||||
# Delete project and remove images
|
||||
ddev delete --omit-snapshot
|
||||
|
||||
# Power off all DDEV projects
|
||||
ddev poweroff
|
||||
|
||||
# Show project description
|
||||
ddev describe
|
||||
|
||||
# List all DDEV projects
|
||||
ddev list
|
||||
```
|
||||
|
||||
## Accessing Services
|
||||
|
||||
```bash
|
||||
# SSH into web container
|
||||
ddev ssh
|
||||
|
||||
# SSH into database container
|
||||
ddev ssh -s db
|
||||
|
||||
# Open project in browser
|
||||
ddev launch
|
||||
|
||||
# Open specific path
|
||||
ddev launch /admin
|
||||
|
||||
# Open phpMyAdmin
|
||||
ddev launch -p
|
||||
|
||||
# Open MailHog (email catcher)
|
||||
ddev launch -m
|
||||
```
|
||||
|
||||
## Database Operations
|
||||
|
||||
```bash
|
||||
# Import database from file
|
||||
ddev import-db --src=dump.sql
|
||||
ddev import-db --src=dump.sql.gz
|
||||
ddev import-db --file=dump.sql
|
||||
|
||||
# Export database to file
|
||||
ddev export-db --file=backup.sql
|
||||
ddev export-db --file=backup.sql.gz --gzip
|
||||
|
||||
# Execute MySQL query
|
||||
ddev mysql -e "SELECT * FROM users WHERE uid=1;"
|
||||
|
||||
# Connect to MySQL CLI
|
||||
ddev mysql
|
||||
|
||||
# Import database and files from @drush-alias
|
||||
ddev pull @production
|
||||
|
||||
# Snapshot database (backup)
|
||||
ddev snapshot
|
||||
|
||||
# Restore from snapshot
|
||||
ddev snapshot restore
|
||||
|
||||
# List snapshots
|
||||
ddev snapshot list
|
||||
|
||||
# Delete snapshot
|
||||
ddev snapshot delete --name=backup-name
|
||||
```
|
||||
|
||||
## File Management
|
||||
|
||||
```bash
|
||||
# Import files directory
|
||||
ddev import-files --src=/path/to/files
|
||||
|
||||
# Pull files from remote using Drush alias
|
||||
ddev pull @production --skip-db
|
||||
|
||||
# SCP files into container
|
||||
ddev scp local-file.txt :/var/www/html/web/
|
||||
|
||||
# SCP files from container
|
||||
ddev scp :/var/www/html/web/file.txt ./local-file.txt
|
||||
```
|
||||
|
||||
## Composer
|
||||
|
||||
```bash
|
||||
# Run composer install
|
||||
ddev composer install
|
||||
|
||||
# Require package
|
||||
ddev composer require drupal/webform
|
||||
|
||||
# Require dev package
|
||||
ddev composer require --dev drupal/devel
|
||||
|
||||
# Update packages
|
||||
ddev composer update
|
||||
|
||||
# Remove package
|
||||
ddev composer remove drupal/old_module
|
||||
|
||||
# Show installed packages
|
||||
ddev composer show
|
||||
```
|
||||
|
||||
## Drush Integration
|
||||
|
||||
```bash
|
||||
# Run Drush commands
|
||||
ddev drush status
|
||||
ddev drush cr
|
||||
ddev drush uli
|
||||
|
||||
# Config import
|
||||
ddev drush cim -y
|
||||
|
||||
# Config export
|
||||
ddev drush cex -y
|
||||
|
||||
# Update database
|
||||
ddev drush updb -y
|
||||
|
||||
# Enable module
|
||||
ddev drush en mymodule -y
|
||||
|
||||
# Install Drupal
|
||||
ddev drush site:install standard --account-name=admin --account-pass=admin
|
||||
```
|
||||
|
||||
## Logs & Debugging
|
||||
|
||||
```bash
|
||||
# View container logs
|
||||
ddev logs
|
||||
|
||||
# Follow logs in real-time
|
||||
ddev logs -f
|
||||
|
||||
# View web server logs
|
||||
ddev logs -s web
|
||||
|
||||
# View database logs
|
||||
ddev logs -s db
|
||||
|
||||
# Enable Xdebug
|
||||
ddev xdebug on
|
||||
|
||||
# Disable Xdebug
|
||||
ddev xdebug off
|
||||
|
||||
# Toggle Xdebug
|
||||
ddev xdebug toggle
|
||||
|
||||
# Check Xdebug status
|
||||
ddev xdebug status
|
||||
```
|
||||
|
||||
## Mailhog (Email Testing)
|
||||
|
||||
```bash
|
||||
# Launch MailHog UI
|
||||
ddev launch -m
|
||||
|
||||
# All emails sent by Drupal are caught in MailHog
|
||||
# Access at: http://<project>.ddev.site:8025
|
||||
```
|
||||
|
||||
## Custom Commands
|
||||
|
||||
```bash
|
||||
# Execute arbitrary command in web container
|
||||
ddev exec ls -la
|
||||
|
||||
# Run PHP command
|
||||
ddev exec php -v
|
||||
|
||||
# Run npm
|
||||
ddev exec npm install
|
||||
ddev exec npm run build
|
||||
|
||||
# Execute command in specific service
|
||||
ddev exec -s db mysql --version
|
||||
```
|
||||
|
||||
## Add-ons & Services
|
||||
|
||||
```bash
|
||||
# Get additional services (Redis, Elasticsearch, etc.)
|
||||
ddev get ddev/ddev-redis
|
||||
ddev get ddev/ddev-elasticsearch
|
||||
ddev get ddev/ddev-solr
|
||||
|
||||
# List available add-ons
|
||||
ddev get --list
|
||||
|
||||
# Remove add-on
|
||||
ddev get --remove ddev/ddev-redis
|
||||
```
|
||||
|
||||
## Environment & Configuration
|
||||
|
||||
```bash
|
||||
# Show DDEV version
|
||||
ddev version
|
||||
|
||||
# Show project info
|
||||
ddev describe
|
||||
|
||||
# Edit project configuration
|
||||
# Edit .ddev/config.yaml manually
|
||||
|
||||
# Common config.yaml settings:
|
||||
# - php_version: "8.2"
|
||||
# - nodejs_version: "18"
|
||||
# - webserver_type: nginx-fpm
|
||||
# - database: mariadb:10.11
|
||||
# - router_http_port: "80"
|
||||
# - router_https_port: "443"
|
||||
```
|
||||
|
||||
## Multiple PHP Versions
|
||||
|
||||
```bash
|
||||
# Set PHP version
|
||||
ddev config --php-version=8.1
|
||||
ddev config --php-version=8.2
|
||||
ddev config --php-version=8.3
|
||||
|
||||
# Apply changes
|
||||
ddev restart
|
||||
```
|
||||
|
||||
## Database Types & Versions
|
||||
|
||||
```bash
|
||||
# Use MySQL
|
||||
ddev config --database=mysql:8.0
|
||||
|
||||
# Use MariaDB (default)
|
||||
ddev config --database=mariadb:10.11
|
||||
|
||||
# Use PostgreSQL
|
||||
ddev config --database=postgres:14
|
||||
```
|
||||
|
||||
## Performance Optimization
|
||||
|
||||
```bash
|
||||
# Use Mutagen for better file sync performance (Mac)
|
||||
ddev config --mutagen-enabled
|
||||
|
||||
# Use NFS for better performance (Mac/Linux)
|
||||
ddev config --nfs-mount-enabled
|
||||
|
||||
# Disable NFS
|
||||
ddev config --nfs-mount-enabled=false
|
||||
```
|
||||
|
||||
## Sharing Your Project
|
||||
|
||||
```bash
|
||||
# Share project via ngrok (requires ngrok account)
|
||||
ddev share
|
||||
|
||||
# This creates a public URL for your local site
|
||||
```
|
||||
|
||||
## Drupal-Specific Workflows
|
||||
|
||||
### Fresh Drupal Installation
|
||||
```bash
|
||||
# Initialize DDEV
|
||||
ddev config --project-type=drupal10 --docroot=web
|
||||
|
||||
# Start DDEV
|
||||
ddev start
|
||||
|
||||
# Install Drupal via Composer
|
||||
ddev composer create drupal/recommended-project
|
||||
|
||||
# Install Drupal
|
||||
ddev drush site:install standard --account-name=admin --account-pass=admin
|
||||
|
||||
# Launch site
|
||||
ddev launch
|
||||
```
|
||||
|
||||
### Clone Existing Project
|
||||
```bash
|
||||
# Clone repository
|
||||
git clone <repo-url> myproject
|
||||
cd myproject
|
||||
|
||||
# Start DDEV (uses existing .ddev/config.yaml)
|
||||
ddev start
|
||||
|
||||
# Install dependencies
|
||||
ddev composer install
|
||||
|
||||
# Import database
|
||||
ddev import-db --src=database.sql.gz
|
||||
|
||||
# Import files
|
||||
ddev import-files --src=files.tar.gz
|
||||
|
||||
# Clear cache
|
||||
ddev drush cr
|
||||
|
||||
# Launch site
|
||||
ddev launch
|
||||
```
|
||||
|
||||
### Development Workflow
|
||||
```bash
|
||||
# Start work
|
||||
ddev start
|
||||
|
||||
# Enable development modules
|
||||
ddev drush en devel devel_generate -y
|
||||
|
||||
# Watch theme files (if using compile tools)
|
||||
ddev exec npm run watch
|
||||
|
||||
# Clear cache frequently
|
||||
ddev drush cr
|
||||
|
||||
# Stop work
|
||||
ddev stop
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
```bash
|
||||
# Restart if containers are unresponsive
|
||||
ddev restart
|
||||
|
||||
# Clean restart (rebuild containers)
|
||||
ddev restart --clean
|
||||
|
||||
# Remove all Docker volumes and restart
|
||||
ddev stop --remove-data
|
||||
ddev start
|
||||
|
||||
# Check for port conflicts
|
||||
ddev describe
|
||||
|
||||
# View detailed debug info
|
||||
ddev debug test
|
||||
|
||||
# Check Docker is running
|
||||
docker ps
|
||||
|
||||
# Rebuild DDEV containers from scratch
|
||||
ddev delete --omit-snapshot
|
||||
ddev start
|
||||
```
|
||||
|
||||
## Common Issues
|
||||
|
||||
### Port Conflicts
|
||||
If ports 80/443 are in use:
|
||||
```bash
|
||||
# Change router ports in .ddev/config.yaml
|
||||
router_http_port: "8080"
|
||||
router_https_port: "8443"
|
||||
|
||||
# Then restart
|
||||
ddev restart
|
||||
```
|
||||
|
||||
### Permission Issues
|
||||
```bash
|
||||
# Fix file permissions
|
||||
ddev exec chmod -R 755 web/sites/default/files
|
||||
|
||||
# Fix ownership
|
||||
ddev exec chown -R www-data:www-data web/sites/default/files
|
||||
```
|
||||
|
||||
### Database Connection Issues
|
||||
Check database credentials in settings.php or settings.ddev.php:
|
||||
```php
|
||||
$databases['default']['default'] = [
|
||||
'database' => 'db',
|
||||
'username' => 'db',
|
||||
'password' => 'db',
|
||||
'host' => 'db',
|
||||
'port' => '3306',
|
||||
'driver' => 'mysql',
|
||||
];
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **Always use `ddev` prefix**: Run Composer, Drush, and other tools through DDEV (`ddev composer`, `ddev drush`)
|
||||
2. **Commit .ddev/config.yaml**: Share project configuration with team
|
||||
3. **Use .gitignore**: Exclude `.ddev/.importdb`, `.ddev/.ddev-docker-compose*`
|
||||
4. **Performance**: Enable Mutagen or NFS on Mac for better performance
|
||||
5. **Xdebug**: Only enable when needed (slows performance)
|
||||
6. **Regular updates**: Keep DDEV updated with `brew upgrade ddev` (Mac) or equivalent
|
||||
7. **Clean shutdown**: Use `ddev stop` before system shutdown
|
||||
8. **Database snapshots**: Create snapshots before major changes
|
||||
9. **Environment variables**: Use `.ddev/config.yaml` for environment-specific settings
|
||||
10. **Multiple projects**: Use unique project names to avoid conflicts
|
||||
|
||||
## Additional Resources
|
||||
|
||||
- Official docs: https://ddev.readthedocs.io/
|
||||
- DDEV Discord: https://discord.gg/hCZFfAMc5k
|
||||
- DDEV GitHub: https://github.com/ddev/ddev
|
||||
387
references/drush.md
Normal file
387
references/drush.md
Normal file
@@ -0,0 +1,387 @@
|
||||
# Drush Commands Reference
|
||||
|
||||
Comprehensive Drush command reference for Drupal 8-11+. These commands work with Drush 10, 11, and 12.
|
||||
|
||||
## Cache Management
|
||||
|
||||
```bash
|
||||
# Clear all caches
|
||||
drush cache:rebuild
|
||||
drush cr
|
||||
|
||||
# Clear specific cache bins
|
||||
drush cache:clear css-js
|
||||
drush cache:clear render
|
||||
|
||||
# List all cache bins
|
||||
drush cache:bins
|
||||
```
|
||||
|
||||
## Configuration Management
|
||||
|
||||
```bash
|
||||
# Export configuration
|
||||
drush config:export
|
||||
drush cex
|
||||
|
||||
# Import configuration
|
||||
drush config:import
|
||||
drush cim
|
||||
|
||||
# Get configuration value
|
||||
drush config:get system.site name
|
||||
drush cget system.site name
|
||||
|
||||
# Set configuration value
|
||||
drush config:set system.site name "My Site"
|
||||
drush cset system.site name "My Site"
|
||||
|
||||
# Edit configuration in editor
|
||||
drush config:edit system.site
|
||||
|
||||
# Delete configuration
|
||||
drush config:delete mymodule.settings
|
||||
|
||||
# List all configuration
|
||||
drush config:list
|
||||
```
|
||||
|
||||
## Module Management
|
||||
|
||||
```bash
|
||||
# Enable module
|
||||
drush pm:enable mymodule
|
||||
drush en mymodule
|
||||
|
||||
# Uninstall module
|
||||
drush pm:uninstall mymodule
|
||||
drush pmu mymodule
|
||||
|
||||
# List all modules
|
||||
drush pm:list
|
||||
drush pml
|
||||
|
||||
# List enabled modules only
|
||||
drush pm:list --status=enabled
|
||||
|
||||
# Download module from drupal.org
|
||||
drush pm:download webform
|
||||
drush dl webform
|
||||
```
|
||||
|
||||
## Database Operations
|
||||
|
||||
```bash
|
||||
# Update database (run update hooks)
|
||||
drush updatedb
|
||||
drush updb
|
||||
|
||||
# Execute SQL query
|
||||
drush sql:query "SELECT * FROM users WHERE uid=1"
|
||||
drush sqlq "SELECT * FROM users WHERE uid=1"
|
||||
|
||||
# Connect to database CLI
|
||||
drush sql:cli
|
||||
drush sqlc
|
||||
|
||||
# Dump database to file
|
||||
drush sql:dump > backup.sql
|
||||
drush sql:dump --gzip > backup.sql.gz
|
||||
|
||||
# Drop all tables
|
||||
drush sql:drop
|
||||
|
||||
# Sanitize database (for dev environments)
|
||||
drush sql:sanitize
|
||||
```
|
||||
|
||||
## User Management
|
||||
|
||||
```bash
|
||||
# Login as user 1
|
||||
drush user:login
|
||||
drush uli
|
||||
|
||||
# Login as specific user
|
||||
drush user:login admin
|
||||
drush uli admin
|
||||
|
||||
# Create user
|
||||
drush user:create newuser --mail="user@example.com" --password="password"
|
||||
|
||||
# Cancel/delete user
|
||||
drush user:cancel username
|
||||
|
||||
# Add role to user
|
||||
drush user:role:add "administrator" username
|
||||
|
||||
# Remove role from user
|
||||
drush user:role:remove "administrator" username
|
||||
|
||||
# Change user password
|
||||
drush user:password admin "newpassword"
|
||||
|
||||
# Block user
|
||||
drush user:block username
|
||||
|
||||
# Unblock user
|
||||
drush user:unblock username
|
||||
```
|
||||
|
||||
## Content Management
|
||||
|
||||
```bash
|
||||
# Generate test content
|
||||
drush devel:generate:content 50 --bundles=article
|
||||
|
||||
# Delete content
|
||||
drush entity:delete node --bundle=article
|
||||
|
||||
# Generate users
|
||||
drush devel:generate:users 20
|
||||
```
|
||||
|
||||
## State Management
|
||||
|
||||
```bash
|
||||
# Get state value
|
||||
drush state:get system.maintenance_mode
|
||||
|
||||
# Set state value
|
||||
drush state:set system.maintenance_mode 1
|
||||
|
||||
# Delete state value
|
||||
drush state:delete mymodule.last_run
|
||||
```
|
||||
|
||||
## Theme Management
|
||||
|
||||
```bash
|
||||
# List all themes
|
||||
drush theme:list
|
||||
|
||||
# Enable theme
|
||||
drush theme:enable mytheme
|
||||
|
||||
# Uninstall theme
|
||||
drush theme:uninstall oldtheme
|
||||
|
||||
# Set default theme
|
||||
drush config:set system.theme default mytheme
|
||||
```
|
||||
|
||||
## Cron
|
||||
|
||||
```bash
|
||||
# Run cron
|
||||
drush cron
|
||||
|
||||
# Run cron for specific module
|
||||
drush cron mymodule
|
||||
```
|
||||
|
||||
## Status & Information
|
||||
|
||||
```bash
|
||||
# Show site status
|
||||
drush status
|
||||
drush st
|
||||
|
||||
# Show core status and available updates
|
||||
drush pm:security
|
||||
|
||||
# Show Drupal version
|
||||
drush core:status
|
||||
|
||||
# Show requirements report
|
||||
drush core:requirements
|
||||
```
|
||||
|
||||
## Development & Debugging
|
||||
|
||||
```bash
|
||||
# Watch for file changes and clear cache
|
||||
drush watchdog:tail
|
||||
|
||||
# Show recent log messages
|
||||
drush watchdog:show
|
||||
|
||||
# Show recent log messages and follow
|
||||
drush watchdog:tail
|
||||
|
||||
# Evaluate PHP code
|
||||
drush php:eval "echo \Drupal::VERSION;"
|
||||
drush ev "echo \Drupal::VERSION;"
|
||||
|
||||
# Open PHP REPL
|
||||
drush php:cli
|
||||
```
|
||||
|
||||
## Generate Code (Drush Generate)
|
||||
|
||||
```bash
|
||||
# Generate module
|
||||
drush generate module
|
||||
|
||||
# Generate controller
|
||||
drush generate controller
|
||||
|
||||
# Generate form
|
||||
drush generate form
|
||||
|
||||
# Generate plugin block
|
||||
drush generate plugin:block
|
||||
|
||||
# Generate service
|
||||
drush generate service
|
||||
|
||||
# Generate theme
|
||||
drush generate theme
|
||||
|
||||
# Generate hook implementation
|
||||
drush generate hook
|
||||
|
||||
# Generate event subscriber
|
||||
drush generate event-subscriber
|
||||
|
||||
# List all generators
|
||||
drush generate --help
|
||||
```
|
||||
|
||||
## Field Management
|
||||
|
||||
```bash
|
||||
# Create field
|
||||
drush field:create node.article.field_custom
|
||||
|
||||
# Delete field
|
||||
drush field:delete node.article.field_custom
|
||||
|
||||
# List fields
|
||||
drush field:list
|
||||
```
|
||||
|
||||
## Locale/Translation
|
||||
|
||||
```bash
|
||||
# Import translations
|
||||
drush locale:import de
|
||||
|
||||
# Update translations
|
||||
drush locale:update
|
||||
|
||||
# Check translation status
|
||||
drush locale:check
|
||||
```
|
||||
|
||||
## Queue Management
|
||||
|
||||
```bash
|
||||
# Run specific queue
|
||||
drush queue:run mymodule_queue
|
||||
|
||||
# List all queues
|
||||
drush queue:list
|
||||
|
||||
# Delete items from queue
|
||||
drush queue:delete mymodule_queue
|
||||
```
|
||||
|
||||
## Deployment Commands
|
||||
|
||||
```bash
|
||||
# Standard deployment workflow
|
||||
drush updatedb -y
|
||||
drush config:import -y
|
||||
drush cache:rebuild
|
||||
|
||||
# One-liner deployment
|
||||
drush updb -y && drush cim -y && drush cr
|
||||
```
|
||||
|
||||
## Site Installation
|
||||
|
||||
```bash
|
||||
# Install Drupal site
|
||||
drush site:install standard --db-url=mysql://user:pass@localhost/dbname --account-name=admin --account-pass=admin
|
||||
|
||||
# Install with configuration
|
||||
drush site:install --existing-config
|
||||
```
|
||||
|
||||
## Alias Usage
|
||||
|
||||
Drush aliases allow running commands on remote sites.
|
||||
|
||||
```bash
|
||||
# Run command on remote site
|
||||
drush @production cache:rebuild
|
||||
|
||||
# Sync database from remote to local
|
||||
drush sql:sync @production @self
|
||||
|
||||
# Sync files from remote to local
|
||||
drush rsync @production:%files @self:%files
|
||||
```
|
||||
|
||||
## Useful Flags
|
||||
|
||||
```bash
|
||||
# -y: Assume "yes" to all prompts
|
||||
drush en mymodule -y
|
||||
|
||||
# -v: Verbose output
|
||||
drush cache:rebuild -v
|
||||
|
||||
# --uri: Specify site URI (multisite)
|
||||
drush --uri=example.com cache:rebuild
|
||||
|
||||
# --root: Specify Drupal root directory
|
||||
drush --root=/var/www/html cache:rebuild
|
||||
|
||||
# --debug: Show debug information
|
||||
drush --debug cache:rebuild
|
||||
```
|
||||
|
||||
## Custom Drush Commands
|
||||
|
||||
Create custom Drush commands by implementing Drush command files in your module:
|
||||
|
||||
**mymodule/src/Commands/MyModuleCommands.php**
|
||||
```php
|
||||
<?php
|
||||
|
||||
namespace Drupal\mymodule\Commands;
|
||||
|
||||
use Drush\Commands\DrushCommands;
|
||||
|
||||
/**
|
||||
* Custom Drush commands for mymodule.
|
||||
*/
|
||||
class MyModuleCommands extends DrushCommands {
|
||||
|
||||
/**
|
||||
* Performs a custom operation.
|
||||
*
|
||||
* @command mymodule:custom-operation
|
||||
* @aliases mco
|
||||
* @usage mymodule:custom-operation
|
||||
* Runs the custom operation.
|
||||
*/
|
||||
public function customOperation() {
|
||||
$this->output()->writeln('Running custom operation...');
|
||||
// Your custom logic here
|
||||
$this->logger()->success('Operation completed successfully!');
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **Aliases**: Create aliases in `drush/sites/` for easier multi-site management
|
||||
2. **Automation**: Use Drush commands in deployment scripts
|
||||
3. **Backup**: Always backup before running destructive commands
|
||||
4. **Testing**: Test Drush scripts in development before production
|
||||
5. **Version**: Check Drush version compatibility with `drush --version`
|
||||
6. **Performance**: Use `drush status` to verify environment configuration
|
||||
Reference in New Issue
Block a user