jjuanrivvera / canvas-lms-kit-laravel
Laravel integration for Canvas LMS Kit - Auto-configuration, multi-tenancy, and testing utilities
Requires
- php: ^8.1
- illuminate/config: ^9.0|^10.0|^11.0|^12.0
- illuminate/console: ^9.0|^10.0|^11.0|^12.0
- illuminate/support: ^9.0|^10.0|^11.0|^12.0
- jjuanrivvera/canvas-lms-kit: ^1.5
Requires (Dev)
- laravel/pint: ^1.0
- orchestra/testbench: ^7.0|^8.0|^9.0|^10.0
- pestphp/pest: ^2.0
- pestphp/pest-plugin-arch: ^2.0
- pestphp/pest-plugin-laravel: ^2.0
- pestphp/pest-plugin-mock: ^2.0
- phpstan/phpstan: ^1.10
- phpstan/phpstan-strict-rules: ^1.5
- symfony/var-dumper: ^6.0|^7.0
This package is not auto-updated.
Last update: 2025-09-09 19:14:49 UTC
README
A minimal Laravel integration package for the Canvas LMS Kit. Auto-configure Canvas API access, manage multiple connections, and test with ease.
โจ Features
- ๐ Zero Configuration - Works immediately after installation
- ๐ Multi-Tenant Support - Easily switch between Canvas instances
- ๐งช Testing Utilities - Mock Canvas API calls in your tests
- ๐ฆ Minimal & Focused - Just 500 lines of code that do exactly what you need
- ๐ง Laravel Native - Uses Laravel's config, logging, and testing systems
๐ฆ Installation
composer require jjuanrivvera/canvas-lms-kit-laravel
โก Quick Start
1. Publish Configuration
php artisan vendor:publish --tag=canvas-config
2. Add Credentials to .env
CANVAS_API_KEY=your-api-key-here CANVAS_BASE_URL=https://your-institution.instructure.com CANVAS_ACCOUNT_ID=1
3. Test Your Connection
php artisan canvas:test
4. Start Using!
use CanvasLMS\Api\Courses\Course; use CanvasLMS\Api\Users\User; // That's it! The package auto-configures everything $courses = Course::get(); $user = User::find(123);
๐ฏ Why This Package?
The Problem
Without this package, you need to manually configure Canvas LMS Kit in every controller, job, or service:
// ๐ซ Before - Manual configuration everywhere class CourseController { public function __construct() { Config::setApiKey(env('CANVAS_API_KEY')); Config::setBaseUrl(env('CANVAS_BASE_URL')); Config::setAccountId(env('CANVAS_ACCOUNT_ID')); // ... more configuration } }
The Solution
This package auto-configures everything from your Laravel config:
// ๐ After - Just works! class CourseController { public function index() { return Course::get(); // Already configured! } }
๐ Usage
Basic Usage
The package automatically configures the Canvas LMS Kit when your application boots. You can immediately use all Canvas API classes:
use CanvasLMS\Api\Courses\Course; use CanvasLMS\Api\Enrollments\Enrollment; use CanvasLMS\Api\Assignments\Assignment; // Get all courses $courses = Course::get(); // Get a specific course $course = Course::find(123); // Create a course $course = Course::create([ 'name' => 'Introduction to Laravel', 'course_code' => 'LAR101', ]); // Update a course $course->name = 'Advanced Laravel'; $course->save();
Multi-Tenant Support
Perfect for SaaS applications managing multiple Canvas instances:
use CanvasLMS\Laravel\Facades\Canvas; // Switch to a different Canvas instance Canvas::connection('school_b'); $courses = Course::get(); // From school_b // Temporarily use a different connection Canvas::usingConnection('school_c', function () { $course = Course::find(456); // From school_c }); // Back to default connection Canvas::connection('main');
Configure multiple connections in config/canvas.php
:
'connections' => [ 'main' => [ 'api_key' => env('CANVAS_API_KEY'), 'base_url' => env('CANVAS_BASE_URL'), ], 'school_b' => [ 'api_key' => env('SCHOOL_B_API_KEY'), 'base_url' => env('SCHOOL_B_BASE_URL'), ], ],
Testing
Mock Canvas API calls in your tests:
use CanvasLMS\Laravel\Testing\CanvasFake; use CanvasLMS\Api\Courses\Course; test('creates a course in canvas', function () { // Arrange $fake = new CanvasFake(); $fake->fake([ 'courses' => [ ['id' => 123, 'name' => 'Test Course'], ], ]); // Act $courses = Course::get(); // Assert expect($courses)->toHaveCount(1); expect($courses[0]->name)->toBe('Test Course'); $fake->assertApiCallMade('GET', '/courses'); });
Facade Usage (Optional)
If you prefer facades, you can use the Canvas facade:
use CanvasLMS\Laravel\Facades\Canvas; // These are equivalent: Course::get(); // Direct SDK usage Canvas::courses()::get(); // Via facade // The facade is most useful for connection management: Canvas::connection('tenant_2')->courses()::get();
๐ง Configuration
The configuration file (config/canvas.php
) provides extensive customization options:
return [ // Default connection to use 'default' => env('CANVAS_CONNECTION', 'main'), // Multiple Canvas connections 'connections' => [ 'main' => [ // Authentication mode: 'api_key' or 'oauth' 'auth_mode' => env('CANVAS_AUTH_MODE', 'api_key'), // API Key authentication (when auth_mode = 'api_key') 'api_key' => env('CANVAS_API_KEY'), 'base_url' => env('CANVAS_BASE_URL'), 'account_id' => env('CANVAS_ACCOUNT_ID', 1), 'timeout' => env('CANVAS_TIMEOUT', 30), 'log_channel' => env('CANVAS_LOG_CHANNEL'), // OAuth 2.0 authentication (when auth_mode = 'oauth') 'oauth_client_id' => env('CANVAS_OAUTH_CLIENT_ID'), 'oauth_client_secret' => env('CANVAS_OAUTH_CLIENT_SECRET'), 'oauth_redirect_uri' => env('CANVAS_OAUTH_REDIRECT_URI'), 'oauth_token' => env('CANVAS_OAUTH_TOKEN'), 'oauth_refresh_token' => env('CANVAS_OAUTH_REFRESH_TOKEN'), // Optional middleware configuration 'middleware' => [ 'retry' => [ 'max_attempts' => 3, 'delay' => 1000, ], 'rate_limit' => [ 'wait_on_limit' => true, ], ], ], ], // Testing configuration 'testing' => [ 'fake' => env('CANVAS_FAKE', false), ], ];
๐ Authentication Methods
API Key Authentication (Default)
The simplest authentication method using Canvas API tokens:
CANVAS_AUTH_MODE=api_key # or omit - api_key is default CANVAS_API_KEY=your-canvas-api-token
OAuth 2.0 Authentication
For OAuth-based authentication, switch the auth mode and configure OAuth settings:
CANVAS_AUTH_MODE=oauth CANVAS_OAUTH_CLIENT_ID=your-client-id CANVAS_OAUTH_CLIENT_SECRET=your-client-secret CANVAS_OAUTH_REDIRECT_URI=https://yourapp.com/canvas/callback CANVAS_OAUTH_TOKEN=current-access-token CANVAS_OAUTH_REFRESH_TOKEN=refresh-token
User Masquerading (Runtime Only)
Administrators can make API calls as another user (requires appropriate permissions):
use CanvasLMS\Config; // Masquerade as a specific user for all subsequent calls Config::asUser(12345); // Make API calls as that user $courses = Course::get(); // Returns courses visible to user 12345 // Stop masquerading Config::stopMasquerading(); // Now calls are made as the authenticated user again $courses = Course::get();
๐จ Artisan Commands
Test Connection
Verify your Canvas API connection and see authenticated user info:
# Test default connection php artisan canvas:test # Test specific connection php artisan canvas:test --connection=school_b # Show current configuration php artisan canvas:test --show-config # Verbose mode (tests additional endpoints) php artisan canvas:test -v
๐งช Testing Your Integration
Using Pest (Recommended)
use CanvasLMS\Laravel\Testing\CanvasFake; beforeEach(function () { $this->canvas = new CanvasFake(); }); test('enrolls user in course', function () { // Arrange $this->canvas->fake([ 'enrollments' => [ 'id' => 999, 'user_id' => 123, 'course_id' => 456, 'type' => 'StudentEnrollment', ], ]); // Act $enrollment = Enrollment::create([ 'enrollment' => [ 'user_id' => 123, 'course_id' => 456, 'type' => 'StudentEnrollment', ], ]); // Assert expect($enrollment->user_id)->toBe(123); $this->canvas->assertEnrollmentCreated(123, 456, 'StudentEnrollment'); });
Available Assertions
$canvas = new CanvasFake(); // Assert specific API calls $canvas->assertCourseCreated(['name' => 'Laravel 101']); $canvas->assertEnrollmentCreated($userId, $courseId); $canvas->assertApiCallMade('GET', '/courses/*'); $canvas->assertApiCallCount(3); $canvas->assertNoApiCallsMade();
๐ Real-World Examples
Syncing Users from Laravel to Canvas
use App\Models\User; use CanvasLMS\Api\Users\User as CanvasUser; class SyncUsersToCanvas { public function handle() { User::chunk(100, function ($users) { foreach ($users as $user) { CanvasUser::create([ 'user' => [ 'name' => $user->name, 'email' => $user->email, 'sis_user_id' => $user->id, ], ]); } }); } }
Multi-Tenant Course Management
use CanvasLMS\Laravel\Facades\Canvas; class TenantCourseService { public function getCoursesByTenant(string $tenant): array { return Canvas::connection($tenant) ->courses() ::get(['per_page' => 100]); } public function syncCourseAcrossTenants(int $courseId, array $tenants): void { $sourceCourse = Course::find($courseId); foreach ($tenants as $tenant) { Canvas::usingConnection($tenant, function () use ($sourceCourse) { Course::create([ 'name' => $sourceCourse->name, 'course_code' => $sourceCourse->course_code, ]); }); } } }
๐ Available Canvas APIs
This package provides auto-configuration for all Canvas LMS Kit APIs. Use them directly:
Core Resources
CanvasLMS\Api\Courses\Course
- Course managementCanvasLMS\Api\Users\User
- User managementCanvasLMS\Api\Accounts\Account
- Account administration
Course Components
CanvasLMS\Api\Enrollments\Enrollment
- User enrollmentsCanvasLMS\Api\Assignments\Assignment
- Assignments and submissionsCanvasLMS\Api\Modules\Module
- Course modules and itemsCanvasLMS\Api\Pages\Page
- Wiki pagesCanvasLMS\Api\Sections\Section
- Course sectionsCanvasLMS\Api\Tabs\Tab
- Course navigation tabsCanvasLMS\Api\Announcements\Announcement
- Course announcements
Discussions & Communication
CanvasLMS\Api\DiscussionTopics\DiscussionTopic
- Discussion forumsCanvasLMS\Api\Conversations\Conversation
- Internal messagingCanvasLMS\Api\Conferences\Conference
- Web conferences
Files & Media
CanvasLMS\Api\Files\File
- File uploads and managementCanvasLMS\Api\MediaObjects\MediaObject
- Media/video content
Grading & Assessment
CanvasLMS\Api\Quizzes\Quiz
- Quiz creation and managementCanvasLMS\Api\QuizSubmissions\QuizSubmission
- Quiz attemptsCanvasLMS\Api\Submissions\Submission
- Assignment submissionsCanvasLMS\Api\SubmissionComments\SubmissionComment
- Submission feedbackCanvasLMS\Api\Rubrics\Rubric
- Grading rubricsCanvasLMS\Api\GradebookHistory\GradebookHistory
- Grade audit trail
Groups & Collaboration
CanvasLMS\Api\Groups\Group
- Student groupsCanvasLMS\Api\GroupCategories\GroupCategory
- Group sets
Outcomes & Standards
CanvasLMS\Api\Outcomes\Outcome
- Learning outcomesCanvasLMS\Api\OutcomeGroups\OutcomeGroup
- Outcome organizationCanvasLMS\Api\OutcomeResults\OutcomeResult
- Outcome assessmentsCanvasLMS\Api\OutcomeImports\OutcomeImport
- Bulk outcome imports
Calendar & Scheduling
CanvasLMS\Api\CalendarEvents\CalendarEvent
- Calendar entriesCanvasLMS\Api\AppointmentGroups\AppointmentGroup
- Office hours/appointments
Admin & Configuration
CanvasLMS\Api\Admins\Admin
- Account administratorsCanvasLMS\Api\FeatureFlags\FeatureFlag
- Feature togglesCanvasLMS\Api\ExternalTools\ExternalTool
- LTI integrationsCanvasLMS\Api\ContentMigrations\ContentMigration
- Course copy/importCanvasLMS\Api\Progress\Progress
- Long-running job status
See the Canvas LMS Kit documentation for complete API reference.
๐ค Contributing
Contributions are welcome! Please see CONTRIBUTING.md for details.
Development
# Install dependencies composer install # Run tests composer test # Run tests with coverage composer test-coverage # Format code composer format # Run static analysis composer analyse # Run all checks composer check
๐ License
The MIT License (MIT). Please see License File for more information.
๐ Credits
๐ Related Packages
- Canvas LMS Kit - The base PHP SDK
- Canvas LMS API Documentation - Official Canvas API docs
๐ Support
If you encounter any issues or have questions:
- Check the FAQ section below
- Search through existing issues
- Create a new issue with a clear description
โ FAQ
Q: Do I need to manually initialize the Canvas API?
A: No! This package auto-configures everything when Laravel boots.
Q: Can I use this with multiple Canvas instances?
A: Yes! Configure multiple connections and switch between them using Canvas::connection()
.
Q: How do I test Canvas API calls?
A: Use the included CanvasFake
class to mock API responses in your tests.
Q: Is this package compatible with Laravel Octane?
A: Yes, the package is stateless and works with Laravel Octane.
Q: What Laravel versions are supported?
A: Laravel 9.x, 10.x, and 11.x are fully supported.