Introduction
About This Package
This package is currently a preview release. The first official release is expected in January. After the first official release, breaking changes will be avoided whenever possible, with the exception being breaking changes as a result of changes in the Valence API itself. However, as last minute details are worked out, there may be changes to this preview release that may cause code you create with this to be changed. It is being offered for experimental purposes at this time.
This open-source package was built to make it easier to use the API (Valence) and data exports (Data Hub) of D2L Brightspace.
This package is written in PHP. If you do not use PHP, while the packages themselves may not be of direct use to you in your applications, it may inspire you to port them over to the language of your choice.
You'll find that the documentation of this package is sparse, which is intentional. The primary functionality for this package is to use with an IDE, like PhpStorm, which offers completion for using classes, functions, fields, etc.
Want to enroll a user in a course with Valence? Just type $valenceobjectname->enroll
and
check the autocompletes for the function that contains action you're looking for. The idea is that
you will not need to dig through documentation, or memorize all the API routes and fields. You'll
use autocomplete to do it for you.
If you do not use an IDE with class-awareness and autocompletion, this package problem won't help you very much. In fact, it will probably increase the amount of time it takes to develop applications with the API as it just adds another layer of documentation you need to read.
Want to access information from the Data Hub? Just type the name of the report you want to retrieve data from (which should autocomplete for you) and access information using the Eloquent ORM.
Features
- Query the Data Hub using the auto-complete feature, chaining methods to find what you're looking for.
- Join Data Hub reports using methods.
- Leverage the Valence API using your IDE's autocomplete features, both to find the appropriate API calls and access the returned object's fields.
- Work directly in your timezone, letting the Valence class convert the times returned from API
calls in GMT to your LMS's or custom time zone, and convert them back to GMT automatically when
making a
POST
orPUT
request, all while using a more friendly format. - Use virtual PATCH objects, allowing you to specify the object you want to modify and specify only the fields you want to change, without needing to rebuild the entire data object to send with a PUT.
- Use the Data Hub as a backdrop for retrieving data, allowing you to specify specific reports to utilize or a certain threshold for how long a course must be completed to use the Data Hub, while returning the data in the same format as the API call, no longer requiring you to use two different sets of code depending upon which source you use.
Future Possible Features
- More API calls added
- More documentation, both written and inline
- More helper functions for specific processes
- More object-specific classes
- More report relationships
- Built-in support to process full and differential reports into a local database
- Helper functions to use additional features of Eloquent
- Ability to process monthly changes to the Data Hub
Note that there are some areas of the API that will not be included. For example, Wilkes University does not have the Learning Object Repository or ePortfolio addons, so they will not be included. However, if you review the source code and the documentation below, you will find that you can extend this class to add functions of your own to the API calls not included as needed.
Presentations
See the presentation below from the D2L Site Administrator Network Connection Event from May 2021:
Setup
Requirements
This class requires you to use PHP 8.1 or later to fully utilize the type hinting options available. It also requires composer. To utilize functionality of the Data Hub, you must have a database setup with each table named after a report and each field in the table named after the corresponding column of the report.
Install the Package
Install the package from composer using the command:
composer require jason-wagner/brightspace-dev-helper:dev-main
This will install the package, as well as all dependencies, including guzzlehttp/guzzle
,
nesbot/carbon
, vlucas/phpdotenv
, illuminate/database
, and
phpleague/csv
.
Generate App and User IDs and Keys
You will need to create an API App ID and key. While this package does support user authentication, you may also need to create a service account, and capture that account's USER ID and key as well. You can find the directions to use generate these through this community post.
Create the .env File
The .env file contains information about your D2L environment and database where the Data Hub reports
have been loaded, and is loaded into $_ENV
each time you run a script using this helper
class.
Use the following to get started with your .env file.
D2L_VALENCE_HOST= D2L_VALENCE_PORT= D2L_VALENCE_SCHEME= D2L_VALENCE_APP_ID= D2L_VALENCE_APP_KEY= D2L_VALENCE_USER_ID= D2L_VALENCE_USER_KEY= DB_DRIVER= DB_HOST= DB_DATABASE= DB_USERNAME= DB_PASSWORD= DB_CHARSET= DB_COLLATION= DB_PREFIX=
For the configuration, it is recommended that you set the charset to utf
and the
collation to utf8_unicode_ci
. The prefix should be set to be blank, but it is required
by the constructor of the database connection class. It may be utilized if additional functionality
to support it is added in the future.
Create the init.php File
Finally, create an init.php file which will be included in all files you create that use this package. This will automatically include all composer packages, initialize the environment variables and create a database connection.
<?php require_once __DIR__.'/vendor/autoload.php'; use Illuminate\Database\Capsule\Manager as Capsule; use BrightspaceDevHelper\Valence\Object\BrightspaceConfig; $dotenv = Dotenv\Dotenv::createImmutable(__DIR__)->load(); $valence_config = new BrightspaceConfig($_ENV['D2L_VALENCE_HOST'], $_ENV['D2L_VALENCE_PORT'], $_ENV['D2L_VALENCE_SCHEME'], $_ENV['D2L_VALENCE_APP_ID'], $_ENV['D2L_VALENCE_APP_KEY'], $_ENV['D2L_VALENCE_USER_ID'], $_ENV['D2L_VALENCE_USER_KEY']); $capsule = new Capsule; $capsule->addConnection([ 'driver' => $_ENV['DB_DRIVER'], 'host' => $_ENV['DB_HOST'], 'database' => $_ENV['DB_DATABASE'], 'username' => $_ENV['DB_USERNAME'], 'password' => $_ENV['DB_PASSWORD'], 'charset' => $_ENV['DB_CHARSET'], 'collation' => $_ENV['DB_COLLATION'], 'prefix' => $_ENV['DB_PREFIX'], ]); $capsule->setAsGlobal(); $capsule->bootEloquent();
If you will not be using this to connect to a database utilizing the Data Hub, remove the lines
related to the Capsule
above.
Using the Package
Basic Examples
Making Valence Requests
First, you will need to create a new Valence Client object:
$valenceObject = new Valence($valence_config);
Then, you just need to find the calls you want to use. Suppose you want to enroll John Smith (UserId 12345) into the ENG 101 A (OrgUnitId 67890) as a student (RoleId 246). Then you can use:
$response = $valenceObject->enrollUser(67890, 12345, 246);
The response is an object in which each of the returned items is an attribute. For example, if the
returned item has a field that is returned called Identifer
, you would access it with
$response->Identifier
.
There are also "IDer functions" which allow you to easily retrieve the IDs of items that have easily queriable codes, like Users and OrgUnits.
For example, suppose in the exam above, John Smith's username is jsmith12 and the course has an offering code of 13579.202101. We can use the IDer functions to find these IDs.
$userId = $valenceObject->getUserIdFromUsername('jsmith12'); $orgUnitId = $valenceObject->getOrgUnitIdFromOfferingCode('13579.202101'); $response = $valenceObject->enrollUser($orgUnitId, $userId, 246);
If a function does not exist for the API call you want to use, you can use the apirequest($route,
$method = 'GET', $data = null)
function to make the call. $data
is an array with
the field names provided as keys.
For example, suppose the whoami
function did not exist in this class:
$response = $valenceObject->apirequest("/d2l/api/lp/".Valence::VERSION_LP."/users/whoami");
Note the use of the constant Valence::VERSION_LP
to get the current version of the
learning platform supported by the class.
Querying the Data Hub
For the Data Hub, this package uses the Eloquent ORM to define relationships to the tables. Once relationships are defined, you can simply call methods on the classes named after what you're attempting to join. Looking for John Doe's assignment submissions?
$user = User::whereUserName('john.doe'); foreach($user->assignmentsubmissions()->get() as $submission) echo implode("\t", [$user->FirstName, $user->LastName, $submission->assignmentsummary->orgunit->Name, $submission->assignmentsummary->Name, $submission->LastSubmissionDate, $submission->Score, $submission->assignmentsummary->PossibleScore]) . "\n";
This creates a tab-delimited table with the student's first name, last name, name of the course the assignment is in, name of the assignment, timestamp of the submission, score, and number of points possible.
But what does all of this mean?
First, we find the user with the username John Doe. Normally, we would use
User::find($UserId)
, but since we probably don't know $UserId
, a helper
function was created to easily find the user by username instead. We can also use other functions of
Eloquent to find what we're looking for, such as User::where('Email',
'john.doe@school.edu')
or User::where('FirstName', 'John')->where('LastName',
'Doe')
. Then, since the Data Hub has a relationship between the Users
table
and AssignmentSubmissions
table (through UserId
), a relationship is
defined on the User
class in a method called assignmentsubmissions
. We
call that method, then get()
, and loop through the results.
Within the results, you can see that there are a few instances where we call
assignmentsummary
on the $submission
object. As we did above, we also
defined a relationship on the AssignmentSubmissions
and AssignmentSummary
tables to join the information. We did this again when we call orgunit
to get the name
of the course it is in, defining a relationship between AssignmentSummary
and
OrganizationalUnits
.
For other examples. you will first need to come up with a starting point, with a query on one of the objects in the database.
Then, functions were created for the relationships on each object, in both directions.
The syntax of the call for the relationship depends upon the type of relationship.
For example, consider the relationship between an OrganizationalUnit
and a
QuizObject
.
This is a one-to-many relationship: each OrganizationalUnit
can have many
QuizObject
s, but each QuizObject
belongs to only one
OrganizationalUnit
.
When something has many, we call it as a function, followed by get()
. In this
case, to get the QuizObject
s of the OrganizationalUnit
with OrgUnitId
123456, we would use the following code:
$orgObject = OrganizationalUnit::find(12345); foreach($orgObject->quizobjects()->get() as $quizobject) // loop through each quiz in $quizobject, such as $quizobject's name in $quizobject->Name
However, when something belongs to, we call it as an attribute. In this case, to get the
OrganizationalUnit
that the QuizObject
with a QuizId
of
24680, we would use the following code:
$quizObject = QuizObject::find(24680); $orgObject = $quizObject->orgunit; // record for the org unit is in $orgObject, such as $orgObject's offering code in $orgObject->Code
In a many-to-many relationship (such as the relationship between Users
and OrganizationalUnits
,
which goes through UserEnrollments
), you always use functions. In a one-to-one
relationship (such as the relationship between OrganizationalUnits
and GradebookSettings
),
you always use attributes.
Options
Logging
The setLogging($mode, $filename)
function allows you to automatically log each API call
that is requested.
If $mode
is 0, nothing is logged; if $mode
is 1, only API calls that change
data (anything besides a GET) is logged; if $mode
is 2, all calls, including GETs, are
logged.
If $filename
is provided, the logs will be saved to a file in that path. If
$filename
is not provided, it will automatically be saved in that directory in a file
called valence.log in the current directory.
Logging is disabled by default.
Error Handling
The setExitOnError($option)
function tells whether the class should exit if there is an
HTTP error is encountered, or allow the script to continue.
exitOnError is enabled by default. To disable it:
$valenceObject->setExitOnError(false);
However, if you disable it, be sure to check the HTTP status code after each call to ensure the API calls have been successful.
To re-enable it, set it to true
.
Return Object on Create
The setReturnObjectOnCreate($option)
function tells whether the class should return a
User or Course client object when one of these entities is created with the Valence class using
createCourseOffering
or createUser
. If it is set to false, it will return
the default object, which is the default setting. However, to use it:
$valenceObject->setReturnObjectOnCreate(true); $newCourseObject = $valenceObject->createCourseOffering(...); print_r($newCourseObject->get()); // displays course information $userid = $valence->getUserIdFromUsername('jsmith12'); $response = $newCourseObject->enrollInstructor($userid); // enroll John Smith in the course
Alternatively, if it were not enabled:
$valenceObject->setReturnObjectOnCreate(false); // not necessary unless it was previously enabled $newCourseResponse = $valenceObject->createCourseOffering(...); print_r($newCourseResponse); // displays course information $userid = $valence->getUserIdFromUsername('jsmith12'); $newCourseObject = $valence->course($newCourseResponse->Identifier); // to get object, must use OrgUnitId from response on creation $response = $newCourseObject->enrollInstructor($userid); // enroll John Smith in the course
Set Class Clients
There are functions, setUserClass
and setCourseClass
, that allow you to set
which class should be used to create User and Course clients if you choose to extend them to add
more customized functions. See the section below on Extending Clients.
Create Objects
To use create objects, use the constructor to create the object you want to create. When you're
created it, you can simply call the create()
.
$newCourse = $valence->newCreateCourseOfferingObject(/* arguments here */); $newCourse->create();
This will make the appropriate API call. Alternatively, you can manually call the method for the API call and pass the object as a parameter.
$newCourse = $valence->newCreateCourseOfferingObject(/* arguments here */); $valence->createCourseOffering($newCourse);
Update Objects
To use update objecrts, they work similarly to create objects except you'll call the
update()
method when finished.
$updateCourse = $valence->newCourseOfferingInfoObject(/* arguments here */); $updateCourse->update();
Like above, you can also create an update object and pass it as an argument to the method for teh API call.
$updateCourse = $valence->newCourseOfferingInfoObject(/* arguments here */); $valence->updateCourseOffering($updateCourse);
Patch Objects
Patch Objects allow you to update an entity while specifying only the fields you want to change and automatically carrying over existing items by at GET request in the background.
For example, suppose you want to activate the course with the OrgId 123456.
$patchObject = $valence->newCourseOfferingInfoPatchObject(123456); $patchObject->setIsActive(true); $patchObject->update();
Note that there is a method, setXXXXX($value)
method for every property of the block.
Array Block Objects
Array Blocks allow you to iterate through an array of results of a given object.
Support you want to iterate all the topics in ForumId 7890 of OrgUnit 123456:
$topics = $valence->getDiscussionTopics(123456, 7890); foreach($topics as $topic) // use $topic->TopicId, $topic->Name, etc.
For results that are paginated, this will automatically grab the next page of results and continue through the loop. There is no need to manually maek another API call.
Extending Clients
In the event that you need to make custom classes, you can extend any of the clients and include them in your application. This may be to add additional functions that are not supported, or to customize functions for your instance or institution.
For example, at Wilkes University, all course offering codes follow the format
crn.termcode
from Banner. Thus, I may create a helper function by doing the following:
class MyValance extends Valence { public function findIdFromCrn(int $termcode, int $crn) { return $this->getOrgUnitIdFromOfferingCode($crn . "." . $termcode): } }
If you override any class besides the main Valence class, you should set the Valence object to utilize that new class.
For example, if you extend the ValenceCourse class:
class MyValanceCourse extends ValenceCourse { ... }
Then, to tell the course object generator in the Valence class to use this when you make a new course object, use the following:
$valenceObject->setCourseClass(MyValenceCourse::class);
Using Eloquent
To do more advanced querying of the database, you should use Laravel's Eloquent ORM. Each of the reports from the Data Hub was created in this package as an Eloquent model. To learn more about what you can do with Eloquent, check out Laravel's documentation.
If you do not use an IDE with class-awareness and autocompletion, this package problem won't help you very much. In fact, it will probably increase the amount of time it takes to develop applications with the API as it just adds another layer of documentation you need to read.
There are some more advanced features of Eloquent that use relationships that you may attempt to use, but may encounter errors if you attempt to use them. This is because many of Eloquent's features rely on default settings with a database created with specific naming conventions that are not utilized by the Data Hub. All the tables in the Data Hub are named exactly as the name of the respective report with spaces removed, while the fields in the table are named exactly as the name of the respective column in the report.
For example, under Laravel's naming conventions, all tables
are to be named, in lowercase, of the plural of the object, with a primary key of
id
, and when used as a foreign key, is to take on the name singularoftablename_id
.
However, in Data Hub, the tables utilize "uppercase words" casing, and the primary key is
TablenameId
.
For the majority of Laravel's operations, the default behavior is also to assume there is a single field as a primary key; however, the Data Hub does have several tables which have a composite key.
You can still use many of this additional functionality of Eloquent; however, you may need to dig into the documentation further to find the additional fields that you need to provide to the different functions.
Function Reference
Valence Functions
Valence Client
Options Functions
getDatahubSearch(string $report): int getTimezone(): string getTimezoneConvert(): bool setCopyStatusDelay(int $seconds): void setCourseClass($courseclass): void setDatahubDayThreshold(int $days): void setDatahubSearch(string $report, int $mode): void setExitOnError(bool $exitonerror): void setInternalIds(): void setLogging(int $logMode, ?string $logFile = null): void setReturnObjectOnCreate(bool $returnobject): void setRoleNameForInstructor(string $role): void setRoleNameForStudent(string $role): void setTimezone(string $timezone): void setTimezoneConversion(bool $timezoneConversion): void setUserClass($userclass): void
Client Helper Functions
__construct(BrightspanceConfig $config) apirequest(string $route, string $method = 'GET', ?array $data = null): ?array apirequestfile(string $route, string $filepath) apisendfile(string $route, string $method, string $filepath, string $field, string $name) checkOrgUnitDatahub(int $orgUnitId): bool createDateTimeFromIso8601($datetime): DateTime createDateTimeFromTimestamp($datetime): DateTime createFromComponents(int $year, int $month, int $day, int $hour, int $minute, int $second): DateTime isValidResponseCode(): bool logrequest(string $route, string $method, ?array $data = null): void responseCode(): ?int responseError(): ?string
Authentication Functions
getAuthUrl(string $appUrl): string getUserCredentials(): ?UserIdKeyPair
Object Generator Functions
newCourseObject(int $orgid): ValenceCourse newUserObject(int $userid): ValenceUser
Create/Patch Object Functions
newCourseOfferingInfoObject(int $orgUnitId, string $Name, string $Code, bool $IsActive, ?string $StartDate, ?string $EndDate, RichTextInput $Description, bool $CanSelfRegister): CourseOfferingInfo newCourseOfferingInfoPatchObject(int $orgUnitId): CourseOfferingInfoPatch newCreateCopyJobRequest(int $SourceOrgUnitId, COPYCOMPONENT|array|null $Components, ?string $CallbackUrl, ?int $DaysToOffsetDates, ?float $HoursToOffsetDates, ?bool $OffsetByStartDate): CreateCopyJobRequest newCreateCourseOfferingObject(string $Name, string $Code, ?string $Path, int $CourseTemplateId, ?int $SemesterId, DateTime|string|null $StartDate, DateTime|string|null $EndDate, ?int $LocaleId, bool $ForceLocale, bool $ShowAddressBook, RichTextInput $Description, ?bool $CanSelfRegister): CreateCourseOffering newCreateEnrollmentDataObject(int $OrgUnitId, int $UserId, int $RoleId): CreateEnrollmentData newGroupCategoryDataCreate(int $orgUnitId, string $Name, RichTextInput $Description, GRPENROLL $EnrollmentStyle, ?int $EnrollmentQuantity, bool $AutoEnroll, bool $RandomizeEnrollments, ?int $NumberOfGroups, ?int $MaxUsersPerGroup, bool $AllocateAfterExpiry, ?string $SelfEnrollmentExpiryDate, ?string $GroupPrefix, ?int $RestrictedByOrgUnitId): ?GroupCategoryDataCreate newGroupDataCreate(int $orgUnitId, int $groupCategoryId, string $Name, string $Code, RichTextInput $Description): ?GroupDataCreate newGroupEnrollmentObject(int $orgUnitId, int $groupCategoryId, int $groupId, int $UserId): GroupEnrollment newNewsItemDataObject(int $orgUnitId, string $Title, RichText $Body, DateTime|string $StartDate, DateTime|string|null $EndDate, bool $IsGlobal, bool $IsPublished, bool $ShowOnlyInCourseOfferings, bool $IsAuthorInfoShown): NewsItemData newNewsItemDataPatchObject(int $orgUnitId, int $newsItemId): NewsItemDataPatch newSectionDataCreate(int $orgUnitId, string $Name, string $Code, RichTextInput $Description): ?SectionDataCreate newSectionEnrollmentObject(int $orgUnitId, int $sectionId, int $UserId): SectionEnrollment newUserAccommodationsCreateObject(int $OrgUnitId, int $UserId, QuizzingAccommodations $QuizzingAccommodations): UserAccommodationsCreate
ID Retriever Functions
getOrgUnitIdFromCode(string $orgUnitCode, int $orgUnitType): ?int getOrgUnitIdFromDepartmentCode(string $departmentCode): ?int getOrgUnitIdFromOfferingCode(string $offeringCode): ?int getOrgUnitIdFromSemesterCode(string $semesterCode): ?int getOrgUnitIdFromTemplateCode(string $templateCode): ?int getUserIdFromOrgDefinedId(string $orgDefinedId): ?int getUserIdFromUsername(string $username): ?int
API Helper Functions
createCourseCopyRequest(int $orgUnitId, CreateCopyJobRequest $input): ?CreateCopyJobResponse createCourseCopyRequestAndWait(int $orgUnitId, CreateCopyJobRequest $input): bool createCourseCopyRequestsAndWait(CopyRequestQueue $requests): bool createCourseGroup(int $orgUnitId, int $groupCategoryId, GroupDataCreate $input): ?GroupData createCourseGroupCategory(int $orgUnitId, GroupCategoryDataCreate $input): ?GroupCategoryData createCourseGroupCategoryAndWait(int $orgUnitId, GroupCategoryDataCreate $input): ?GroupCategoryData createCourseOffering(CreateCourseOffering $input): ValenceCourse|CourseOffering createCourseSection(int $orgUnitId, SectionDataCreate $input): ?SectionData deleteCourseAnnouncement(int $orgUnitId, int $newsItemId): void deleteCourseGroup(int $orgUnitId, int $groupCategoryId, int $groupId): void deleteCourseGroupCategory(int $orgUnitId, int $groupCategoryId): void deleteCourseOffering(int $orgUnitId): void deleteCourseSection(int $orgUnitId, int $sectionId): void deleteUserPicture(int $userId): void dismissCourseAnnouncement(int $orgUnitId, int $newsItemId): void enrollInstructor(int $OrgUnitId, int $UserId): ?EnrollmentData enrollStudent(int $OrgUnitId, int $UserId): ?EnrollmentData enrollUser(CreateEnrollmentData $input): ?EnrollmentData enrollUserInCourseSection(int $orgUnitId, int $sectionId, SectionEnrollment $input): void enrollUserInGroup(int $orgUnitId, int $groupCategoryId, int $groupId, int $UserId): void getAccommodations(int $orgUnitId, int $userId): UserAccommodations getBrightSpaceDataSets(): BrightspaceDataSetReportInfoArray getContentToc(int $orgUnitId): ?TableOfContents getContentTopicFile(int $orgUnitId, int $topicId, string $filepath): bool getCourseAnnouncement(int $orgUnitId, int $newsItemId): ?NewsItem getCourseAnnouncements(int $orgUnitId): ?NewsItemArray getCourseAnnouncementsForUser(int $orgUnitId, int $userId): ?NewsItemArray getCourseCopyJobStatus(int $orgUnitId, string $jobToken): ?GetCopyJobResponse getCourseGroup(int $orgUnitId, int $groupCategoryId, int $groupId): ?GroupData getCourseGroupCategories(int $orgUnitId): GroupCategoryDataArray getCourseGroupCategory(int $orgUnitId, int $groupCategoryId): ?GroupCategoryData getCourseGroups(int $orgUnitId, int $groupCategoryId): GroupDataArray getCourseImage(int $orgUnitId, string $filepath): bool getCourseOffering(int $orgUnitId): ?CourseOffering getCourseSection(int $orgUnitId, int $sectionId): ?SectionData getCourseSectionSettings(int $orgUnitId): ?SectionPropertyData getCourseSections(int $orgUnitId): SectionDataArray getDeletedCourseAnnouncements(int $orgUnitId): ?NewsItemArray getDiscussionForum(int $orgUnitId, int $forumId): ?Forum getDiscussionForums(int $orgUnitId): ForumArray getDiscussionPost(int $orgUnitId, int $forumId, int $topicId, int $postId): ?Post getDiscussionPosts(int $orgUnitId, int $forumId, int $topicId): PostArray getDiscussionTopic(int $orgUnitId, int $forumId, int $topicId): ?Topic getDiscussionTopics(int $orgUnitId, int $forumId): TopicArray getEnrollment(int $orgUnitId, int $userId): ?EnrollmentData getEnrollments(int $orgUnitId): ?OrgUnitUserArray getOrgUnitType($orgUnitTypeId): ?OrgUnitType getOrgUnitTypes(): OrgUnitTypeArray getOrganization(): ?Organization getRole($roleId): ?Role getRoles(): RoleArray getUser(int $userId): ?UserData getUserNames(int $userId): ?LegalPreferredNames getUserPicture(int $userId, string $filepath): bool getUserProfile(int $userId): ?UserProfile initializeCourseSections(int $orgUnitId, SECTENROLL $EnrollmentStyle, int $EnrollmentQuantity, bool $AuthEnroll, bool $RandomizeEnrollments): ?SectionData pinCourse(int $orgUnitId, int $userId): void postCourseAnnouncement(int $orgUnitId, NewsItemData $input): NewsItem publishCourseAnnouncement(int $orgUnitId, int $newsItemId): void restoreCourseAnnouncement(int $orgUnitId, int $newsItemId): void restoreDeletedCourseAnnouncement(int $orgUnitId, int $newsItemId): void setAccommodations(UserAccommodationsCreate $input): UserAccommodations unenrollUser(int $userId, int $orgUnitId): void unenrollUserFromGroup(int $orgUnitId, int $groupCategoryId, int $groupId, int $userId): void unpinCourse(int $orgUnitId, int $userId): void updateCourseAnnouncement(int $orgUnitId, int $newsItemId, NewsItemData $input): void updateCourseGroup(int $orgUnitId, int $groupCategoryId, int $groupId, string $Name, string $Code, string $DescriptionText): ?GroupData updateCourseGroupCategory(int $orgUnitId, int $groupCategoryId, string $Name, string $DescriptionText, GRPENROLL $EnrollmentStyle, ?int $EnrollmentQuantity, bool $AutoEnroll, bool $RandomizeEnrollments, ?int $NumberOfGroups, ?int $MaxUsersPerGroup, bool $AllocateAfterExpiry, ?string $SelfEnrollmentExpiryDate, ?string $GroupPrefix, ?int $RestrictedByOrgUnitId): ?GroupCategoryData updateCourseOffering(int $orgUnitId, CourseOfferingInfo $input): void updateCourseSection(int $orgUnitId, int $sectionId, string $Name, string $Code, string $DescriptionText): ?SectionData updateCourseSectionSettings(int $orgUnitId, SECTENROLL $EnrollmentStyle, int $EnrollmentQuantity, int $AuthEnroll, int $RandomizeEnrollments): ?SectionPropertyData updateUserNames(int $userId, string $LegalFirstName, string $LegalLastName, ?string $PreferredFirstName, ?string $PreferredLastName): ?LegalPreferredNames uploadCourseImage(int $orgUnitId, string $filepath, string $name): bool uploadUserPicture(int $userId, string $filepath): bool version(string $productCode): ?ProductVersions versions(): ProductVersionArray whoami(): ?WhoAmIUser
Course Client API Helper Functions
__construct(Valence $valence, int $orgUnitId) createCopyRequest(CreateCopyJobRequest $input): ?CreateCopyJobResponse createGroup(int $groupCategoryId, string $Name, string $Code, string $DescriptionText): ?GroupData createGroupCategory(string $Name, string $DescriptionText, GRPENROLL $EnrollmentStyle, ?int $EnrollmentQuantity, bool $AutoEnroll, bool $RandomizeEnrollments, ?int $NumberOfGroups, ?int $MaxUsersPerGroup, bool $AllocateAfterExpiry, ?string $SelfEnrollmentExpiryDate, ?string $GroupPrefix, ?int $RestrictedByOrgUnitId): ?GroupCategoryData createSection(string $Name, string $Code, RichText $Description): ?SectionData deleteCourseAnnouncement(int $newsItemId): void deleteGroup(int $groupCategoryId, int $groupId): void deleteGroupCategory(int $groupCategoryId): void deleteSection(int $sectionId): void dismissCourseAnnouncement(int $newsItemId): void enrollInstructor(int $UserId): ?EnrollmentData enrollStudent(int $UserId): ?EnrollmentData enrollUser(int $UserId, int $RoleId): ?EnrollmentData enrollUserInGroup(int $groupCategoryId, int $groupId, int $UserId): void enrollUserInSection(int $sectionId, int $UserId): void get(): ?CourseOffering getAccommodations(int $userId): UserAccommodations getAnnouncement(int $newsItemId): NewsItem getAnnouncements(): NewsItemArray getAnnouncementsForUser(int $userId): NewsItemArray getContentToc(): ?TableOfContents getContentTopicFile(int $topicId, string $filepath): bool getCopyJobStatus(string $jobToken): ?GetCopyJobResponse getDeletedAnnouncements(): NewsItemArray getDiscussionForum(int $forumId): ?Forum getDiscussionForums(): ForumArray getDiscussionPost(int $forumId, int $topicId, int $postId): ?Post getDiscussionPosts(int $forumId, int $topicId): PostArray getDiscussionTopic(int $forumId, int $topicId): ?Topic getDiscussionTopics(int $forumId): TopicArray getEnrollment(int $userId): ?EnrollmentData getEnrollments(): ?OrgUnitUserArray getGroup(int $groupCategoryId, int $groupId): ?GroupData getGroupCategories(): GroupCategoryDataArray getGroupCategory(int $groupCategoryId): ?GroupCategoryData getGroups(int $groupCategoryId): GroupDataArray getImage(string $filepath): bool getSection(int $sectionid): ?SectionData getSectionSettings(): ?SectionPropertyData getSections(): SectionDataArray initializeSections(SECTENROLL $EnrollmentStyle, int $EnrollmentQuantity, bool $AuthEnroll, bool $RandomizeEnrollments): ?SectionData pinForUser(int $userId): void postCourseAnnouncement(NewsItemData $input): NewsItem publishCourseAnnouncement(int $newsItemId): void restoreCourseAnnouncement(int $newsItemId): void restoreDeletedCourseAnnouncement(int $newsItemId): void unenrollUser(int $UserId): void unenrollUserFromGroup(int $groupCategoryId, int $groupId, int $userId): void unpinForUser(int $userId): void updateCourseAnnouncement(int $newsItemId, NewsItemData $input): void updateGroup(int $groupCategoryId, int $groupId, string $Name, string $Code, string $DescriptionText): ?GroupData updateGroupCategory(int $groupCategoryId, string $Name, string $DescriptionText, GRPENROLL $EnrollmentType, ?int $EnrollmentQuantity, bool $AutoEnrollment, bool $RandomizeEnrollments, ?int $NumberOfGroups, ?int $MaxUsersPerGroup, bool $AllocateAfterExpiry, ?string $SelfEnrollmentExpiryDate, ?string $GroupPrefix, ?int $RestrictedByOrgUnitId): ?GroupCategoryData updateSection(int $sectionId, string $Name, string $Code, string $DescriptionText): ?SectionData updateSectionSettings(SECTENROLL $EnrollmentStyle, int $EnrollmentQuantity, bool $AuthEnroll, bool $RandomizeEnrollments): ?SectionPropertyData uploadCourseImage(string $filepath, string $name): bool
User Client API Helper Functions
__construct(Valence $valence, int $userId) deletePicture(): void enrollAsInstructor(int $OrgUnitId): ?EnrollmentData enrollAsStudent(int $OrgUnitId): ?EnrollmentData enrollInCourse(int $OrgUnitId, int $RoleId): ?EnrollmentData enrollInCourseSection(int $orgUnitId, int $sectionId): void enrollInGroup(int $orgUnitId, int $groupCategoryId, GroupEnrollment $input): void get(): ?UserData getAccommodations(int $orgUnitId): UserAccommodations getEnrollment(int $orgUnitId): ?EnrollmentData getNames(): LegalPreferredNames getPicture(string $filepath): bool getProfile(): ?UserProfile pinCourse(int $orgUnitId): void unenroll(int $orgUnitId): void unenrollFromGroup(int $orgUnitId, int $groupCategoryId, int $groupId): void unpinCourse(int $orgUnitId): void updateNames(string $LegalFirstName, string $LegalLastName, ?string $PreferredFirstName, ?string $PreferredLastName): LegalPreferredNames uploadPicture(string $filepath): bool
Objects
Arrays
COPYCOMPONENT
Attributes
ACTIVITYTYPE AVAILABILITY CONTENT_COMPLETIONTYPE COPYJOBSTATUS GRPENROLL RATING SCORING SECTENROLL TIMEOP
Blocks
BasicOrgUnit Birthday BrightspaceDatasetReportInfo CourseOffering CreateCopyJobResponse EnrollmentData Forum GetCopyJobResponse GroupCategoryData GroupData LegalPreferredNames NewsItem OrgUnitType OrgUnitUser Organization Permissions Post ProductVersions QuizzingAccommodations QuizControlAccommodation QuizTimeLimitAccommodation RichText Role RoleInfo SectionData SectionPropertyData SocialMediaUrl TableOfContents TableOfContentsModule TableOfContentsTopic Topic User UserAccommodations UserActivationData UserData UserProfile WhoAmIUser
Block Arrays
BrightspaceDataSetReportInfoArray BrightspaceDataSetReportInfoPreviousArray ForumArray GroupCategoryDataArray GroupDataArray NewsItemArray OrgUnitTypeArray OrgUnitUserArray PostArray ProductVersionArray RoleArray SectionDataArray SocialMediaUrls TableOfContentsModuleArray TableOfContentsTopicArray TopicArray
Create Blocks
CreateCopyJobRequest CreateCourseOffering CreateEnrollmentData GroupCategoryDataCreate GroupDataCreate GroupEnrollment NewsItemData QuizzingAccommodationsCreate QuizControlAccommodationCreate QuizTimeLimitAccommodationCreate RichTextInput SectionDataCreate SectionEnrollment UserAccommodationsCreate
Update Blocks
CourseOfferingInfo
Patch Blocks
CourseOfferingInfoPatch NewsItemDataPatch
Class Objects
BrightspaceConfig CopyRequest CopyRequestQueue DateTime NotInDatahub UserIdKeyPair
Data Hub Related Functions
Relationship Mappings
While this release contains all the objects for the Data Hub, it does not have all the relationships mapped. These are the relationships that are currently included:
- AssignmentSubmission
- assignmentsubmissions
- assignmentsummary
- orgunit
- users
- DiscussionForum
- discussiontopics
- orgunit
- DiscussionPost
- discussiontopic
- users
- DiscussionTopic
- discussionforum
- discussionposts
- OrganizationalUnit
- assignments
- department
- discussionforums
- parents
- quizobjects
- semester
- template
- users
- QuizAttempt
- quizobject
- user
- QuizObject
- orgunit
- quizattempts
- User
- assignmentsubmissions
- courses
- discussionposts
- quizattempts
Helper Functions
The following helper functions exist to find some of the objects that have a more common identifier you may be familiar with.
OrganizationalUnit::whereCode($code)
OrganizationalUnit::whereCodeAndType($code, $type)
OrganizationalUnit::whereOrgUnitId($orgunitid)
OrganizationalUnit::isCurrent($orgUnitId, $thresholdInDays)
Users::whereOrgDefinedId($orgdefinedid)
Users::whereUserId($userid)
Users::whereUserName($username)
Frequently Asked Questions
Why are some variables in the hints in camel case (i.e. variableName) and some with uppercase words (VariableName)?
This is intentionally done to be consistent with the corresponding variables in the API. In general, variables in URLs (such as parameters within the API calls and query strings) are in camel case and fields within the JSON parameters have the uppercase first words.
Why are the variables inconsistent in terms of some being arrays and some being objects? Is there a way to have all functions return arrays instead of objects?
This is to best utilize the functionality of your IDE. In PHP, there is no way to define anything like an "array template." Thus, if we simply utilized an array, you would still need to dig in to the documentation to find the fields that are available. However, by using objects, and using type-hinting to define the return type of a function to be a particular object, your IDE can then autocomplete the attributes of an object returned by a function. Although a later version of PHP introduces the ability to specify that a function may return one of several object types, it would break -- at least partially -- the ability to autocomplete attributes of a class if we were to specify that an array could also be returned.