While it's easy to programmatically add Express objects in your package controllers, you can also use a similar approach to programmatically add Express entries, their attributes, and even associate these entries with each other. f
Create Entities
Package Prerequisite
Note: this documentation assumes you'll be adding an Express Object via the install()
method of a Package. If you aren't familiar with creating Concrete packages you should check out that documentation first.
First, create some Express entities as described in the Express Object Builder documentation.. For example, let's say you create a student entity:
$student = Express::buildObject('student', 'students', 'Student');
$student->addAttribute('text', 'First Name', 'student_first_name');
$student->addAttribute('text', 'Last Name', 'student_last_name');
$student->addAttribute('textarea', 'Bio', 'student_bio');
$student->addAttribute('address', 'Address', 'student_contact_address');
$student->save();
This creates a student object with four attributes. Next, you'll use the Express Entry Builder to create some student entries.
The Express Entry Builder
First, you're going to retrieve an instance of the Express Entry Builder. This can be done by importing Express facade into your package's controller.php file:
use Express;
Then, within the install()
method of the controller.php file, you'll retrieve an instance of the Concrete\Core\Express\EntryBuilder
and add some attributes to it:
$address = new \Concrete\Core\Entity\Attribute\Value\Value\AddressValue();
$address->setAddress1('123 SW Test');
$address->setCity('Portland');
$address->setStateProvince('OR');
$address->setPostalCode('97200');
$entry = Express::buildEntry('student')
->setStudentFirstName('Andrew')
->setStudentLastName('Embler')
->setStudentContactAddress($address)
->save();
The $entry
object here is the full Concrete\Core\Entity\Express\Entry
object, with three attribute keys attached to it. The magic methods setStudent*
work automatically based off the attribute key handles set in the ObjectBuilder class.
Adding Associations to the Object
Adding associations to the entry object is easy too. It's not done through the EntryBuilder class, because unlike the EntryBuilder class objects, associations happen immediately (there is no save()
method.). Let's create a Teacher object, and associate a couple student objects with the teacher:
$teacher = Express::buildObject('teacher', 'teachers', 'Teacher');
$teacher->addAttribute('text', 'First Name', 'teacher_first_name');
$teacher->addAttribute('text', 'Last Name', 'teacher_last_name');
$teacher = $teacher->save();
Now $student
and $teacher
are populated by the Concrete\Core\Entity\Express\Entity
objects that correspond to the relevant Express objects.
$student1 = Express::buildEntry('student')
->setStudentFirstName('Andrew')
->setStudentLastName('Embler')
->save();
$student2 = Express::buildEntry('student')
->setStudentFirstName('Jane')
->setStudentLastName('Doe')
->save();
$teacher = Express::buildEntry('teacher')
->setTeacherFirstName('Albert')
->setTeacherLastName('Einstein')
->save();
Now, assuming there's a one-to-many association from Teacher to Student, we can use the associateEntries()
method on either of the entry objects above, and set the appropriate associated objects.
$teacher->associateEntries()->setStudents([$student1, $student2]);
That's it! The association is updated.
Getting Data From an Express Entry
Once you have an express entry object, it's easy to get data from it. Simply call $entry->get*
where the * matches the camelcased handle of the attribute. So in the example of our attribute named teacher_first_name
, if we had a teacher entry, we'd call
print $entry->getTeacherFirstName();
This returns data in the native value response for the attribute. So in this example it will return text. Want the underlying attribute value object? Just call
$value = $entry->getAttributeValueObject('teacher_first_name');
Getting Associated Entries
It's just as easy to get associated entries from an entry object. In our example above, we have a student and its many-to-one relation with a teacher, and vice versa. When getting the related teacher entries from a student, that target property name will generally be singular, and will by default use the standard handle for teacher ("teacher"). When operating on a teacher entry, since it's a one-to-many association we're working with, we'll be using the target property name that corresponds to the plural handle ("students."). Once we know the relevant target property name for our type of association, we simply call $entry->get*
with the camelcased version of the target property name:
$students = $teacher->getStudents(); // Returns a collection of students since this is one-to-many;
foreach($students as $student) {
print $student->getStudentFirstName();
}
$teacher = $student->getTeacher(); // Returns a single teacher object, since this association is many to one
print $teacher->getTeacherFirstName();
Retrieving Entries
Getting a List of Entries
Getting a list of entries of a certain type is a matter of using the Concrete\Core\Express\EntryList
class. Let's use this class to get a list of all students. First, retrieve the student Express object:
$entity = Express::getObjectByHandle('student');
Then instantiate the entry list object with the entity as its argument.
$list = new Concrete\Core\Express\EntryList($entity);
This is an instance of the Concrete\Core\Search\ItemList\Database\AttributedItemList
class. You can use all the same methods you use to filter pages and files here:
$students = $list->getResults();
Filtering the List
Filter the list the same way you would for custom attributes in a page list:
$list->filterByStudentFirstName('Andrew');
$results = $list->getResults(); // Only returns student objects where the attribute student_first_name is Andrew
Filtering by Association
Filtering by association is possible using the filterByAssociatedEntry
method of the EntryList
. Here's an example filtering the "Medium" object by its associated "Medium Language" entry.
$entity = Express::getObjectByHandle('medium');
$list = new EntryList($entity);
/** @var ExpressEntry $languageEntry */
$languageEntry = Express::getEntry(10); // ID of language entry
/** @var \Concrete\Core\Entity\Express\Association $association */
$association = $entity->getAssociation('medium_language');
$list->filterByAssociatedEntry($association, $languageEntry);
$entries = $list->getResults();
Getting an Entry By Its ID
Need to retrieve an entry by its ID? It's simple:
$student = Express::getEntry(1);
Now you can get its associates or attributes:
print $student->getFirstName();
$teacher = $student->getTeacher();
print $teacher->getTeacherFirstName();
Sorting the List
The same magic methods that work for filtering also work for sorting.
$list = new Concrete\Core\Express\EntryList($entity);
$list->sortByStudentFirstName('desc');
$result = $list->getResults();
Updating Entries
Updating entries is a simple matter as well.
$student = Express::getEntry(1);
We have our first student entry. Let's change his name from Andrew to Andy.
$student->setStudentFirstName('Andy');
$student->setAttribute("student_first_name", "Andy"); // These methods are the same and are interchangeable
Setting the attribute on the object changes it immediately. However, if you were to immediately call getAttribute()
later in the script, the attribute value in the object might not be updated. To combat this, use the refresh()
method in the express Object manager:
$student = Express::refresh($student);
print $student->getStudentFirstName(); // Returns "Andy"
Updating associations is the same as creating them. Note: updating associations clears the existing association.
$student->associateEntries()->setTeacher(null); // Now Andrew has no teacher.
Deleting Entries
Need to delete an Express entry? It's easy:
Express::deleteEntry($student->getID());
Now the student entry is gone. All attribute values and association joins in the database are gone as well. The associations on related entries are kept up to date.