İlk temizlik tamamlandı bir önceki projeden
This commit is contained in:
@@ -0,0 +1,664 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use App\Models\DocumentManagerPermission;
|
||||
|
||||
class CustomElfinderController extends Controller
|
||||
{
|
||||
/**
|
||||
* Cache for access results to avoid repeated calculations
|
||||
*/
|
||||
private static $accessCache = [];
|
||||
|
||||
/**
|
||||
* Cached user instance
|
||||
*/
|
||||
private static $currentUser = null;
|
||||
|
||||
/**
|
||||
* Custom access control for Elfinder
|
||||
*
|
||||
* @param string $attr - Operation type (read, write, rm, etc.)
|
||||
* @param string $path - File/folder path
|
||||
* @param array $data - Additional data
|
||||
* @param object $volume - Volume object
|
||||
* @return bool - Whether access is allowed
|
||||
*/
|
||||
public static function access($attr, $path, $data, $volume)
|
||||
{
|
||||
// 1. Check access cache (Critical Optimization)
|
||||
// Using path + attr as key
|
||||
$cacheKey = $path . '#' . $attr;
|
||||
if (isset(self::$accessCache[$cacheKey])) {
|
||||
return self::$accessCache[$cacheKey];
|
||||
}
|
||||
|
||||
// 2. Get User (Cached)
|
||||
if (self::$currentUser === null) {
|
||||
self::$currentUser = Auth::user();
|
||||
}
|
||||
$user = self::$currentUser;
|
||||
|
||||
// If user is not authenticated, deny access
|
||||
if (!$user) {
|
||||
return self::$accessCache[$cacheKey] = false;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------
|
||||
// GLOBAL EXCLUSION LIST (Hidden for EVERYONE - INCLUDING ADMINS)
|
||||
// ---------------------------------------------------------
|
||||
// Moved BEFORE admin check to ensure these are hidden for admins too
|
||||
|
||||
// Get folder name from path early (needed for checks)
|
||||
$folderName = self::getFolderNameFromPath($path);
|
||||
|
||||
// Default exclusions if setting is empty
|
||||
$defaultExclusions = [
|
||||
'.tmb',
|
||||
'cache',
|
||||
'register_creator_errors',
|
||||
'test',
|
||||
'NewFolder 1',
|
||||
'files',
|
||||
'document-templates',
|
||||
'Excel Form Templates',
|
||||
'Archive'
|
||||
];
|
||||
|
||||
// Get from settings - Cache this if possible or trust Laravel's config cache
|
||||
static $globalExcludedFolders = null;
|
||||
if ($globalExcludedFolders === null) {
|
||||
$settingsJson = setting('global_excluded_folders');
|
||||
$settingsExclusions = [];
|
||||
if (!empty($settingsJson)) {
|
||||
$settingsExclusions = json_decode($settingsJson, true);
|
||||
}
|
||||
$globalExcludedFolders = !empty($settingsExclusions) ? $settingsExclusions : $defaultExclusions;
|
||||
}
|
||||
|
||||
// Check if it is a root folder (no slashes in normalized path)
|
||||
$isRootFolder = strpos($folderName, '/') === false;
|
||||
|
||||
if ($isRootFolder && in_array($folderName, $globalExcludedFolders)) {
|
||||
// Hide from list
|
||||
if ($attr === 'hidden') {
|
||||
return self::$accessCache[$cacheKey] = true;
|
||||
}
|
||||
// Block read access to effectively hide contents too
|
||||
if ($attr === 'read') {
|
||||
return self::$accessCache[$cacheKey] = false;
|
||||
}
|
||||
}
|
||||
// ---------------------------------------------------------
|
||||
|
||||
// 3. Admin Optimization (Fast Track)
|
||||
if ($user->level == "Admin") {
|
||||
// Validate path for security (fast check)
|
||||
if (strpos($path, '..') !== false) {
|
||||
return self::$accessCache[$cacheKey] = false;
|
||||
}
|
||||
|
||||
// Special handling for operations that need false (NOT locked/hidden)
|
||||
if ($attr === 'hidden' || $attr === 'locked') {
|
||||
return self::$accessCache[$cacheKey] = false; // false means NOT hidden/locked (writable/deletable)
|
||||
}
|
||||
|
||||
return self::$accessCache[$cacheKey] = true; // true means ALLOW operation (read/write/rm/etc)
|
||||
}
|
||||
|
||||
// Validate path for security (Normal users)
|
||||
if (!self::validatePath($path)) {
|
||||
Log::warning("Path validation failed", ['path' => $path, 'user' => $user->level]);
|
||||
return self::$accessCache[$cacheKey] = false;
|
||||
}
|
||||
|
||||
// folderName already retrieved above for global exclusion check
|
||||
// $folderName = self::getFolderNameFromPath($path);
|
||||
|
||||
// ---------------------------------------------------------
|
||||
// GLOBAL EXCLUSION LIST (Moved to top)
|
||||
// ---------------------------------------------------------
|
||||
|
||||
// For non-admin users, handle system folders based on operation
|
||||
if (self::isSystemFolder($folderName)) {
|
||||
// For these operations, explicitly hide/lock system folders
|
||||
if (in_array($attr, ['read', 'write', 'upload', 'mkdir', 'mkfile', 'rename', 'copy', 'move', 'rm', 'edit'])) {
|
||||
return self::$accessCache[$cacheKey] = false; // Block these operations
|
||||
}
|
||||
|
||||
// For hidden check, return true to hide
|
||||
if ($attr === 'hidden') {
|
||||
return self::$accessCache[$cacheKey] = true; // Hide system folders from non-admin
|
||||
}
|
||||
|
||||
// For locked check, return true to lock
|
||||
if ($attr === 'locked') {
|
||||
return self::$accessCache[$cacheKey] = true; // Lock system folders for non-admin
|
||||
}
|
||||
|
||||
// For other operations, return null (use default behavior)
|
||||
return self::$accessCache[$cacheKey] = null;
|
||||
}
|
||||
|
||||
// For other users, implement basic permission checks
|
||||
$module = "document-manager";
|
||||
|
||||
// Check basic module permission first
|
||||
// Cache basic permissions
|
||||
static $modulePermissions = [];
|
||||
if (!isset($modulePermissions[$user->level])) {
|
||||
$modulePermissions[$user->level] = [
|
||||
'read' => isAuth($module, "read"),
|
||||
'write' => isAuth($module, "write"),
|
||||
'modify' => isAuth($module, "modify")
|
||||
];
|
||||
}
|
||||
|
||||
$hasModuleRead = $modulePermissions[$user->level]['read'];
|
||||
$hasModuleWrite = $modulePermissions[$user->level]['write'];
|
||||
$hasModuleModify = $modulePermissions[$user->level]['modify'];
|
||||
|
||||
/*
|
||||
// DEBUG: Check if PTO user has basic permissions
|
||||
if ($user->level === 'Manager (PTO)') {
|
||||
error_log("PTO User Basic Permissions - Read: " . ($hasModuleRead ? 'YES' : 'NO') . ", Write: " . ($hasModuleWrite ? 'YES' : 'NO') . ", Modify: " . ($hasModuleModify ? 'YES' : 'NO'));
|
||||
}
|
||||
*/
|
||||
|
||||
// Debug logging - enabled for testing
|
||||
/*
|
||||
Log::info("Elfinder Access Check", [
|
||||
'user_level' => $user->level,
|
||||
'user_id' => $user->id ?? 'unknown',
|
||||
'attr' => $attr,
|
||||
'path' => $path,
|
||||
'folder_name' => $folderName,
|
||||
'module' => $module,
|
||||
'permission_separation' => 'write_edit_separated',
|
||||
'is_dir' => is_dir($path),
|
||||
'is_file' => is_file($path),
|
||||
'path_exists' => file_exists($path),
|
||||
'has_module_read' => $hasModuleRead,
|
||||
'has_module_write' => $hasModuleWrite,
|
||||
'has_module_modify' => $hasModuleModify
|
||||
]);
|
||||
*/
|
||||
|
||||
switch($attr) {
|
||||
case 'read':
|
||||
// For folders, check if user should see this folder at all
|
||||
if (is_dir($path)) {
|
||||
// First check if this is a system folder for non-admin users
|
||||
if ($user->level !== "Admin" && self::isSystemFolder($folderName)) {
|
||||
return self::$accessCache[$cacheKey] = false; // Block system folders from non-admin
|
||||
}
|
||||
|
||||
return self::$accessCache[$cacheKey] = self::checkFolderVisibility($user, $folderName, $module);
|
||||
} else {
|
||||
// For files, check if parent folder is system folder for non-admin
|
||||
if ($user->level !== "Admin" && self::isSystemFolder($folderName)) {
|
||||
return self::$accessCache[$cacheKey] = false; // Block files in system folders from non-admin
|
||||
}
|
||||
|
||||
// For files, check read permission
|
||||
return self::checkFolderReadPermission($user, $folderName, $module);
|
||||
}
|
||||
|
||||
case 'write':
|
||||
case 'upload':
|
||||
case 'mkdir':
|
||||
case 'mkfile':
|
||||
case 'rename':
|
||||
case 'copy':
|
||||
case 'move':
|
||||
// Check if user has write permission for this specific folder
|
||||
$writeAuth = self::checkFolderWritePermission($user, $folderName, $module);
|
||||
// Log::info("Write permission check", ['result' => $writeAuth, 'folder' => $folderName, 'operation' => $attr]);
|
||||
return self::$accessCache[$cacheKey] = $writeAuth;
|
||||
|
||||
case 'edit':
|
||||
// Special handling for edit operations - check file type and edit permission
|
||||
$editAuth = self::checkFileEditPermission($user, $path, $module);
|
||||
// Log::info("Edit permission check", ['result' => $editAuth, 'path' => $path, 'operation' => $attr]);
|
||||
return self::$accessCache[$cacheKey] = $editAuth;
|
||||
|
||||
case 'rm':
|
||||
// Check if user has delete permission for this specific folder
|
||||
$rmAuth = self::checkFolderDeletePermission($user, $folderName, $module);
|
||||
// Log::info("Remove permission check", ['result' => $rmAuth, 'folder' => $folderName]);
|
||||
|
||||
// Additional protection for critical files
|
||||
if (self::isCriticalFile($path)) {
|
||||
// Log::info("Critical file protection - delete blocked", ['path' => $path]);
|
||||
return self::$accessCache[$cacheKey] = false;
|
||||
}
|
||||
|
||||
return self::$accessCache[$cacheKey] = $rmAuth;
|
||||
|
||||
case 'hidden':
|
||||
// Check if folder should be hidden from user
|
||||
// For non-admin users, hide system folders
|
||||
if ($user->level !== "Admin") {
|
||||
if (self::isSystemFolder($folderName)) {
|
||||
return self::$accessCache[$cacheKey] = true; // Hide system folders from non-admin
|
||||
}
|
||||
}
|
||||
|
||||
// Check general visibility
|
||||
return self::$accessCache[$cacheKey] = !self::checkFolderVisibility($user, $folderName, $module);
|
||||
|
||||
default:
|
||||
// For other operations, return null for default behavior
|
||||
/*
|
||||
Log::info("Default permission check", [
|
||||
'attr' => $attr,
|
||||
'folder' => $folderName,
|
||||
'user_level' => $user->level
|
||||
]);
|
||||
*/
|
||||
return self::$accessCache[$cacheKey] = null; // Use Elfinder's default behavior
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Cache for folder names to improve performance
|
||||
*/
|
||||
private static $folderNameCache = [];
|
||||
|
||||
/**
|
||||
* Get folder name from path with improved path normalization (supports subfolders)
|
||||
*/
|
||||
private static function getFolderNameFromPath($path)
|
||||
{
|
||||
// Check cache first
|
||||
if (isset(self::$folderNameCache[$path])) {
|
||||
return self::$folderNameCache[$path];
|
||||
}
|
||||
|
||||
$originalPath = $path;
|
||||
|
||||
// Normalize path separators
|
||||
$path = str_replace('\\', '/', $path);
|
||||
|
||||
// Remove common path prefixes (case-insensitive)
|
||||
$path = preg_replace('#^.*?/storage/documents/?#i', '', $path);
|
||||
$path = preg_replace('#^.*?/storage/office-server/?#i', '', $path);
|
||||
$path = preg_replace('#^.*?/public/storage/documents/?#i', '', $path);
|
||||
$path = preg_replace('#^.*?/public/storage/office-server/?#i', '', $path);
|
||||
$path = preg_replace('#^.*?/Applications/MAMP/htdocs/stellar/public/storage/documents/?#i', '', $path);
|
||||
$path = preg_replace('#^.*?/Applications/MAMP/htdocs/stellar/public/storage/office-server/?#i', '', $path);
|
||||
|
||||
// Additional path patterns for Elfinder
|
||||
$path = preg_replace('#^.*?/storage/documents$#i', '', $path);
|
||||
$path = preg_replace('#^.*?/storage/documents/$#i', '', $path);
|
||||
|
||||
// Clean up any remaining leading/trailing slashes
|
||||
$path = trim($path, '/');
|
||||
|
||||
// For subfolder support, return the full relative path instead of just first folder
|
||||
// This allows us to check permissions for specific subfolders
|
||||
$folderName = $path;
|
||||
|
||||
// Log path processing for debugging
|
||||
/*
|
||||
Log::info("Path processing", [
|
||||
'original_path' => $originalPath,
|
||||
'normalized_path' => $path,
|
||||
'folder_name' => $folderName,
|
||||
'has_slashes' => strpos($folderName, '/') !== false,
|
||||
'is_empty' => empty($folderName)
|
||||
]);
|
||||
*/
|
||||
|
||||
self::$folderNameCache[$originalPath] = $folderName;
|
||||
|
||||
return $folderName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if folder should be visible to user (for folder listing)
|
||||
*/
|
||||
private static function checkFolderVisibility($user, $folderName, $module)
|
||||
{
|
||||
// Root path - always visible if user has basic read permission
|
||||
if (empty($folderName)) {
|
||||
return isAuth($module, "read");
|
||||
}
|
||||
|
||||
// Office Server files - only Admin can see
|
||||
if (self::isOfficeServerPath($folderName)) {
|
||||
return $user->level == "Admin";
|
||||
}
|
||||
|
||||
// Check if this is a system folder - only Admin can see
|
||||
if (self::isSystemFolder($folderName)) {
|
||||
return $user->level == "Admin";
|
||||
}
|
||||
|
||||
// Check if user has any permission for this folder (read, write, or edit)
|
||||
// This includes both explicit permissions and inherited permissions
|
||||
$hasReadPermission = self::checkFolderReadPermission($user, $folderName, $module);
|
||||
$hasWritePermission = self::checkFolderWritePermission($user, $folderName, $module);
|
||||
$hasEditPermission = self::checkFolderEditPermission($user, $folderName, $module);
|
||||
|
||||
return $hasReadPermission || $hasWritePermission || $hasEditPermission;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if user has read permission for specific folder
|
||||
*/
|
||||
private static function checkFolderReadPermission($user, $folderName, $module)
|
||||
{
|
||||
// Root path - allow access if user has basic read permission
|
||||
if (empty($folderName)) {
|
||||
return isAuth($module, "read");
|
||||
}
|
||||
|
||||
// Office Server files - only Admin can read
|
||||
if (self::isOfficeServerPath($folderName)) {
|
||||
return $user->level == "Admin";
|
||||
}
|
||||
|
||||
// Check dynamic permission using cached/recursive check
|
||||
return self::checkDynamicPermission($user->level, $folderName, 'read');
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if user has write permission for specific folder
|
||||
* Write permission covers: upload, create, rename, copy, move, delete
|
||||
*/
|
||||
private static function checkFolderWritePermission($user, $folderName, $module)
|
||||
{
|
||||
// Office Server files - only Admin can write
|
||||
if (self::isOfficeServerPath($folderName)) {
|
||||
return $user->level == "Admin";
|
||||
}
|
||||
|
||||
// Check dynamic permission using cached/recursive check
|
||||
return self::checkDynamicPermission($user->level, $folderName, 'write');
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if user has edit permission for specific folder
|
||||
* Edit permission covers: edit file content only (not file operations)
|
||||
*/
|
||||
private static function checkFolderEditPermission($user, $folderName, $module)
|
||||
{
|
||||
// Office Server files - only Admin can edit
|
||||
if (self::isOfficeServerPath($folderName)) {
|
||||
return $user->level == "Admin";
|
||||
}
|
||||
|
||||
// Check dynamic permission using cached/recursive check
|
||||
return self::checkDynamicPermission($user->level, $folderName, 'edit');
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if user has delete permission for specific folder
|
||||
*/
|
||||
private static function checkFolderDeletePermission($user, $folderName, $module)
|
||||
{
|
||||
// Office Server files - only Admin can delete
|
||||
if (self::isOfficeServerPath($folderName)) {
|
||||
return $user->level == "Admin";
|
||||
}
|
||||
|
||||
// Delete permission uses write permission (write includes delete operations)
|
||||
return self::checkFolderWritePermission($user, $folderName, $module);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if user can edit specific file types based on edit permission
|
||||
* Edit permission covers: edit file content only (not file operations)
|
||||
*/
|
||||
private static function checkFileEditPermission($user, $path, $module)
|
||||
{
|
||||
// Get file extension
|
||||
$extension = strtolower(pathinfo($path, PATHINFO_EXTENSION));
|
||||
|
||||
// Define editable file types
|
||||
$editableFileTypes = ['pdf', 'xlsx', 'xlsb', 'csv', 'doc', 'docx', 'txt'];
|
||||
|
||||
// Check if file type is editable
|
||||
if (!in_array($extension, $editableFileTypes)) {
|
||||
Log::info("File type not editable", ['extension' => $extension, 'path' => $path]);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check folder-based permissions for edit
|
||||
$folderName = self::getFolderNameFromPath($path);
|
||||
|
||||
// Check dynamic permission using cached/recursive check
|
||||
return self::checkDynamicPermission($user->level, $folderName, 'edit');
|
||||
}
|
||||
|
||||
/**
|
||||
* Static cache for permissions during a single request
|
||||
* Structure: ['UserLevel' => ['folder/path' => ['read' => bool, 'write' => bool]]]
|
||||
*/
|
||||
private static $permissionsCache = [];
|
||||
|
||||
/**
|
||||
* Load all permissions for a user level into static cache
|
||||
*/
|
||||
private static function loadPermissionsIntoCache($userLevel)
|
||||
{
|
||||
if (isset(self::$permissionsCache[$userLevel])) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get all permissions from Model (which uses Redis/File Cache)
|
||||
// This returns a collection grouped by folder_path
|
||||
$rawPermissions = \App\Models\DocumentManagerPermission::getUserLevelPermissions($userLevel);
|
||||
|
||||
$formatted = [];
|
||||
foreach ($rawPermissions as $path => $permissions) {
|
||||
$formatted[$path] = [];
|
||||
foreach ($permissions as $perm) {
|
||||
// Store the boolean value directly
|
||||
$formatted[$path][$perm->permission_type] = $perm->is_allowed;
|
||||
}
|
||||
}
|
||||
|
||||
self::$permissionsCache[$userLevel] = $formatted;
|
||||
|
||||
Log::info("Permissions loaded into static cache", [
|
||||
'user_level' => $userLevel,
|
||||
'folder_count' => count($formatted)
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check dynamic permission using cached data with inheritance
|
||||
*/
|
||||
private static function checkDynamicPermission($userLevel, $folderName, $permissionType)
|
||||
{
|
||||
// Ensure cache is loaded
|
||||
self::loadPermissionsIntoCache($userLevel);
|
||||
|
||||
// 1. Check for explicit permission on this folder
|
||||
if (isset(self::$permissionsCache[$userLevel][$folderName])) {
|
||||
$folderPerms = self::$permissionsCache[$userLevel][$folderName];
|
||||
|
||||
if (isset($folderPerms[$permissionType])) {
|
||||
// Explicit permission found (either true or false)
|
||||
// Return exactly what is set, do not inherit if explicitly set
|
||||
return $folderPerms[$permissionType];
|
||||
}
|
||||
}
|
||||
|
||||
// 2. If no explicit permission, check parent folder inheritance
|
||||
// BUT ONLY for subfolders, not for main folders
|
||||
$parentFolder = self::getParentFolder($folderName);
|
||||
if ($parentFolder && $parentFolder !== $folderName && strpos($folderName, '/') !== false) {
|
||||
$inherited = self::checkDynamicPermission($userLevel, $parentFolder, $permissionType);
|
||||
if ($inherited) {
|
||||
// Log only if allowed via inheritance (to reduce noise)
|
||||
// Log::info("Permission granted via inheritance", ['folder' => $folderName, 'parent' => $parentFolder, 'type' => $permissionType]);
|
||||
}
|
||||
return $inherited;
|
||||
}
|
||||
|
||||
// 3. No explicit permission and no parent - default deny
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get parent folder from a folder path
|
||||
*/
|
||||
private static function getParentFolder($folderPath)
|
||||
{
|
||||
// Remove trailing slash if exists
|
||||
$folderPath = rtrim($folderPath, '/');
|
||||
|
||||
// Split by slash
|
||||
$parts = explode('/', $folderPath);
|
||||
|
||||
// If only one part, no parent
|
||||
if (count($parts) <= 1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Remove last part to get parent
|
||||
array_pop($parts);
|
||||
return implode('/', $parts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if file is a critical system file that should be protected
|
||||
*/
|
||||
private static function isCriticalFile($path)
|
||||
{
|
||||
$fileName = basename($path);
|
||||
$criticalFiles = [
|
||||
'index.php',
|
||||
'config.php',
|
||||
'.htaccess',
|
||||
'web.config',
|
||||
'robots.txt',
|
||||
'sitemap.xml',
|
||||
'.env',
|
||||
'composer.json',
|
||||
'composer.lock',
|
||||
'package.json',
|
||||
'yarn.lock'
|
||||
];
|
||||
|
||||
return in_array(strtolower($fileName), array_map('strtolower', $criticalFiles));
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate file path for security
|
||||
*/
|
||||
private static function validatePath($path)
|
||||
{
|
||||
// Check for path traversal attempts
|
||||
if (strpos($path, '..') !== false || strpos($path, '//') !== false) {
|
||||
Log::warning("Path traversal attempt detected", ['path' => $path]);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check for suspicious file extensions
|
||||
$extension = strtolower(pathinfo($path, PATHINFO_EXTENSION));
|
||||
$dangerousExtensions = ['php', 'php3', 'php4', 'php5', 'phtml', 'exe', 'bat', 'cmd', 'sh', 'js'];
|
||||
|
||||
if (in_array($extension, $dangerousExtensions)) {
|
||||
Log::warning("Dangerous file extension detected", ['path' => $path, 'extension' => $extension]);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get file size in human readable format
|
||||
*/
|
||||
private static function formatFileSize($bytes)
|
||||
{
|
||||
$units = ['B', 'KB', 'MB', 'GB', 'TB'];
|
||||
|
||||
for ($i = 0; $bytes > 1024 && $i < count($units) - 1; $i++) {
|
||||
$bytes /= 1024;
|
||||
}
|
||||
|
||||
return round($bytes, 2) . ' ' . $units[$i];
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if path is in Office Server directory
|
||||
*/
|
||||
private static function isOfficeServerPath($folderName)
|
||||
{
|
||||
// Check if the path contains office-server
|
||||
return strpos($folderName, 'office-server') !== false ||
|
||||
strpos($folderName, 'Office_Server') !== false ||
|
||||
strpos($folderName, 'office_server') !== false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if path is a network drive path
|
||||
*/
|
||||
private static function isNetworkDrivePath($path)
|
||||
{
|
||||
// Check for network drive patterns
|
||||
$networkPatterns = [
|
||||
'/^\\\\/', // Windows UNC path
|
||||
'/^\/\/[^\/]+/', // Unix network path
|
||||
'/^smb:\/\//', // SMB protocol
|
||||
'/^cifs:\/\//', // CIFS protocol
|
||||
];
|
||||
|
||||
foreach ($networkPatterns as $pattern) {
|
||||
if (preg_match($pattern, $path)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if folder is a system folder (only visible to Admin)
|
||||
* System folders are defined in config/document-folders.php
|
||||
* Uses static cache for performance optimization
|
||||
*/
|
||||
private static function isSystemFolder($folderName)
|
||||
{
|
||||
// Static cache to avoid repeated config reads
|
||||
static $exactMatches = null;
|
||||
static $regexPatterns = null;
|
||||
static $cache = [];
|
||||
|
||||
// Return cached result if available
|
||||
if (isset($cache[$folderName])) {
|
||||
return $cache[$folderName];
|
||||
}
|
||||
|
||||
// Load patterns once
|
||||
if ($exactMatches === null) {
|
||||
$exactMatches = config('document-folders.system_patterns.exact', []);
|
||||
$regexPatterns = config('document-folders.system_patterns.regex', []);
|
||||
}
|
||||
|
||||
// Check exact matches first (faster)
|
||||
if (in_array($folderName, $exactMatches)) {
|
||||
$cache[$folderName] = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check regex patterns
|
||||
foreach ($regexPatterns as $pattern) {
|
||||
if (preg_match($pattern, $folderName)) {
|
||||
$cache[$folderName] = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
$cache[$folderName] = false;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user