core-bundle/src/Resources/contao/library/Contao/Dbafs.php
public static function addResource($strResource, $blnUpdateFolders=true)
	{
		$strUploadPath = Config::get('uploadPath') . '/';
		$rootDir = System::getContainer()->getParameter('kernel.project_dir');

		// Remove trailing slashes (see #5707)
		if (substr($strResource, -1) == '/')
		{
			$strResource = substr($strResource, 0, -1);
		}

		// Normalize the path (see #6034)
		$strResource = str_replace(array('\\', '//'), '/', $strResource);

		// The resource does not exist or lies outside the upload directory
		if ($strResource == '' || strncmp($strResource, $strUploadPath, \strlen($strUploadPath)) !== 0 || !file_exists($rootDir . '/' . $strResource))
		{
			throw new \InvalidArgumentException("Invalid resource $strResource");
		}

		$objModel = FilesModel::findByPath($strResource);

		// Return the model if it exists already
		if ($objModel !== null)
		{
			$objFile = ($objModel->type == 'folder') ? new Folder($objModel->path) : new File($objModel->path);

			// Update the timestamp and file hash (see #4818, #7828)
			if ($objModel->hash != $objFile->hash)
			{
				$objModel->tstamp = time();
				$objModel->hash   = $objFile->hash;
				$objModel->save();
			}

			return $objModel;
		}

		$arrPaths    = array();
		$arrChunks   = explode('/', $strResource);
		$strPath     = array_shift($arrChunks);
		$arrPids     = array($strPath => null);
		$arrUpdate   = array($strResource);
		$objDatabase = Database::getInstance();

		// Build the paths
		while (\count($arrChunks))
		{
			$strPath .= '/' . array_shift($arrChunks);
			$arrPaths[] = $strPath;
		}

		unset($arrChunks);

		$objModels = FilesModel::findMultipleByPaths($arrPaths);

		// Unset the entries in $arrPaths if the DB entry exists
		if ($objModels !== null)
		{
			while ($objModels->next())
			{
				if (($i = array_search($objModels->path, $arrPaths)) !== false)
				{
					unset($arrPaths[$i]);
					$arrPids[$objModels->path] = $objModels->uuid;
				}
			}
		}

		$arrPaths = array_values($arrPaths);

		// If the resource is a folder, also add its contents
		if (is_dir($rootDir . '/' . $strResource))
		{
			/** @var \SplFileInfo[] $objFiles */
			$objFiles = new \RecursiveIteratorIterator(
				new SyncExclude(
					new \RecursiveDirectoryIterator(
						$rootDir . '/' . $strResource,
						\FilesystemIterator::UNIX_PATHS|\FilesystemIterator::FOLLOW_SYMLINKS|\FilesystemIterator::SKIP_DOTS
					)
				), \RecursiveIteratorIterator::SELF_FIRST
			);

			// Add the relative path
			foreach ($objFiles as $objFile)
			{
				$strRelpath = StringUtil::stripRootDir($objFile->getPathname());

				if ($objFile->isDir())
				{
					$arrUpdate[] = $strRelpath;
				}

				$arrPaths[] = $strRelpath;
			}
		}

		$objReturn = null;

		// Create the new resources
		foreach ($arrPaths as $strPath)
		{
			if (\in_array(basename($strPath), array('.public', '.nosync')))
			{
				continue;
			}

			$strParent = \dirname($strPath);

			// The parent ID should be in $arrPids
			// Do not use isset() here, because the PID can be null
			if (\array_key_exists($strParent, $arrPids))
			{
				$strPid = $arrPids[$strParent];
			}
			else
			{
				throw new \Exception("No parent entry for $strParent");
			}

			// Create the file or folder
			if (is_file($rootDir . '/' . $strPath))
			{
				$objFile = new File($strPath);

				$objModel = new FilesModel();
				$objModel->pid       = $strPid;
				$objModel->tstamp    = time();
				$objModel->name      = $objFile->name;
				$objModel->type      = 'file';
				$objModel->path      = $objFile->path;
				$objModel->extension = $objFile->extension;
				$objModel->hash      = $objFile->hash;
				$objModel->uuid      = $objDatabase->getUuid();
				$objModel->save();

				$arrPids[$objFile->path] = $objModel->uuid;
			}
			else
			{
				$objFolder = new Folder($strPath);

				$objModel = new FilesModel();
				$objModel->pid       = $strPid;
				$objModel->tstamp    = time();
				$objModel->name      = $objFolder->name;
				$objModel->type      = 'folder';
				$objModel->path      = $objFolder->path;
				$objModel->extension = '';
				$objModel->uuid      = $objDatabase->getUuid();
				$objModel->save();

				$arrPids[$objFolder->path] = $objModel->uuid;
			}

			// Store the model to be returned (see #5979)
			if ($objModel->path == $strResource)
			{
				$objReturn = $objModel;
			}
		}

		// Update the folder hashes from bottom up after all file hashes are set
		foreach (array_reverse($arrPaths) as $strPath)
		{
			if (is_dir($rootDir . '/' . $strPath))
			{
				$objModel = FilesModel::findByPath($strPath);
				$objModel->hash = static::getFolderHash($strPath);
				$objModel->save();
			}
		}

		// Update the folder hashes
		if ($blnUpdateFolders)
		{
			static::updateFolderHashes($arrUpdate);
		}

		return $objReturn;
	}
