##
# phpMyFAQ .htaccess file for Apache 2.x
#
# This Source Code Form is subject to the terms of the Mozilla Public License,
# v. 2.0. If a copy of the MPL was not distributed with this file, You can
# obtain one at https://mozilla.org/MPL/2.0/.
#
# @author    Thorsten Rinne <thorsten@phpmyfaq.de>
# @author    Patrick Preuster <sica@php-q.net>
# @author    Matteo Scaramuccia <matteo@scaramuccia.com>
# @copyright 2004-2024 phpMyFAQ Team
# @license   http://www.mozilla.org/MPL/2.0/ Mozilla Public License Version 2.0
# @link      https://www.phpmyfaq.de
# @since     2004-11-13
DirectoryIndex index.php
# always follow the symlinks
<IfModule mod_negotiation.c>
    Options +FollowSymlinks -MultiViews -Indexes
</IfModule>
# Increase upload limits for PHP (adjust as needed)
# Note: php_value only works with mod_php; for PHP-FPM, set these in php.ini or .user.ini
<IfModule mod_php.c>
    php_value upload_max_filesize 100M
    php_value post_max_size 100M
    php_value max_execution_time 300
    php_value max_input_time 300
</IfModule>
<IfModule mod_php8.c>
    php_value upload_max_filesize 100M
    php_value post_max_size 100M
    php_value max_execution_time 300
    php_value max_input_time 300
</IfModule>
# X-Frame-Options to prevent clickjacking
<IfModule mod_headers.c>
    Header always append X-Frame-Options SAMEORIGIN
    # CORS
    Header set Access-Control-Allow-Origin "*"
    Header set Access-Control-Allow-Methods "GET,PUT,POST,DELETE"
    Header set Access-Control-Allow-Headers "Content-Type, Authorization"
</IfModule>
# Set cache control
<filesMatch ".(ico|pdf|flv|jpg|jpeg|png|gif|js|css|swf)$">
    Header set Cache-Control "max-age=84600, no-store"
    Header set Pragma "no-cache"
</filesMatch>
# Set Gzip compression
<IfModule mod_deflate.c>
    AddOutputFilterByType DEFLATE application/javascript
    AddOutputFilterByType DEFLATE application/json
    AddOutputFilterByType DEFLATE application/rss+xml
    AddOutputFilterByType DEFLATE application/vnd.ms-fontobject
    AddOutputFilterByType DEFLATE application/x-font
    AddOutputFilterByType DEFLATE application/x-font-opentype
    AddOutputFilterByType DEFLATE application/x-font-otf
    AddOutputFilterByType DEFLATE application/x-font-truetype
    AddOutputFilterByType DEFLATE application/x-font-ttf
    AddOutputFilterByType DEFLATE application/x-javascript
    AddOutputFilterByType DEFLATE application/xhtml+xml
    AddOutputFilterByType DEFLATE application/xml
    AddOutputFilterByType DEFLATE font/opentype
    AddOutputFilterByType DEFLATE font/otf
    AddOutputFilterByType DEFLATE font/ttf
    AddOutputFilterByType DEFLATE image/svg+xml
    AddOutputFilterByType DEFLATE image/x-icon
    AddOutputFilterByType DEFLATE text/css
    AddOutputFilterByType DEFLATE text/html
    AddOutputFilterByType DEFLATE text/javascript
    AddOutputFilterByType DEFLATE text/plain
    AddOutputFilterByType DEFLATE text/xml
</IfModule>
# Enable Expires headers to set expiration dates for various file types
<IfModule mod_expires.c>
    ExpiresActive On
    # Set expiration for image files to 1 year
    ExpiresByType image/jpeg "access plus 1 year"
    ExpiresByType image/gif "access plus 1 year"
    ExpiresByType image/png "access plus 1 year"
    ExpiresByType image/webp "access plus 1 year"
    ExpiresByType image/svg+xml "access plus 1 year"
    ExpiresByType image/x-icon "access plus 1 year"
    # Set expiration for video files to 1 year
    ExpiresByType video/webm "access plus 1 year"
    ExpiresByType video/mp4 "access plus 1 year"
    ExpiresByType video/mpeg "access plus 1 year"
    # Set expiration for font files to 1 year
    ExpiresByType font/ttf "access plus 1 year"
    ExpiresByType font/otf "access plus 1 year"
    ExpiresByType font/woff "access plus 1 year"
    ExpiresByType font/woff2 "access plus 1 year"
    ExpiresByType application/font-woff "access plus 1 year"
    ExpiresByType application/font-woff2 "access plus 1 year"
    # Set expiration for CSS and JavaScript files to 1 year
    ExpiresByType text/css "access plus 1 year"
    ExpiresByType text/javascript "access plus 1 year"
    ExpiresByType application/javascript "access plus 1 year"
    # Set expiration for other file types to 1 year
    ExpiresByType application/pdf "access plus 1 year"
    ExpiresByType image/vnd.microsoft.icon "access plus 1 year"
</IfModule>
# Enable Cache-Control headers to set caching policies for various file types
<IfModule mod_headers.c>
    <FilesMatch "\.(flv|gif|ico|jpg|jpeg|mp4|mpeg|png|svg|swf|webp|webm|js|pdf|css|woff|woff2)$">
        Header set Cache-Control "max-age=31536000, public"
    </FilesMatch>
</IfModule>
# Set mod_rewrite
<IfModule mod_rewrite.c>
    # This has to be 'On'
    RewriteEngine On
    <IfModule mod_fcgid.c>
        RewriteCond %{HTTP:Authorization} .
        RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
    </IfModule>
    # the path to your phpMyFAQ installation
    RewriteBase /
    # Block zip files in content directory
    RewriteRule ^content/.*\.zip$ - [F,L]
    # Block direct access to server-side internals under content/core/
    # (user tracking logs, configuration with DB credentials, logs, caches).
    # The tracking logs may contain sensitive query strings such as password
    # reset signatures, so they must never be served to HTTP clients.
    RewriteRule ^content/core/ - [F,L]
    # Block direct access to attachments: downloads must go through the
    # permission-checked /attachment/{id} controller
    RewriteRule ^content/user/attachments/ - [F,L]
    # Exclude assets from being handled by Symfony Router
    RewriteRule ^admin/assets($|/) - [L]
    # Error pages
    ErrorDocument 404 /404.html
    # Administration API
    RewriteRule ^admin/api/ admin/api/index.php [L,QSA]
    # Administration pages (redirect /admin to /admin/)
    RewriteRule ^admin$ admin/ [R=301,L]
    RewriteRule ^admin/ admin/index.php [L,QSA]
    # API routes (all API endpoints)
    RewriteRule ^api/ api/index.php [L,QSA]
    # Setup pages
    RewriteRule ^setup/ setup/index.php [L,QSA]
    # Update page - route directly to index.php (handled by Symfony router)
    RewriteRule ^update$ index.php [L,QSA]
    RewriteRule ^update/ index.php [L,QSA]
    # Front controller: route all other requests to index.php (Symfony Router)
    # Skip if the file or directory exists
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^ index.php [L]
</IfModule>
