Download the PHP package sahablibya/laravel-sharepoint-filesystem without Composer

On this page you can find all versions of the php package sahablibya/laravel-sharepoint-filesystem. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package laravel-sharepoint-filesystem

Laravel SharePoint/OneDrive Filesystem Driver

Latest Version on Packagist Total Downloads License

A Laravel filesystem driver for SharePoint and OneDrive using Microsoft Graph API. It supports client credentials for unattended SharePoint and OneDrive for Business access, plus device-code sign-in for personal and business OneDrive accounts.

✨ Features

📋 Requirements

📦 Installation

Install via Composer:

The service provider will be automatically registered via Laravel's package discovery.

⚙️ Configuration

Step 1: Azure App Registration

  1. Go to Azure Portal
  2. Navigate to Azure Active Directory → App registrations
  3. Click New registration
  4. Enter a name (e.g., "Laravel SharePoint Integration")
  5. Click Register
  6. Note your Application (client) ID and Directory (tenant) ID

Step 2: Create Client Secret

  1. In your app registration, go to Certificates & secrets
  2. Click New client secret
  3. Add a description and set expiration
  4. Click Add
  5. ⚠️ Copy the secret value immediately (you won't see it again!)

Step 3: Grant API Permissions

  1. Go to API permissions
  2. Click Add a permission → Microsoft Graph → Application permissions
  3. Choose the permission model that matches your deployment:
    • For folder-scoped access, add Files.SelectedOperations.Selected
    • For broad access, Files.ReadWrite.All or Sites.ReadWrite.All can be used
  4. Click Grant admin consent (requires admin privileges)
  5. If using Files.SelectedOperations.Selected, explicitly assign the application the write role on the target driveItem

See Folder-scoped application permissions for the complete selected-permissions setup.

Step 4: Get SharePoint Drive ID and Optional Folder Item ID

To use a specific SharePoint document library, you need the drive ID:

Using Microsoft Graph Explorer

  1. Go to Graph Explorer
  2. Sign in with your account
  3. Find your site: GET https://graph.microsoft.com/v1.0/sites?search=YourSiteName
  4. Get drives for that site: GET https://graph.microsoft.com/v1.0/sites/{site-id}/drives
  5. Copy the id of your desired document library

To mount one folder instead of the whole drive, also retrieve that folder's Microsoft Graph driveItem id. Configure this value as root_item_id; in this package's configuration it is the Parent Folder Item ID returned by Microsoft Graph.

For example, resolve a folder by path and copy the id from the response:

Step 5: Environment Configuration

Add these variables to your .env file:

Step 6: Register Filesystem Disk

Add the SharePoint disk to your config/filesystems.php:

Personal OneDrive

Personal OneDrive uses delegated device-code authentication. The Microsoft account owner signs in once, and the package stores the resulting refresh token encrypted with Laravel's APP_KEY.

Register a Public Client

  1. Create a Microsoft Entra app registration.
  2. Select an account type that includes personal Microsoft accounts.
  3. Under Authentication → Advanced settings, enable Allow public client flows.
  4. Add the Microsoft Graph delegated permission Files.ReadWrite.
  5. Copy the Application (client) ID.

A client secret, tenant ID, and drive ID are not required for this mode. Microsoft still requires a public client ID to identify the application; the system owner can configure that value once for all users of the system.

Configure the Disk

Add the disk to config/filesystems.php:

Connect the account once:

The command displays a Microsoft URL and code. After sign-in, scheduled backups can refresh their access token without user interaction. Tokens are encrypted under storage/app/onedrive-tokens by default. Set a unique token_key for each OneDrive account when configuring multiple disks.

Mount a Folder as the Disk Root

Set root_item_id to a folder's Microsoft Graph driveItem ID to mount that folder as the virtual root of the Flysystem disk:

root_item_id is a folder's Microsoft Graph driveItem id, sometimes called the Parent Folder Item ID. It is not the folder's name, a sharing URL, or a browser URL. Retrieve the folder through Graph and use its id from the response. Logical disk paths are resolved below that item. A configured prefix is then applied inside the item root; it is not a physical path above the item.

For example:

uses:

This is Microsoft Graph's upload by parent item ID request form.

With delegated authentication and no drive_id, the equivalent path starts with /me/drive/items/{rootItemId}. If root_item_id is omitted, the package retains its existing /drives/{driveId}/root or /me/drive/root routing.

An empty logical path addresses the mounted item itself (or the configured prefix beneath it). For safety, the adapter refuses to delete or move a configured item root through an empty logical path.

Destination path construction

For Spatie Laravel Backup, the remote destination is:

Empty components are omitted. The filename is the Spatie filename prefix followed by its timestamp and .zip, unless you explicitly customize the filename.

Setting Meaning Example
Disk name The key under filesystems.disks; used by Storage::disk() and Spatie's destination disks. It does not create a remote folder. onedrive
driver The registered adapter; sharepoint and onedrive are aliases for the same implementation. Authentication is chosen by auth_mode. sharepoint
drive_id Selects the Graph drive. App-only access needs it; delegated access can use the signed-in user's drive. Graph drive ID
root_item_id Mounts an existing Graph folder by ID. Omit it to use the drive root. Graph folder ID
Disk prefix A relative folder path inside the mounted root, applied once to every disk operation. '' or schools/daily
Spatie backup.name The backup folder relative to the disk; accessed as config('backup.backup.name'). imamMalik_schools_system_backup
Spatie backup.destination.filename_prefix Text prepended to the ZIP basename, not a folder. Keep it free of path separators. imamMalik_schools_system_backup_

For a mounted folder displayed in OneDrive as Shared Backups:

Do not repeat the mounted folder's name in prefix, or repeat backup.name in prefix unless you want two nested folders with that name. Pass ordinary, unencoded relative paths; the adapter encodes each Graph path segment, including spaces, %, #, Unicode, and Arabic names. Encoding does not override Microsoft's filename restrictions.

The SHAREPOINT_* and ONEDRIVE_* environment names only matter where your disk configuration reads them. An onedrive disk can read SHAREPOINT_PREFIX; renaming the disk does not change that mapping. See the complete backup recipe.

Folder-scoped application permissions

root_item_id changes Microsoft Graph routing only; it does not grant the application access to the folder.

For app-only folder-scoped access with client credentials, the Microsoft Entra application needs all of the following:

  1. Microsoft Graph Files.SelectedOperations.Selected as an Application permission.
  2. Administrator consent for that application permission.
  3. An explicit write permission assignment for the application on the target driveItem.

Create the resource assignment using an appropriately authorized administrator process:

Selected permissions grant no access until the resource assignment is created. See Microsoft's Selected permissions overview and create permission on a driveItem documentation.

A signed-in user's personal permission on the folder does not transfer to a client-credentials token, because app-only access is evaluated for the application rather than a user. Broader application permissions such as Files.ReadWrite.All or Sites.ReadWrite.All can also work, but they are unnecessary when folder-scoped selected permissions and the explicit driveItem assignment are configured correctly.

🚀 Usage

Basic Operations

Directory Operations

File Metadata

URLs & Downloads

🔄 Using with Spatie Laravel Backup

Follow the complete installation and backup recipe for credentials, disk registration, configuration refresh, commands, and the resulting path. The relevant structure in the published config/backup.php is:

Merge these settings into the published configuration; this excerpt is not a replacement for the whole file. destination belongs inside backup; monitor_backups is a top-level sibling of backup. Laravel's full lookup keys are backup.backup.name, backup.backup.destination.disks, backup.backup.destination.filename_prefix, and backup.monitor_backups.

With SHAREPOINT_PREFIX="" mapped to the disk's prefix, the example produces this path beneath the mounted root:

The timestamp illustrates Spatie's default naming at that application-local time. See multiple applications sharing one root for separate project folders and monitoring.

Spatie's destination writer uploads the local archive through Flysystem writeStream(). Its “Copying zip” console message does not mean it invoked this adapter's Graph copy() operation.

🔧 Advanced Configuration

Multiple SharePoint Sites

Using OneDrive

For application-only OneDrive for Business access, use the existing client credentials mode and provide the user's drive ID:

Token Caching

Client-credentials access tokens are cached for 58 minutes. Device-code connections store an encrypted refresh token and request a new access token when the current token is close to expiry.

Copy Monitoring

Microsoft Graph copy operations run asynchronously. This package waits for Graph's copy monitor to report completion before copy() returns. Because move() uses copy followed by delete, the source file is only deleted after the copy is confirmed complete.

You can tune the monitor wait behavior per disk:

🐛 Troubleshooting

Missing or misplaced backups

  1. Confirm the terminal, cron entry, or scheduler runs from the intended Laravel project directory. Run pwd and check the path to artisan; two applications can have identically named disks but different resolved configuration.
  2. Inspect the resolved values below, not just .env. config/backup.php must have destination inside backup, and the monitoring name must match backup.name exactly. Check --only-to-disk or a custom Spatie --config argument if your job uses one.
  3. Refresh configuration in that project: use php artisan config:clear during local setup, or php artisan config:cache to rebuild a deployment's cached configuration. Open a new console session and restart long-running workers that hold the old disk instance. cache:clear is not a substitute for refreshing configuration. Laravel does not load .env when configuration is cached; read env() in configuration files, then use config() in application code. See Laravel configuration caching.
  4. Reconstruct mounted root / prefix / backup name / filename. Check for a repeated backup name in prefix, an unexpected APP_NAME fallback, or an environment variable that the disk does not actually read. Changing configuration leaves existing archives at their old paths.
  5. Check the backup command's exit status and the failing operation. An empty backup:list result or a folder visible in OneDrive does not prove that the ZIP uploaded successfully.

For a credential-free configuration summary, start php artisan tinker in the intended application (if Laravel Tinker is installed) and paste this whole expression. It prints only the listed fields, without resolving the disk or requesting a token:

Do not dump the complete filesystem configuration, .env, disk object, or token store. Those can contain client secrets or tokens. Review folder and drive identifiers before sharing the allowlisted summary publicly.

Visible exceptions during setup

Set 'throw' => true on the disk in config/filesystems.php, then refresh configuration. Laravel's filesystem wrapper will rethrow supported failures such as UnableToWriteFile, UnableToCreateDirectory, UnableToCopyFile, and UnableToMoveFile, instead of returning false. If you choose throw => false, check those return values explicitly. This setting does not enable application debug mode or change permissions. See Laravel failed writes.

There is a package limitation in v1.4.0 and the current adapter: fileExists() and directoryExists() catch errors and return false; listContents() can stop silently on an HTTP error or exception, returning an empty or partial listing. throw => true cannot restore an exception the adapter already swallowed. A missing-looking file or empty listing is therefore inconclusive. Use a read of a known existing harmless file to check reading, and the explicit console write test below to check uploading.

Identify the failing operation

Stage What to investigate
Authentication Disk resolution obtains or refreshes a token. Check authentication mode, app registration, secret expiry for client credentials, or the delegated connection. Do not print tokens.
Listing / metadata Check the drive, mounted folder ID, prefix, and access to that location. A successful listing only demonstrates listing access; empty results can hide errors as described above.
Directory creation makeDirectory() posts a new child under an existing parent. It does not recursively create parents and requests Graph conflict behavior rename. Folder creation success does not demonstrate file upload success.
Upload put() / writeStream() use Graph PUT ...:/content. Check the full destination, existing parent folders, archive size, HTTP status, and Graph error. A successful listing or directory creation does not prove uploading works.
Server-side copy copy() first resolves destination-parent metadata, posts ...:/copy, then polls a monitor URL. Capture which stage failed and the previous exception. A successful upload or read does not test this operation.
Move This adapter calls copy() and only then deletes the source. A failed copy leaves the source in place; a timeout can leave an unconfirmed destination, so inspect before retrying.

Spatie uploads its local ZIP through writeStream() even when its console output calls the step “copying”. Diagnose an upload exception separately from an explicit Storage::disk(...)->copy() failure.

Copy failure investigation

During integration of v1.4.0, OneDrive folder creation, upload, read, and delete succeeded, while copy() raised UnableToCopyFile. Transferring the same file with read/write succeeded, and its contents were verified before deleting the source. The underlying Graph response was not captured, so the cause of that copy failure remains unknown. These observations do not establish a permission limitation for OneDrive or selected permissions.

Inspection of its tests shows:

A separate, reproducible limitation is that a copy-monitor 429 response fails immediately: the adapter does not respect Retry-After or retry that request. A throttling guidance calls for waiting before retrying. This is not evidence that the integration incident was throttling-related.

Proposed runtime follow-up, not implemented here: add bounded retries for monitor GET requests on 429, respecting Retry-After within the copy-monitor deadline, with tests for eventual completion, exhaustion, and source preservation. Review selected transient 5xx handling separately; do not blindly repeat an accepted copy POST. This documentation update does not change runtime behavior.

For a future reproduction, record the operation stage, HTTP status, Graph error code and message, request ID/date if available, package/Laravel versions, and redacted source/destination paths. Remove authorization headers, tokens, secrets, and signed monitor/download URLs before sharing. Do not broaden permissions based only on UnableToCopyFile.

A manual read/write transfer is a separate operation, not an automatic package fallback. If deliberately used, choose a fresh destination, preserve the source until a complete read-back comparison or checksum succeeds, and handle upload/verification failures without deleting the source. It does not promise to preserve Graph versions or metadata. The current readStream() also buffers the full file, so it is not a constant-memory workaround for large backups.

Permission Errors

Error: "Access denied" or "403 Forbidden"

Solutions:

  1. Verify the configured permission model: Files.SelectedOperations.Selected, Files.ReadWrite.All, or Sites.ReadWrite.All
  2. Ensure admin consent is granted (look for green checkmarks in Azure Portal)
  3. For selected permissions, verify the application has an explicit write assignment on the target driveItem
  4. Verify SHAREPOINT_ROOT_ITEM_ID or ONEDRIVE_ROOT_ITEM_ID is the target folder's driveItem ID
  5. Capture the failed operation and Graph error before changing permissions; folder selection and authentication mode must agree with your setup

Authentication Errors

Error: "Failed to obtain access token" or "invalid_client"

Solutions:

  1. Verify GRAPH_CLIENT_ID matches your app registration's Application ID
  2. Verify GRAPH_CLIENT_SECRET is correct (they expire!)
  3. Check GRAPH_TENANT_ID matches your Directory (tenant) ID
  4. Ensure no extra spaces in your .env file

For a device-code disk, run php artisan onedrive:connect {disk} again if Microsoft access was revoked, the refresh token expired, or Laravel's APP_KEY changed.

Drive Not Found

Error: "itemNotFound" or "Resource not found"

Solutions:

  1. Verify SHAREPOINT_DRIVE_ID is correct
  2. For application-only OneDrive, verify ONEDRIVE_DRIVE_ID is configured
  3. Omit drive_id only when using device-code authentication, which uses /me/drive
  4. Ensure the app has access to the specified drive
  5. Check the drive exists and hasn't been deleted

Timeout Issues

Error: Timeouts when uploading large files

Solutions:

Clear Token Cache

Client-credentials tokens use a hashed sharepoint_access_token_... cache key and a 3,500-second cache lifetime. Laravel's cache:forget accepts an exact key, not a wildcard: sharepoint_access_token_* will not clear all matching tokens. A broad php artisan cache:clear affects the application's default cache, including unrelated entries; it is not needed merely because a backup path changed. Delegated tokens are stored separately in encrypted files, so clearing the application cache does not reconnect a device-code account.

Testing connection from the console

Run this only when you intend to create and delete a temporary remote file. From the intended application directory, start php artisan tinker (requires Laravel Tinker), then paste the whole expression below. Use your actual disk name. The closure avoids displaying the disk object or configuration in Tinker's output.

The file is placed directly below the disk prefix, if any; this does not create the Spatie backup-name folder. Ensure the configured prefix already exists. To verify the exact backup folder, prepend its confirmed existing name to $path.

Generate a new random filename for every run; never substitute an existing backup filename. The collision check is an extra guard, not an atomic create-only guarantee: this adapter's existence checks can hide errors and its writes replace existing content. The unpredictable 128-bit suffix avoids reusing a shared test name. If interrupted or cleanup is not confirmed, inspect that exact printed temporary path before removing it. This check verifies upload, read-back contents, and deletion separately; it does not test Graph copy() or a full backup job.

Proposed diagnostic command

sharepoint:check --disk=onedrive is a future proposal, not a command shipped by this package. A useful design would show an allowlisted resolved path and separate authentication/listing results by default, require an explicit --write-test to create a unique temporary file, verify its contents, and report cleanup independently. It should never dump secrets or start database exports. Use the console example above until such a command is separately implemented.

🔐 Security Best Practices

  1. Never commit credentials - Keep .env in .gitignore
  2. Use environment-specific apps - Separate Azure apps for dev/staging/production
  3. Rotate secrets regularly - Set expiration dates on client secrets in Azure
  4. Monitor access logs - Review app activity in Azure Portal regularly
  5. Principle of least privilege - Only grant necessary permissions
  6. Secure your .env - Restrict file permissions: chmod 600 .env
  7. Protect APP_KEY - Delegated refresh tokens are encrypted with the Laravel application key

📚 API Reference

Supported Flysystem Operations

Method Supported Notes
write() ✅ Write file contents
writeStream() ✅ Write from stream (memory efficient)
read() ✅ Read file contents
readStream() ✅ Read as stream
delete() ✅ Delete file
deleteDirectory() ✅ Delete directory and contents
createDirectory() ✅ Create directory
fileExists() ✅ Check if file exists
directoryExists() ✅ Check if directory exists
listContents() ✅ List directory contents with Graph pagination
move() ✅ Move/rename file after monitored copy completion
copy() ✅ Copy file with Graph monitor polling
lastModified() ✅ Get last modified timestamp
fileSize() ✅ Get file size
mimeType() ✅ Get MIME type
visibility() ❌ Not supported by SharePoint/OneDrive
setVisibility() ❌ Not supported by SharePoint/OneDrive

🤝 Contributing

Contributions are welcome! Please see CONTRIBUTING.md for details.

Development Setup

📝 Changelog

Please see CHANGELOG.md for recent changes.

📄 License

This package is open-sourced software licensed under the MIT license.

💡 Credits

🙏 Acknowledgments

Special thanks to:

📞 Support


Made with ❤️ by SahabLibya Development Team


All versions of laravel-sharepoint-filesystem with dependencies

PHP Build Version
Package Version
Requires php Version ^8.1|^8.2|^8.3|^8.4|^8.5
guzzlehttp/guzzle Version ^7.0
guzzlehttp/psr7 Version ^2.0
illuminate/console Version ^10.0|^11.0|^12.0|^13.0
illuminate/encryption Version ^10.0|^11.0|^12.0|^13.0
illuminate/filesystem Version ^10.0|^11.0|^12.0|^13.0
illuminate/http Version ^10.0|^11.0|^12.0|^13.0
illuminate/support Version ^10.0|^11.0|^12.0|^13.0
league/flysystem Version ^3.0
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package sahablibya/laravel-sharepoint-filesystem contains the following files

Loading the files please wait ...