Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Php Spo Laravel Package

vgrem/php-spo

REST/OData client library for Microsoft 365 in PHP. Access SharePoint Online/On-Prem (2013-2019), OneDrive for Business, Teams, and Outlook APIs with supported auth flows (client credentials, certificates, etc.). Install via Composer.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require vgrem/php-spo
    

    Ensure vendor/autoload.php is included in your Laravel app (handled automatically by Laravel’s autoloader).

  2. Authentication: Register an app in Azure AD and obtain:

    • Client ID (Application ID)
    • Client Secret (or use certificate auth)
    • Tenant ID Configure credentials in .env:
    SPO_CLIENT_ID=your_client_id
    SPO_CLIENT_SECRET=your_client_secret
    SPO_TENANT_ID=your_tenant_id
    
  3. First Use Case: Fetch a SharePoint site’s lists:

    use Vgrem\PhpSpo\Client;
    use Vgrem\PhpSpo\Authentication\ClientCredential;
    
    $auth = new ClientCredential(
        env('SPO_CLIENT_ID'),
        env('SPO_CLIENT_SECRET'),
        env('SPO_TENANT_ID')
    );
    
    $client = new Client($auth);
    $site = $client->getSite('https://yourdomain.sharepoint.com/sites/yoursite');
    $lists = $site->getLists();
    

Key Entry Points

  • Client: Main entry point for all API operations.
  • Authentication: Supports ClientCredential, OAuth2, and Certificate flows.
  • Resources: Site, List, Drive, User, etc., for granular operations.

Implementation Patterns

Common Workflows

1. SharePoint CRUD Operations

  • Fetch a List:

    $list = $site->getList('Documents');
    $items = $list->getItems(['$select' => 'Title,Id']);
    
  • Create/Update/Delete Items:

    $item = $list->createItem(['Title' => 'New File', 'FileLeafRef' => 'file.txt']);
    $list->updateItem($item->getId(), ['Title' => 'Updated File']);
    $list->deleteItem($item->getId());
    
  • File Operations:

    $file = $list->getFile('file.txt');
    $content = $file->getContent(); // Download
    $file->updateContent(file_get_contents('local-path.txt')); // Upload
    

2. Teams API Integration

  • List Teams:
    $teams = $client->getTeams();
    foreach ($teams as $team) {
        $channels = $team->getChannels();
    }
    
  • Send Messages:
    $channel = $team->getChannel('general');
    $channel->sendMessage('Hello from PHP!');
    

3. Outlook API (Emails)

  • Fetch Emails:
    $emails = $client->getOutlook()->getMessages();
    foreach ($emails as $email) {
        $email->getBody();
    }
    
  • Send Email:
    $email = $client->getOutlook()->createMessage();
    $email->setSubject('Test')
          ->setBody('Hello!')
          ->setTo(['user@example.com'])
          ->send();
    

4. OneDrive Integration

  • Upload/Download Files:
    $drive = $client->getOneDrive();
    $file = $drive->uploadFile('local-file.txt', 'remote-file.txt');
    $content = $drive->downloadFile('remote-file.txt');
    

Laravel-Specific Patterns

  1. Service Providers: Bind the client to Laravel’s container in AppServiceProvider:

    public function register()
    {
        $this->app->singleton(Client::class, function ($app) {
            $auth = new ClientCredential(
                env('SPO_CLIENT_ID'),
                env('SPO_CLIENT_SECRET'),
                env('SPO_TENANT_ID')
            );
            return new Client($auth);
        });
    }
    
  2. Facade (Optional): Create a facade for cleaner syntax:

    // app/Facades/SPO.php
    namespace App\Facades;
    use Illuminate\Support\Facades\Facade;
    class SPO extends Facade { protected static function getFacadeAccessor() { return 'spo.client'; } }
    

    Update config/app.php to bind the facade.

  3. Jobs/Queues: Offload long-running operations (e.g., bulk file uploads) to queues:

    use Vgrem\PhpSpo\Client;
    class UploadFilesJob implements ShouldQueue
    {
        protected $client;
        public function __construct(Client $client) { $this->client = $client; }
        public function handle() {
            $this->client->getSite('...')->uploadFiles(...);
        }
    }
    
  4. Events/Listeners: Trigger events for SharePoint/Teams actions (e.g., FileUploaded, TeamMessageSent):

    event(new FileUploaded($file));
    

Gotchas and Tips

Pitfalls

  1. Authentication Timeouts:

    • Issue: ClientCredential tokens expire after 1 hour. Subsequent requests fail with 401 Unauthorized.
    • Fix: Implement token refresh logic or use OAuth2 with longer-lived tokens.
      if ($auth->isTokenExpired()) {
          $auth->refreshToken();
      }
      
  2. Throttling:

    • Issue: Microsoft throttles requests (~10-20 calls/second). Bulk operations may fail.
    • Fix: Add delays between requests or use batch processing:
      sleep(1); // Simple delay
      // OR
      $client->setRateLimit(10); // Hypothetical method (check docs)
      
  3. OData Query Complexity:

    • Issue: Overly complex $expand or $filter queries may fail silently.
    • Fix: Test queries in Microsoft Graph Explorer first.
  4. Permissions:

    • Issue: Missing API permissions (e.g., Files.ReadWrite) cause 403 Forbidden.
    • Fix: Register required permissions in Azure AD:
      https://graph.microsoft.com/.default (for delegated)
      api://<client-id>/Files.ReadWrite (for app-only)
      
  5. Large File Handling:

    • Issue: Uploading/downloading files > 4MB may fail or timeout.
    • Fix: Use chunked uploads/downloads:
      $file->uploadContent($chunkedContent, ['chunkSize' => 1024 * 1024]); // 1MB chunks
      

Debugging Tips

  1. Enable Logging:

    $client->setLogger(new \Monolog\Logger('spo', [new \Monolog\Handler\StreamHandler(storage_path('logs/spo.log'))]));
    
  2. HTTP Debugging:

    • Use Guzzle middleware to inspect requests:
      $client->getHttpClient()->getEmitter()->attach(
          new \GuzzleHttp\Middleware::tap(function ($request) {
              \Log::debug('SPO Request:', ['url' => (string) $request->getUri()]);
          })
      );
      
  3. Common Errors:

    • InvalidAuthenticationToken: Check Client ID/Secret/Tenant ID.
    • ResourceNotFound: Verify SharePoint site URL format (https://domain.sharepoint.com/sites/site).
    • InvalidQuery: Validate OData syntax (use OData Validator).

Extension Points

  1. Custom Resources: Extend the library for unsupported endpoints:

    class CustomResource extends \Vgrem\PhpSpo\Resource
    {
        protected $endpoint = 'https://graph.microsoft.com/v1.0/sites/{site-id}/custom';
        public function getItems() { return $this->get('/items'); }
    }
    
  2. Middleware: Add request/response middleware:

    $client->getHttpClient()->getEmitter()->attach(
        new \GuzzleHttp\Middleware::mapRequest(function ($request) {
            $request->getHeaders()->add('X-Custom-Header', 'value');
            return $request;
        })
    );
    
  3. Caching: Cache responses (e.g., lists, users) to reduce API calls:

    $lists = Cache::remember('spo.lists', 300, function () use ($site) {
        return $site->getLists();
    });
    
  4. Testing: Use mocks for unit tests:

    $mockClient = Mockery::mock(Client::class);
    $mockClient->shouldReceive('getSite')->andReturn($mockSite);
    

Configuration Quirks

  1. Base URL: The library defaults to https://graph.microsoft.com.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky
spatie/mailcoach-vapor