public static function addResource($strResource, $blnUpdateFolders=true)
	{
		$strUploadPath = Config::get('uploadPath') . '/';
		$rootDir = System::getContainer()->getParameter('kernel.project_dir');

		// Remove trailing slashes (see #5707)
		if (substr($strResource, -1) == '/')
		{
			$strResource = substr($strResource, 0, -1);
		}

		// Normalize the path (see #6034)
		$strResource = str_replace(array('\\', '//'), '/', $strResource);

		// The resource does not exist or lies outside the upload directory
		if ($strResource == '' || strncmp($strResource, $strUploadPath, \strlen($strUploadPath)) !== 0 || !file_exists($rootDir . '/' . $strResource))
		{
			throw new \InvalidArgumentException("Invalid resource $strResource");
		}

		$objModel = FilesModel::findByPath($strResource);

		// Return the model if it exists already
		if ($objModel !== null)
		{
			$objFile = ($objModel->type == 'folder') ? new Folder($objModel->path) : new File($objModel->path);

			// Update the timestamp and file hash (see #4818, #7828)
			if ($objModel->hash != $objFile->hash)
			{
				$objModel->tstamp = time();
				$objModel->hash   = $objFile->hash;
				$objModel->save();
			}

			return $objModel;
		}

		$arrPaths    = array();
		$arrChunks   = explode('/', $strResource);
		$strPath     = array_shift($arrChunks);
		$arrPids     = array($strPath => null);
		$arrUpdate   = array($strResource);
		$objDatabase = Database::getInstance();

		// Build the paths
		while (\count($arrChunks))
		{
			$strPath .= '/' . array_shift($arrChunks);
			$arrPaths[] = $strPath;
		}

		unset($arrChunks);

		$objModels = FilesModel::findMultipleByPaths($arrPaths);

		// Unset the entries in $arrPaths if the DB entry exists
		if ($objModels !== null)
		{
			while ($objModels->next())
			{
				if (($i = array_search($objModels->path, $arrPaths)) !== false)
				{
					unset($arrPaths[$i]);
					$arrPids[$objModels->path] = $objModels->uuid;
				}
			}
		}

		$arrPaths = array_values($arrPaths);

		// If the resource is a folder, also add its contents
		if (is_dir($rootDir . '/' . $strResource))
		{
			/** @var \SplFileInfo[] $objFiles */
			$objFiles = new \RecursiveIteratorIterator(
				new SyncExclude(
					new \RecursiveDirectoryIterator(
						$rootDir . '/' . $strResource,
						\FilesystemIterator::UNIX_PATHS|\FilesystemIterator::FOLLOW_SYMLINKS|\FilesystemIterator::SKIP_DOTS
					)
				), \RecursiveIteratorIterator::SELF_FIRST
			);

			// Add the relative path
			foreach ($objFiles as $objFile)
			{
				$strRelpath = StringUtil::stripRootDir($objFile->getPathname());

				if ($objFile->isDir())
				{
					$arrUpdate[] = $strRelpath;
				}

				$arrPaths[] = $strRelpath;
			}
		}

		$objReturn = null;

		// Create the new resources
		foreach ($arrPaths as $strPath)
		{
			if (\in_array(basename($strPath), array('.public', '.nosync')))
			{
				continue;
			}

			$strParent = \dirname($strPath);

			// The parent ID should be in $arrPids
			// Do not use isset() here, because the PID can be null
			if (\array_key_exists($strParent, $arrPids))
			{
				$strPid = $arrPids[$strParent];
			}
			else
			{
				throw new \Exception("No parent entry for $strParent");
			}

			// Create the file or folder
			if (is_file($rootDir . '/' . $strPath))
			{
				$objFile = new File($strPath);

				$objModel = new FilesModel();
				$objModel->pid       = $strPid;
				$objModel->tstamp    = time();
				$objModel->name      = $objFile->name;
				$objModel->type      = 'file';
				$objModel->path      = $objFile->path;
				$objModel->extension = $objFile->extension;
				$objModel->hash      = $objFile->hash;
				$objModel->uuid      = $objDatabase->getUuid();
				$objModel->save();

				$arrPids[$objFile->path] = $objModel->uuid;
			}
			else
			{
				$objFolder = new Folder($strPath);

				$objModel = new FilesModel();
				$objModel->pid       = $strPid;
				$objModel->tstamp    = time();
				$objModel->name      = $objFolder->name;
				$objModel->type      = 'folder';
				$objModel->path      = $objFolder->path;
				$objModel->extension = '';
				$objModel->uuid      = $objDatabase->getUuid();
				$objModel->save();

				$arrPids[$objFolder->path] = $objModel->uuid;
			}

			// Store the model to be returned (see #5979)
			if ($objModel->path == $strResource)
			{
				$objReturn = $objModel;
			}
		}

		// Update the folder hashes from bottom up after all file hashes are set
		foreach (array_reverse($arrPaths) as $strPath)
		{
			if (is_dir($rootDir . '/' . $strPath))
			{
				$objModel = FilesModel::findByPath($strPath);
				$objModel->hash = static::getFolderHash($strPath);
				$objModel->save();
			}
		}

		// Update the folder hashes
		if ($blnUpdateFolders)
		{
			static::updateFolderHashes($arrUpdate);
		}

		return $objReturn;
	}
public static function addResource ( $ strResource , $ blnUpdateFolders = true ) { $ strUploadPath = Config :: get ( 'uploadPath' ) . '/' ; $ rootDir = System :: getContainer ( ) -> getParameter ( 'kernel.project_dir' ) ; // Remove trailing slashes (see #5707) if ( substr ( $ strResource , - 1 ) == '/' ) { $ strResource = substr ( $ strResource , 0 , - 1 ) ; } // Normalize the path (see #6034) $ strResource = str_replace ( array ( '\\' , '//' ) , '/' , $ strResource ) ; // The resource does not exist or lies outside the upload directory if ( $ strResource == '' || strncmp ( $ strResource , $ strUploadPath , \ strlen ( $ strUploadPath ) ) !== 0 || ! file_exists ( $ rootDir . '/' . $ strResource ) ) { throw new \ InvalidArgumentException ( "Invalid resource $strResource" ) ; } $ objModel = FilesModel :: findByPath ( $ strResource ) ; // Return the model if it exists already if ( $ objModel !== null ) { $ objFile = ( $ objModel -> type == 'folder' ) ? new Folder ( $ objModel -> path ) : new File ( $ objModel -> path ) ; // Update the timestamp and file hash (see #4818, #7828) if ( $ objModel -> hash != $ objFile -> hash ) { $ objModel -> tstamp = time ( ) ; $ objModel -> hash = $ objFile -> hash ; $ objModel -> save ( ) ; } return $ objModel ; } $ arrPaths = array ( ) ; $ arrChunks = explode ( '/' , $ strResource ) ; $ strPath = array_shift ( $ arrChunks ) ; $ arrPids = array ( $ strPath => null ) ; $ arrUpdate = array ( $ strResource ) ; $ objDatabase = Database :: getInstance ( ) ; // Build the paths while ( \ count ( $ arrChunks ) ) { $ strPath .= '/' . array_shift ( $ arrChunks ) ; $ arrPaths [ ] = $ strPath ; } unset ( $ arrChunks ) ; $ objModels = FilesModel :: findMultipleByPaths ( $ arrPaths ) ; // Unset the entries in $arrPaths if the DB entry exists if ( $ objModels !== null ) { while ( $ objModels -> next ( ) ) { if ( ( $ i = array_search ( $ objModels -> path , $ arrPaths ) ) !== false ) { unset ( $ arrPaths [ $ i ] ) ; $ arrPids [ $ objModels -> path ] = $ objModels -> uuid ; } } } $ arrPaths = array_values ( $ arrPaths ) ; // If the resource is a folder, also add its contents if ( is_dir ( $ rootDir . '/' . $ strResource ) ) { /** @var \SplFileInfo[] $objFiles */ $ objFiles = new \ RecursiveIteratorIterator ( new SyncExclude ( new \ RecursiveDirectoryIterator ( $ rootDir . '/' . $ strResource , \ FilesystemIterator :: UNIX_PATHS | \ FilesystemIterator :: FOLLOW_SYMLINKS | \ FilesystemIterator :: SKIP_DOTS ) ) , \ RecursiveIteratorIterator :: SELF_FIRST ) ; // Add the relative path foreach ( $ objFiles as $ objFile ) { $ strRelpath = StringUtil :: stripRootDir ( $ objFile -> getPathname ( ) ) ; if ( $ objFile -> isDir ( ) ) { $ arrUpdate [ ] = $ strRelpath ; } $ arrPaths [ ] = $ strRelpath ; } } $ objReturn = null ; // Create the new resources foreach ( $ arrPaths as $ strPath ) { if ( \ in_array ( basename ( $ strPath ) , array ( '.public' , '.nosync' ) ) ) { continue ; } $ strParent = \ dirname ( $ strPath ) ; // The parent ID should be in $arrPids // Do not use isset() here, because the PID can be null if ( \ array_key_exists ( $ strParent , $ arrPids ) ) { $ strPid = $ arrPids [ $ strParent ] ; } else { throw new \ Exception ( "No parent entry for $strParent" ) ; } // Create the file or folder if ( is_file ( $ rootDir . '/' . $ strPath ) ) { $ objFile = new File ( $ strPath ) ; $ objModel = new FilesModel ( ) ; $ objModel -> pid = $ strPid ; $ objModel -> tstamp = time ( ) ; $ objModel -> name = $ objFile -> name ; $ objModel -> type = 'file' ; $ objModel -> path = $ objFile -> path ; $ objModel -> extension = $ objFile -> extension ; $ objModel -> hash = $ objFile -> hash ; $ objModel -> uuid = $ objDatabase -> getUuid ( ) ; $ objModel -> save ( ) ; $ arrPids [ $ objFile -> path ] = $ objModel -> uuid ; } else { $ objFolder = new Folder ( $ strPath ) ; $ objModel = new FilesModel ( ) ; $ objModel -> pid = $ strPid ; $ objModel -> tstamp = time ( ) ; $ objModel -> name = $ objFolder -> name ; $ objModel -> type = 'folder' ; $ objModel -> path = $ objFolder -> path ; $ objModel -> extension = '' ; $ objModel -> uuid = $ objDatabase -> getUuid ( ) ; $ objModel -> save ( ) ; $ arrPids [ $ objFolder -> path ] = $ objModel -> uuid ; } // Store the model to be returned (see #5979) if ( $ objModel -> path == $ strResource ) { $ objReturn = $ objModel ; } } // Update the folder hashes from bottom up after all file hashes are set foreach ( array_reverse ( $ arrPaths ) as $ strPath ) { if ( is_dir ( $ rootDir . '/' . $ strPath ) ) { $ objModel = FilesModel :: findByPath ( $ strPath ) ; $ objModel -> hash = static :: getFolderHash ( $ strPath ) ; $ objModel -> save ( ) ; } } // Update the folder hashes if ( $ blnUpdateFolders ) { static :: updateFolderHashes ( $ arrUpdate ) ; } return $ objReturn ; }
Adds a file or folder with its parent folders

@param string  $strResource      The path to the file or folder
@param boolean $blnUpdateFolders If true, the parent folders will be updated

@return FilesModel The files model

@throws \Exception                If a parent ID entry is missing
@throws \InvalidArgumentException If the resource is outside the upload folder
Adds a file or folder with its parent folders