Documente Academic
Documente Profesional
Documente Cultură
MANUAL
Contents
Intro ................................................................................................................................ 5
What’s new in eFrontPro ......................................................................................... 5
Administrator ................................................................................................................ 7
Dashboard ................................................................................................................ 7
Users ........................................................................................................................... 8
Courses .................................................................................................................... 10
Curriculums ............................................................................................................. 14
Categories .............................................................................................................. 15
Certificates.............................................................................................................. 16
Groups ..................................................................................................................... 17
Branches ................................................................................................................. 18
Jobs .......................................................................................................................... 19
Skills........................................................................................................................... 20
User types ................................................................................................................ 21
Audiences ............................................................................................................... 23
Locations ................................................................................................................. 25
Themes .................................................................................................................... 26
Notifications ............................................................................................................ 27
Extend Profile .......................................................................................................... 28
Languages .............................................................................................................. 30
Reports..................................................................................................................... 31
Maintenance.......................................................................................................... 33
Discussions ............................................................................................................... 34
Archive .................................................................................................................... 34
Plugins ...................................................................................................................... 34
eCommerce ........................................................................................................... 35
System Settings ....................................................................................................... 36
Instructor ..................................................................................................................... 37
Dashboard .............................................................................................................. 37
Course screen ........................................................................................................ 38
Lesson screen ......................................................................................................... 39
Group key ............................................................................................................... 42
Course catalog ...................................................................................................... 42
Discussions ............................................................................................................... 44
Courses .................................................................................................................... 44
Learner ........................................................................................................................ 45
My courses .............................................................................................................. 45
Course view ............................................................................................................ 45
Course catalog ...................................................................................................... 46
Discussions ............................................................................................................... 46
Personal info ........................................................................................................... 47
Search ..................................................................................................................... 49
Logout ..................................................................................................................... 49
Technical Topics ........................................................................................................ 50
Installation details and considerations ............................................................... 50
Upgrading ............................................................................................................... 52
System Architecture .............................................................................................. 53
How to secure your environment ........................................................................ 55
Performance Tips ................................................................................................... 56
How to create a Theme ........................................................................................ 57
How to customize Certifications .......................................................................... 61
Frequent Questions ................................................................................................... 66
How to assign a set of courses to new users directly ........................................ 66
How to offer Compliance Training ...................................................................... 67
How to customize your learning portal ............................................................... 69
How to customize the communication emails .................................................. 70
What is the difference between Branches and Groups .................................. 72
How to work with Mass Actions ............................................................................ 73
How eFrontPro supports Instructor Led Training ................................................. 74
How eFrontPro deals with WCAG, Section 508 & ADA Compliance ............. 75
How to integrate eFrontPro with your system .................................................... 77
How to work with content conversions ............................................................... 78
How to work with Videoconferencing ................................................................ 79
Appendix 1: eFrontPro Plugin Guide....................................................................... 80
Quick start ............................................................................................................... 80
More plugin examples......................................................................................... 114
Considerations...................................................................................................... 114
Plugin API Reference ........................................................................................... 120
Event Reference .................................................................................................. 124
Core API Notes ..................................................................................................... 126
Intro
Welcome! Whether you’re a long time eFront user upgrading to the latest
version, or you have just entered the world of e-learning, rest assured that you
have chosen well. eFront is a stable, proven, platform covering the e-learning
needs of thousands of organizations and millions of students all over the world.
This Quick Start Guide will teach you all you need to know to get started with
deploying eFrontPro, and creating, managing and taking courses. It’s organized
in 3 sections in accordance with the 3 working modes of eFrontPro: the
Administrator, the Instructor and the Learner mode, plus a fourth section
covering common UI elements.
Improvements include:
Content creation
With eFrontPro we took a leap in revamping the content creation process. We
made it really easy to re-use content you already have from PDFs, Videos,
Audios, Images and SCORM or re-use web material from Youtube, Vimeo, Prezi
and other sources.
Reporting
We totally redesigned the Reporting section of the system to provide clarity and
easy access to vital information. The new filtering system let you segment your
reports in any meaningful way. The new visualization of system activity offers a
5
stunning way to report on your learners’ progress. And the mass actions minimize
the time to perform complex tasks.
Extended Enterprise
Leverage the power of eFrontPro to extend eLearning across your enterprise.
Serve content from a centralized eLearning repository and deliver to any number
of privately branded portals. Each enterprise portal can be personalized using
distinct skins and features to provide a learning experience appropriate to any
target audience.
E-commerce extensions
There is a wealth of ecommerce extensions in eFrontPro, such as Paypal and
Stripe support and ways to handle complex e-commerce relationships through
Balances, Discounts and Price Tracks. If you want to use eFrontPro to resell or
license courses we have great news for you!
Offline Learning
eFrontPro utilizes the power of HTML5 to bring offline content support embedded
within the platform. This first-of-its-class offline implementation let you download
a lesson for offline viewing directly within your browser and without the need of
a dedicated mobile application.
Internals
eFrontPro is built around jQuery (a step forward from our legacy Prototype based
codebase), uses (industry standard) get-text for translations, HTML5 and
Bootstrap-3 for the interface and a modern MVC architecture. The result is a
dramatically improved and lean code-base that we can build upon in the years
to come.
6
Administrator
Dashboard
The Admin dashboard includes everything you need to effectively manage your
eFrontPro installation. Within it you can add users, create courses, view reports
and manage your account.
The left one, titled “Options”, has an icon-based menu of all the available
administration sections.
The right includes a list of announcements (with the ability to create a new one),
and a calendar highlighting events for the current month.
7
Users
The Users section allows you to list, add and manage users.
The Users section allows you to see all users in a tabular listing with buttons to edit,
delete or login as a specific user, and contains a search box for quickly finding
the users you want to view or edit.
The user add/edit panel, shown when you create a new user or edit an existing
one, allows you to specify user information such as email address, preferred
language, time zone, whether or not the user is active, and a short CV.
2. Enter the values for the required fields: First and Last name, username,
password (and password confirmation), and e-mail address. The default
user type created is Student (as normally most of your users will be
students), so if you want to add an Administrator or Instructor be sure to
change it.
8
3. The optional values include: User avatar (usually a photo of the user),
language (which can be used to serve language specific content), time-
zone and the Branch the user belongs to (in case you use eFrontPro’s
Branches feature). You can also add a short description or CV for the user.
4. After you’ve completed the User add form, click Submit and your new
User will be created.
Note that you can also have custom fields when you add a User, which you
can enable in the Extend Profile section.
9
Courses
A course is the main learning entity in eFrontPro.
You can create a new course in the Courses section, by opening the “Add
Course” panel and giving it a name, a category, a type (e-learning or classroom
based), and an optional description and thumbnail image (Avatar).
There are a few more options that can be set for a course if you click to open
the “Advanced Settings”, such as its price (if you want it to be a paid course),
whether the course will offer a certification to those who have completed it (as
well as the certification’s duration), the intended audience and language, and
the branch (department) that offers it.
A course code can also be set, to help users quickly and uniquely identify the
course.
Courses are owned by the user that creates them, and, who has the ability to
edit the basic course information such as name, category, price, etc. A course
owner can assign more users as Instructors for the course, giving them the ability
to add and modify course content.
The Courses section allows you to see all courses in a tabular listing with buttons
to edit or delete a specific course, and contains a search box for quickly finding
the course you want to view or edit. The courses list can be downloaded as an
Excel-compatible CSV file.
After selecting a course, the user can view or edit its Properties, Lessons, Users
and Skills, through the respective tabs. The Properties tab displays the same basic
and advanced course information as discussed above for the “Add Course”
panel.
10
The Lessons tab displays a listing of the lessons contained in the course, and
allows the user to create new lessons assigned to the course, set the lesson order
and configure whether or not the students have to complete lessons in order
(“Serial rule enabled/disabled”). The lesson list can be downloaded as an Excel-
compatible CSV file.
The Users tab displays a listing of the users associated in the course, as either
Professors or Students and their registration date. For each student, the Users
listing also displays his course completion date, what his score was and whether
he was awarded a certificate. This information can be downloaded as an Excel-
compatible CSV file.
Finally, the Skills tab shows a listing of skills associated with the selected course.
A “skill” describes a specific knowledge or experience that is either Offered by
the course (meaning that students who complete the course are assigned that
skill) or “Required” by the course (meaning that students need to have that skill,
perhaps by completing another course offering it, in order to take the course).
The listing of skills can be downloaded as an Excel-compatible CSV file.
11
Mini How-to: Adding a new Course
To add a new course, click on the “+ Add Course” button in the Courses section.
This will open the page to add a new course.
The required fields are the Name and the Category of the course (e.g. History,
Math, Physics, etc.)
The default course type is set to e-learning, for a typical e-learning course
based on asynchronous (i.e. at the student’s discretion) access to the course
material. If you want to create an instructor-led classroom based course,
change this option to Classroom (ILT).
There’s also the option add a short description for the course.
If you’re OK with the settings, you can create the course by clicking the
“Submit” button. But there are several advanced options that you can see and
set by clicking on the “Advanced Settings” button.
The advanced settings include: a course code (a short alphanumeric code for
easy reference, e.g. “CS101”), language (to show language specific content to
different users), a base price (for selling the course), availability (how many
days an enrolled user has access to the course), CEUs (how many continuous
education units the course corresponds to), course’s audiences and branch,
and, finally, the certification awarded for completing the course.
12
When done, click “Submit”. The arrow on the right of the submit button works as
a shortcut that enabled you to create a Lesson with the same name as the
course.
13
Curriculums
Curriculums are a way of grouping your courses for better organization, to
perform mass actions on all of them, and to sell them online as a single entity.
What Groups are for Users, Curriculums are for courses.
The Curriculums section allows you to see all existing curricula in a tabular listing
that also shows the number of students enrolled to each one and buttons to edit
or delete a specific curriculum. The section also features a search box for quickly
finding the curriculum you want to view or edit. The curriculum list can be
downloaded as an Excel-compatible CSV file.
You can add a new curriculum through the “Add curriculum” button, by entering
a name for your new curriculum and selecting the category it belongs too, an
avatar and a short description.
There are also a number of advanced settings, such as a code enabling students
to register to the curriculum by themselves, whether the Curriculum is active and
ok to be shown on the catalog, a base price for enrolling in the curriculum, the
branch it belongs to and the certification you get by completing it.
After you have created your curriculum you can add Courses and Users to it.
On the form that appears you need to fill in the name of the curriculum and
select the category (e.g. History, Math, etc) that your curriculum belongs to. You
can also add an optional Short Description.
Finally, there are several advanced options that you can set when you click on
the “advanced settings” link. Those are a unique code for identifying the
curriculum, whether to activate and/or show the curriculum on the catalog, the
base price for selling the curriculum, the branch the curriculum belongs to, and
a certification that is awarded to the users completing this curriculum.
When you are finished completing the form, click “Submit” to create the new
curriculum.
14
Categories
Categories are a way of organizing your courses into different themes / topics,
etc. They can be a flat list (e.g Ancient Civilizations, Biology, Programming, etc)
or form nested hierarchies (e.g Ancient Civilizations/Greek, Ancient
Civilizations/Latin, etc).
The Categories section allows you to see all existing categories in a tabular listing
that also shows the number of courses assigned to each one and buttons to edit
or delete a specific category. The section also features a search box for quickly
finding the category you want to view or edit. The categories list can be
downloaded as an Excel-compatible CSV file.
You can add a new category through the “Add category” button, by entering
a name for your new category and selecting its parent category (if it’s supposed
to be nested).
15
Certificates
The Certificates section shows a listing of the certificates available to be
awarded upon the completion of a course. You can edit, delete or preview
existing certificates and add new ones.
To add a new certificate, you press the “Add certificate” button (duh!). A
certificate needs a name, and a definition of how it should be presented (as a
PDF). The definition is in the form of an XML template, with all the defaults
provided for you, and the option to customize the presentation and the
information shown in the certificate by placing simple pre-defined tags like
<grade>, <username> and <logo>.
You can also assign the certificate to a specific branch, in which case it will only
be available to its members.
To learn how you can create your own certificate or customize and existing
one, visit the How to customize Certifications chapter.
16
Groups
Groups organize users into logical entities, allowing them to treat all of them as a
single entity. You can communicate to the users of a group directly, assign them
courses, or see reports on them. Groups come with mass actions to synchronize
its users with its courses.
The Groups section shows a tabular listing of all existing groups, allowing you to
edit or delete them and add a new one. You can add a group with the “Add
Group” button by setting a name, selecting an optional branch, and entering a
short description. There are also some advanced options that can be set for a
group, such as a unique group key (which can be shared with the students to
allow them to register to the group’s classes) and an optional limit of maximum
key uses (for groups were a limited student membership is desired).
After selecting a group from the list of groups, you can update its basic and
advanced information, and see the Users and Courses assigned to the group.
You also have the option to mass-enroll all of the group users to the group’s
courses.
17
Branches
Branches allow you to divide your e-learning offering into different logical units
(or “departments”), each with its own courses, users, professors and branding
(sub-domain, theme, logo, etc.). Branches can be a flat list or form a nested
hierarchy.
The Branches section displays a tabular listing of all existing branches, their parent
branch (if nested), and the number of users and courses belonging to the
branch, and allows you to edit a branch or add a new one. The branches list
can be downloaded as an Excel-compatible CSV file.
To create a new branch, you press the “Add Branch” button and enter the
desired name and sub-domain (e.g. mybranch.efrontlearning.com), and an
optional parent branch. You can also enter an optional branch short-code, to
help you uniquely identify the branch.
The panel for editing an existing branch is similar to the “add branch” panel, but
also contains tabs to see the branches Users, Courses and extra Settings.
The Users and Courses tabs are simple tabular listings of the Users and Courses
assigned to the branch respectively, and allow you to download this information
in Excel-compatible CSV format.
The branch Settings tab allows you to set the language used for the branch, as
well as a custom logo, favicon and theme to be used for the branch’s content.
To learn more about the differences between Branches and Groups, you can
visit the What is the difference between Branches and Groups chapter.
18
Jobs
Jobs enable you to divide your students according to their role in your
organization or company. This can be helpful in enterprise e-learning situations,
allowing you to assign courses to people with specific positions. Jobs are a handy
attribute for defining dynamic “Audiences” (see later chapter).
The Jobs section shows a tabular listing of all defined jobs, along with the branch
they belong to (if set), and the number of users holding that job. From the listing,
you have the option to edit or delete an existing job, or create a new one. The
Job listing can be downloaded as an Excel-compatible CSV file.
To create a new Job, click the “Add Job” button, and enter the desired name,
and an optional Branch that the job will be constrained in, number of maximum
users allowed having this job and a short description. You also have the option
to set a unique short-code to quickly and unambiguously identify this job.
19
Skills
A “skill” describes a specific knowledge or experience that is either offered by a
course (meaning that students who complete the course “get” that skill) or
“required” by a course (meaning that students need to have that skill, perhaps
by completing another course offering it, in order to take a course).
The Skills sections shows you a listing of all skills, along with the category each skill
belongs to and the number of users that possess it, and has buttons to add a
new skill, or edit or delete an existing one.
The listing of skills can be filtered, to quickly find the one you want to view/edit,
and it can also be downloaded as an Excel-compatible CSV file.
To add a new skill, click the “Add Skill” button and enter a name and category
the skill belongs to, as well as an optional description and branch to which it
would be constrained.
20
User types
A user’s type defines the set of permissions and capabilities that he has in working
with eFrontPro. You have the option to fine-tune the permissions of the built-in
user types (Administrator, Professor and Student) or add new user types based
on the existing ones.
The set of permissions and capabilities that you can fine-tune includes whether
the user type can view or edit other Users, Courses, Lessons, Groups, Branches,
Skills, Announcements, Themes, etc.
The User Types section shows a tabular listing of the available user types, and
provides buttons to edit an existing user or add a new one.
To add a new user type, click the “Add User Type” button, enter a new name for
the new type (e.g. “Admin Helper” or “Course Manager”), select an existing user
type it will be based on, and configure his permissions.
The three built-in user types (Administrator, Professor (Instructor) and Student) can
serve as the templates to base your custom user type permissions on, by selecting
the “Basic User Type” for your user type (note that this will change the permissions
of your user type to the ones that the basic user type has, so it’s best to only do it
when you begin editing a new user type, to avoid losing your changes).
21
Permissions are applied to eFrontPro’s entities, such as courses, lessons, users,
groups, jobs, branches, etc, and can be “Disabled” (not applicable to this user),
“View” (user can view this item), “Edit” (user can view and edit this item’s
properties) and “Add/Edit” (user can edit this items properties and create new
items of the same kind).
- Can View and Edit Users, User Types, Branches and Jobs, (“Edit”)
Note that if you can “Edit” an item, it is implied that you can also “View” it (but
not the reverse).
22
Audiences
Audiences allow you to divide your users into logical groups based on certain
conditions (“Rules”), such as the Branch they belong to, their Job Position, their
User Type, or custom criteria (the values of custom “Extended Fields” you might
have defined for them).
The Audiences section shows a tabular listing of the audiences you have
defined, allowing you to edit, delete or activate an existing audience or add a
new one.
To add an audience you click on the “New Audience” button, and enter the
name and an optional branch and description for your new audience.
After you created an Audience, you have the option to edit its rules in the “Rules”
tab, and see a listing of the users matching this Audience in the “Users” tab.
To create a new Audience entry, click on the “+ New Audience” button on the
Audiences section. You’ll need to enter a name for the Audience, and specify
an optional Branch and Description. Finally, you can set it to active (default) or
not. When finished, click “Submit” to create your new Audience entry.
After you have created your Audience you get to specify the rules for it. You
can select one or more Branches, Job Positions and User Types to have the
Audience automatically match the users fitting those criteria.
23
You can also specify specific users to be included in the Audience, or use
Extended Criteria, which are custom fields you can specify for your users
(consult the Extend Profile chapter for how to create and manage them).
The Users tab of your Audience will show you a listing of all the Users that your
rules matched.
24
Locations
Locations are names of venues (real of virtual) that classes or meetings will take
place, allowing you to organize your class schedule and inform your students of
upcoming meetings. Locations are especially useful in a hybrid-learning
scenario.
The Locations section shows a tabular listing of all locations, with their short-code,
time zone info and whether or not they are virtual or physical places. Buttons
allow the user to edit or delete an existing Location as well as add a new one.
To add a new Location, click the “+ Add Location” button and enter the name
and the (optional) Branch that the Location applies to.
You can also configure a set of advanced settings, such as the Location’s virtual
or physical status, its address down to the room number (for physical venues), its
time zone and the assigned contact person(s).
25
Themes
Themes allow you to change the layout and look of your e-learning content. You
can have a default look and also define a different look for each of your
Branches.
The Themes section shows two tabs, one for the “Layout” and one to “Change
Theme”.
The “Layout” allow you to define the contents of the page, including what blocks
are shown and in what order. A block, in eFrontPro lingo, is any separate
rectangular page entity, such as the Calendar view or the Announcements list.
The “Change Theme” tab shows a listing of installed themes, and allows you to
edit existing themes or install new ones.
To install a new theme click the Install Theme button, and enter the name of your
theme, an optional branch it will be applied to, and the CSS code with the styling
directions (colors, backgrounds, fonts etc.) for your theme.
To learn more about creating your own themes, or customizing an existing one,
visit the How to create a Theme.
26
Notifications
“Notifications” in eFrontPro lingo are the communication emails that are sent
automatically from the system when specific events take place. eFrontPro
comes with a few notifications types built-in, but you also have the option to
define your own notifications. For example you can setup a mail to be sent to a
user after he or she registers for a course. The Notifications section shows a list of
all defined Notifications and the event that triggers them, and allows you to edit,
delete and activate a Notification, as well as create a new one.
To create a new Notification, click the “Add Notification” button and select the
event that triggers the notification (e.g. course completion), the recipients, the
delivery time, the subject and the body of the email that will be send to the user.
You can write anything you want for the body, and there are also several
keywords such as “date” and “recipient’s name” that you can use, which the
system automatically replaces with their proper values.
The Notifications section also contains the “Mail Queue” and “History” tabs,
which show pending and previously sent notification emails respectively.
To learn more about working with Notifications and customizing messages, visit
the How to customize the communication emails chapter.
27
Extend Profile
Profile extension in eFrontPro lingo refers to the act of adding custom information
fields to Users, Courses, and Branches.
For example you could “extend” the user profile to store the user’s age, gender,
country of origin, twitter link, etc.
The extra fields can be used to filter and view reports for users, and are especially
useful in defining dynamic Audiences.
The “Extend Profile” section displays a tabular listing of all defined extended
profile fields, and allows you to edit or delete an existing field or add a new one.
On the form that shows you have to add a name for the field (how it will be stored
in the system) and an assorted Label (how it will be shown in the user interface).
Besides those two mandatory fields, there are several more options to set:
- A placeholder text (that will be shown inside the text-entry box to tell the
user what the field is about, e.g. “Insert a telephone number here” for a
telephone field).
28
- A field rule, which is a regular expression to validate that the entered
value is correct (a regular expression is a kind of computer code that
can match specific types of text, e.g. web addresses, email addresses,
numbers, alphanumeric sequences, etc.).
- Finally, you can specify the type of the field, with options being a simple
text box (the default, suitable for things like names, descriptions,
addresses and generally any free from text), a yes/no checkbox (e.g.
“Speaks english”), or a dropdown to choose among a list of items (e.g.
“male” or “female”).
29
Languages
The Languages section simply lists the available languages that can be used for
your e-learning content, and allows you to edit a language’s automatic
translations for words in the original to the target language and toggle the
language active or inactive.
30
Reports
Reports in eFrontPro are visualizations of interesting data regarding the system,
the courses and the users.
eFrontPro comes with a variety of pre-defined reports. Upon entering the Reports
section, in the “Systems” tab you’ll see an overview of "events" and activity for
the current day. You can adjust the reference period to yesterday, week, month
and year or set a custom date range.
Other tabs contain reports about Users, Courses, Tests, as well as a “Timeline”
listing of all user actions.
Depending on the report type, you can filter the data based on Branch, User
type, Audience, Group, Job, Skill, etc.
To learn more about how reports enable you perform changes to multiple
viewed items at once, visit the How to work with Mass Actions section.
There will be different options depending on the current view (Users, Courses,
Tests, etc.), but the functionality is the same. You select and set a list of criteria,
and you filter (“narrow down”) the list of items shown based on whether those
criteria match your filters.
31
For example the default Users tab on the Reports section, displays the list of all
Users.
To see just Users from a specific Branch that also belong to a specific Group,
open the Filter panel, and select the Branch and Group (leave the other options
in their default values), then click “Submit”.
The list will be recalculated to display only the Users matching the criteria you
have set in your filter.
You’ll see grey tags next to the “Filter” button, showing what filters are currently
active. Click on the “X” of a filter tag to de-activate this filter, or the single “X” next
to the filter button to discard all active filters.
32
Maintenance
The Maintenance section has some infrequently used items, such as buttons to
import data from CSV (e.g. to transfer users, courses, branches etc from another
system or database), to enter your registration key for eFrontPro (so you can
activate the product and receive updates) and to see the web server’s and
PHP’s status.
You have the option to merge or ignore entries already existing on the system
(duplicates).
Registration
Here you can enter and view your license key, and related details about your
installation (version number, activation date, expiration date, etc).
Information
Displays information about your installation environment (OS, PHP settings,
database, file system permissions, etc.), the PHP-Info table (a PHP diagnostic
tool that displays all PHP related information), and information about the system
cache.
33
Discussions
The Discussions section shows a list of all available “discussions” (eFrontPro lingo
for a simplified discussion forum) and the number of discussion topics (or threads)
that each contains.
For each discussion you can view and delete its topics, and add new ones. To
add a new topic for a discussion click the “Start new discussion” button and enter
its title.
Archive
The “Archive” is eFrontPro’s “recycle bin”, allowing you to see deleted Users,
Lessons and Courses and permanently delete them or restore them.
Plugins
Plugins are packaged pieces of functionality that extend eFrontPro’s
capabilities. An example would be the “LandingPage” plugin, that adds the
ability to show a custom introductory front-page to the user after he signs in.
The Plugins section shows a tabular listing of the installed plugins, and allows the
user to view their description, configure them, delete them or export them. It also
provides the option to install a new plugin or update an existing one.
To install a new plugin you click the “Install plugin” button, and specify the plugin
installation file and whether it should overwrite (upgrade) any existing plugin with
the same name.
34
To learn more about installing, editing and even creating your own plugins, visit
the Appendix 1: eFrontPro Plugin Guide.
eCommerce
The eCommerce section is divided in several sub-sections allowing you to
configure and manage your paid-for courses.
The “Price Tracks” sub-section allows you to set special offers such as discounts
and premiums for specific date ranges and specific Courses, Sessions, Audiences
and Branches.
The “Booked Seats” sub-section allows you to set the number of pre-made
bookings for a session (for sessions with limited seat availability).
The “Balance” sub-section shows a tabular listing of the balance of your students
(i.e how much money they have left to purchase lessons and sessions).
The “Settings” sub-section allows you to configure all the aspects of your
commercial e-learning offering, such as the currency used, the payment
gateway etc.
35
System Settings
The System Settings section allows the administrator (or a user with suitable
permissions) to configure all aspects of the system’s operation.
The Settings section is divided into several sub-sections, which are as follows:
The “Identity” sub-section allows you to define the site’s identity (URL, motto, title
etc.).
The “Locale” sub-section lets you set the locale, default language and time zone
of your service.
The “Logo” sub-section allows you to upload a logo to brand your LMS platform.
The “Limits & Debug” sub-section allows you to set some esoteric PHP options.
The “Security” sub-section allows you to control access to the service (e.g. by IP),
define password length and format policy, etc.
The “Users” sub-section allows you to toggle the ability for Users to self sign-up, to
setup a license note to display on the site, toggle mapped accounts, and set
the username format.
The “Email” sub-section allows you to configure the SMTP server for sending
emails (such as notifications).
The “Payments” sub-section allows you configure course payments (set the
currency, base price, cancellation policy, etc) as well as setup the payment
gateway (currently only PayPal is supported).
36
Instructor
Dashboard
The instructor dashboard is divided in two columns. The main column on the left
displays a listing of all the courses you own as Instructor (*), and allows you to
view, edit or view reports for any of them. Note that when you add a course you
become its owner, and you can still manage a course you have created even if
you stop being an Instructor for it.
The right column shows you your profile picture, a calendar with upcoming items
highlighted, and a Tools palette.
The tools palette contains links to add your Group Key, see the full Course
Catalog, manage Discussions and view Courses. If you have plugins installed, this
is the place they install icons that let you configure them.
(*) If you also have courses assigned to you as a Learner, they won’t be shown
on this screen unless you switch to Learner mode. This allows you to experience
how your courses look and feel like when accessed from your students.
37
Course screen
The course screen (shown after you right click and select “Edit Course” on any
of the courses you own) includes a variety of tools to manage your courses.
From the “Properties” tab you can change the course’s settings, such as name,
avatar, category, type and description. There are more options that can be set
for a course if you click to open the “Advanced Settings”, such as its price (if you
want it to be a paid course), whether the course will offer a certification to those
who have completed it (as well as the certification’s duration), the intended
audience and language, and the branch (department) that offers it. A course
code can also be set to help users quickly and uniquely identify the course.
The Lessons tab displays a listing of the lessons contained in the course, and
allows the user to create new lessons assigned to the course, set the lesson order
and configure whether or not the students have to complete lessons in order
(“Serial rule enabled/disabled”). The lesson list can be downloaded as an Excel-
compatible CSV file.
The Users tab displays a listing of the users associated in the course, as either
Professors or Students and their registration date. For each student, the Users
listing also displays his course completion date, what his score was and whether
he was awarded a certificate. This information can be downloaded as an Excel-
compatible CSV file.
Finally, the Skills tab shows a listing of skills associated with the selected course.
A “skill” describes a specific knowledge or experience that is either Offered by
the course (meaning that students who complete the course are assigned that
skill) or “Required” by the course (meaning that students need to have that skill,
perhaps by completing another course offering it, in order to take the course).
The listing of skills can be downloaded as an Excel-compatible CSV file.
38
Lesson screen
The Lesson screen is shown when you click on a specific lesson shown under a
course you own, or click the arrow icon (“take to lesson”) in the Lessons’ listing.
In this screen you can see the lesson’s content as well as an “Options” panel,
with tools allowing you to add more Content, manage Tests and Completion
Conditions, upload Files, monitor Attendance and Progress, and configure
several other lesson settings.
eFrontPro supports a number of different content types such as Text, URLs and
Files. To add a new content unit, you click on the “Add Unit” button, and enter
a name, the content’s source (e.g written on your own in the editor or taken from
a URL), and content.
If you are uploading a file, the system will detect its type and present it in the best
possible way. For example, images will display embedded, videos in a video
player etc. SCORM 1.2 files will be directly imported and made ready for delivery.
You can also set a completion method, such as “button” (the lesson is
considered “read” by the student after he clicks a button), “time” (the lesson is
considered “read” by the student after some specific time has passed), or
“automatic”.
39
The “Tests” sub-section shows you a listing of existing tests, and allows you to edit
and delete them, or add new ones. To add a test you have to click on the “Add
test” button and specify a name and an optional short description.
You can set a number of advanced settings for a test, such as:
2) Mastery score: An end user needs to get this minimum to pass the Test.
6) Submit action: In this option you can define what it happens when the test is
submitted and graded.
The “Questions” tab lists all existing questions you can re-use on your tests, and
allows you to define new ones. A test question can be one of the following types:
1) Empty Spaces (the student has to fill in the missing words in a phrase).
2) Free Text / File Upload (the student uploads a file, e.g an essay in .doc format,
which will be manually graded later). This type of question can also be
automatically graded based on the presence of specific keywords (that
denote correct answers) in the text.
40
4) Match (the student must match related items)
A newly added option for test questions is the “random” type enabling you to
create randomized tests.
You can add as many as you want to the pool, and you get to specify how many
questions you want displayed when the “random question” entry is added to a
test.
For example, if you have added 20 questions to a “random question” entry and
you have specified 3 of them to be shown, a user taking a test containing that
random question entry will have to answer 3 questions randomly selected
among those 20.
41
4) Completed a fraction of the units
You are allowed to mix and match conditions, e.g include several conditions
requiring different specific units, and even specify if all the conditions should be
met (AND) or just some of them (OR).
The “Files” sub-section allows you to upload files such as Word, PowerPoint, PDF,
audio and video items for the lesson’s content.
Finally, the “Administration” sub-section allows you to set various properties of the
lesson, such as calendar notifications, adjust its content tree and order, and the
toggle the ability to read it when offline.
Group key
The Group key sub-section allows you to enter the group key you have been
given to automatically subscribe to your group and be assigned any classes set
for that group.
Course catalog
The course catalog displays a listing of all the existing courses (as opposed to just
the ones you own or manage). A blue badge is shown to mark courses you own.
42
43
Discussions
The Discussions section shows a list of all available “discussions” (eFrontPro lingo
for a simplified discussion forum) and the number of discussion topics (or threads)
that each contains.
For each discussion you can view and delete its topics and add new ones. To
add a new topic for a discussion click the “Start new discussion” button and enter
its title and a short message to be shown to participants.
Courses
The Courses section (selectable from the Options box on the right) allows you to
see all courses you manage in a tabular listing with buttons to edit or delete a
specific course, and contains a search box for quickly finding the course you
want to view or edit.
After selecting a course, you can view or edit its Properties, Lessons, Users and
Skills, through the respective tabs, with the same behavior as described above
for the “Course screen”.
44
Learner
My courses
Your dashboard includes an overview of the courses you’re taking. Courses you
have completed are marked as such, and display a certification badge if you
have been awarded any certifications for their completion.
Course view
When you select a course you go directly to the course view mode and have
the option to start it (if it’s the first time you open it) or resume from the last seen
unit.
45
A progress bar in the “Content” block displays your overall progress within the
course.
You can complete a course/lesson’s “units” via various actions; including clicking
on a “complete course” button, answering a question or spending a minimum
elapsed time. Depending on the traversal rules set for course might necessitate
to complete units in a serial order. Each course has a course completion rule
(e.g., complete a specific test or complete all units). When you complete a
course a popup will appear with your options for the next step, which may
include proceeding to the next course or download a certification.
Course catalog
The course catalog displays a listing of all the existing courses (as opposed to just
the ones you are subscribed to). A blue badge is shown to mark courses you’re
talking.
Discussions
The Discussions section shows a list of all available “discussions” (eFrontPro lingo
for a simplified discussion forum) and the number of discussion topics (or threads)
that each contains.
For each discussion you can view and delete its topics and add new ones. To
add a new topic for a discussion click the “Start new discussion” button and enter
its title.
46
Generic
In this section we’re going to describe some common UI elements shown to all
user types.
Personal info
From the header you have direct access to your account and the status of your
learning.
From the drop-down list showing your account name you can edit your account
information, see your progress reports, your e-commerce transactions and
balance, and view/edit/add any mapped accounts you might had
Depending on the type of your account you may also have options to switch
between different user modes; these can include the Administrator, the Instructor
and the Learner.
Messages
You can send private messages to other users using the Messages function. The
recipients can be specific users or users involved to specific courses, groups or
branches.
The administrator can communicate with every group and branch of the system,
while a simple user can communicate only with users that share common groups,
branches, courses etc. This behavior is controllable from the user-types (available
only to admins).
The Messages section displays your Incoming messages along with their status,
as well as a second tab (“Sent”) with a list of messages you have send.
To send a new message go to the Messages section and click the “+ New
Message” button, or click the “Messages -> Compose” menu on the top header
bar.
47
You have to specify the recipient (which can be multiple users, and even whole
Courses or Groups, if you are allowed to message them), the subject that will be
shown, and enter your message.
You are also allowed to include an attachment in your message (e.g. to send
some supplementary course material to some student, or your homework to your
instructor).
48
Search
The search box allows you to quickly find relevant courses, lessons, messages and
more.
Search suggestions are autocompleted against the available LMS content, and
are grouped depending on their type.
When you hit ENTER having selected a suggestion entry, you’re taken directly to
Logout
Ends your current session and logs you out of eFrontPro.
49
Technical Topics
Hardware Requirements
There are no limits on the type of hardware used to host an eFrontPro installation.
However, as your needs grow, so will the need for additional resources. A simple
eFrontPro installation requires about 50M of free disk space and 64M of free
system memory. However, a minimum of 128M free memory available to PHP is
recommended. Disk space should be allocated according to usage
Software Requirements
50
duration of the installation (in order for the configuration file to be
created)
51
Upgrading
Upgrading eFrontPro is easy and does not require any special action, nor incurs
any downtime
2. Extract on top of your current installation, making sure that existing files
are replaced.
52
System Architecture
eFrontPro is a client-server web application, designed to be delivered in a
browser using the HTTP protocol. The client side is implemented using HTML,
Javascript and CSS, and the server side is mainly written in PHP.
The server-side architecture follows the MVC pattern, which imposes a 3-way
division of the application logic: The Model represents real-world entities and
relationships; The View implements the user interface of the application; and the
Controller binds user interactions with models to perform operations.
All data are stored inside a RDBMS system. The platform communicates with it
using a Data Abstraction Library called Adodb.
53
54
How to secure your environment
However, no application can ever be 100% secure. The following tips will help
you keep your environment safe:
Remove write access for the web server for any files and folders that the
system does not require write access to. See Maintenance for a list
Make sure that the system where your web and database servers are
installed is always up-to-date. Use the latest release of a PHP version that
is supported.
55
Performance Tips
eFrontPro is designed to deliver fast performance and scale graciously with
increasing load. However, there are a few tips that can moderately or greatly
increase performance:
2. Enabling Mysql Query Cache will reduce the load on the Mysql Server and
consequently the time it takes to serve a request. In order to see whether
mysql query cache is enabled, visit the Maintenance page.
56
How to create a Theme
eFrontPro's look and feel is based on Bootstrap 3, but can be customized by using custom
themes. All installations come with a collection of pre-installed themes, available to use or
customize to anyone's needs. Theme customization is solely based on the use of CSS and
optionally Javascript code. Below we will share some tips on how to quickly put together a
theme that is suitable for your use case.
body {
background-image:url('https://c626fd9a3ea7d7aaf25a-
13df01e1540c03f09828a4c08555f8b9.ssl.cf2.rackcdn.com/back13.jpg');
opacity:0.9;
background-size:cover;
}
Increase or decrease the opacity to determine how opaque your background will appear.
Customizing Fonts
Set a font-family style to your body element, to change the font used throughout the platform:
57
Changing Blocks
Blocks are the main container element used throughout the system and you can customize
any aspect you wish. Below you can find some basic examples:
/*Box Titles*/
div.block .title {
background:#FFF;
border: 4px solid #ccc;
border-bottom: 0px;
position: relative;
top: 8px;
}
/*Box Content*/
div.block .content {
border: 4px solid #ccc;
box-shadow: 0 1px 1px rgba(0,0,0,0); /*shadow*/
border-radius: 8px;
}
Changing Grids
Grids are the tables listing users, courses etc. You can customize their look and feel via css
using classes similar to the example below:
58
/*Grid table*/
table.sortedTable {
background-color:#d9e5aa;
top: 2px;
border-radius:4px;
}
/*Odd rows*/
tr.oddRowColor {
background: #e9f5ca;
border-bottom: 1px solid #D0D0D0;
border-top: 1px solid #D0D0D0;
}
/*Even rows*/
tr.evenRowColor {
background: #edf9da;
}
/*Grid footer*/
td.sortedTableFooter {
background-color:#d9e5aa;
}
59
}
/*Breadcrumb separator*/
.breadcrumb > li + li:before { color: #000; content: "\003e"; }
Changing buttons
Most of the buttons in the system bear the “primary” class, thus you can alter them as follows:
60
How to customize Certifications
It is important to have a well designed appealing certificate. In this section, we will figure out
how to draw lines, display pictures, set background image and insert fields within the
certificate.
The example XML schema below specifies where elements of the certificate will appear.
Next we will look at each of the elements and explain their properties.
61
<label text="Serial Number" font="Freeserif" weight="" size="10"
color="#000000" x="110" y="192"></label>
<label text="Date" font="Freeserif" weight="" size="10"
color="#000000" x="200" y="192"></label>
</labels>
<lines>
<line x1="5" y1="5" x2="292" y2="5" color="#005b7f" thickness="2"
note="Top Thick"></line>
<line x1="292" y1="5" x2="292" y2="204" color="#005b7f"
thickness="2" note="Right Thick"></line>
<line x1="5" y1="204" x2="292" y2="204" color="#005b7f"
thickness="2" note="Bottom Thick"></line>
<line x1="5" y1="5" x2="5" y2="204" color="#005b7f" thickness="2"
note="Left Thick"></line>
<line x1="7" y1="7" x2="290" y2="7" color="#005b7f" thickness=".25"
note="Top Thin Border"></line>
<line x1="290" y1="7" x2="290" y2="202" color="#005b7f"
thickness=".25" note="Right Thin Border"></line>
<line x1="7" y1="202" x2="290" y2="202" color="#005b7f"
thickness=".25" note="Bottom Thin Border"></line>
<line x1="7" y1="7" x2="7" y2="202" color="#005b7f" thickness=".25"
note="Left Thin"></line>
<line x1="17" y1="190" x2="97" y2="190" color="#000000"
thickness=".25" note="Signature Line"></line>
<line x1="107" y1="190" x2="187" y2="190" color="#000000"
thickness=".25" note="Serial Line"></line>
<line x1="197" y1="190" x2="277" y2="190" color="#000000"
thickness=".25" note="Date Line"></line>
</lines>
<images>
<image file="certificate.gif" x="238" y="14"></image>
<image file="signature.gif" x="18" y="176"></image>
</images>
</certificate>
</certificates>
creator: is used to populate the creator for the PDF document header (it does not
appear on the document).
author: is used to populate the author for the PDF document header (it does not
appear on the document).
subject: is used to populate the subject for the PDF document header (it does not
appear on the document).
keywords: is used to populate the list of keywords for the PDF document header (they
do not appear on the document).
organization: is used to display the organization name on the certificate.
student: is used to display the name of the student on the certificate.
62
course: is used to display the name of the course on the certificate.
grade: is used to display the overall grade of the course on the certificate.
date: is used to display the date the certificate was issued.
serial: is used to display the serial number of the certificate.
logo: is used to display the logo image on the certificate. You can either display the
default logo of your eFront installation or an external image, by supplying its URL.
background: is used to display a background image on the certificate. The
medium.png file corresponds to the background image of the Medium Decoration
template. Also, the heavy.png file corresponds to the background image of the Heavy
Decoration template. Apart from these background images you can display an external
image, by supplying its URL. Image width should be equal to 840 pixels.
orientation: is used to define the page orientation.
label: a label is a line of text that will appear on the certificate. A label element must
appear within the labels section. You can add any number of labels as needed.
line: a line is a graphical line that is drawn on the certificate. A line element must
appear within the lines section. You can add any number of lines as needed.
image: an image is a graphic that will appear on the certificate. An image must appear
within the images section. You can add any number of images as needed.
Properties for student, course, grade, date, serial and organization elements
Property Description
font Name of the font to use.
weight The font weight. Possible values: bold, italic, bold|italic. For normal font, leave the value
empty.
size Size of the font to use.
color Hex value for text color (i.e: #000000 is black).
x X coordinate.
y Y coordinate.
align The text alignment. Possible values: center, left, right.
text Text to appear on the certificate. It applies only on the organization element.
Property Description
name The value that will appear in the PDF document header.
63
Properties for image, logo and background elements
Property Description
file Name of the image to use or the URL of an external image.
x X coordinate. It applies only on the image and logo elements.
y Y coordinate. It applies only on the image and logo elements.
Property Description
name The page orientation. Possible values: landscape, portrait.
Property Description
text Text to appear on the certificate.
font Name of the font to use.
size Size of the font to use.
weight The font weight. Possible values: bold, italic, bold|italic. For normal font, leave the value
empty.
color Hex value for text color (i.e: #000000 is black).
x X coordinate.
y Y coordinate.
Properties for line elements
Property
color Hex value for line color (i.e: #000000 is black).
note A note for user reference. It does not appear on the document.
thickness The line thickness (i.e: Thin: .25, Thick: 2).
x1 Starting X coordinate.
x2 Ending X coordinate.
y1 Starting Y coordinate.
y2 Ending Y coordinate.
Templates with two or more pages In case you would like to have a certificate with more
than one page you should include each page within a <certificate> tag. You should include
all the properties for creator, author, subject and keywords within your first <certificate> tag
64
and you do not need to repeat them again in your second (or third…etc) <certificate> tag.
For example
65
Frequent Questions
You could of course do all those changes manually, one by one, but eFrontPro
provides powerful tools to automate your workflow.
The most common use cases for this would be assigning a set of courses to new
users when starting a new e-learning program (e.g. at the start of a semester).
To automate this action, as with many student related actions, you can use
eFrontPro’s “groups” functionality.
As discussed in the relevant section, groups help you organize users into logical
sets, allowing you to treat all of them as a single entity. Actions performed to the
group can be applied by eFrontPro to each and every member of the group.
Specifically, a group comes with mass actions to synchronize its users with its
courses.
Let’s walk through the mass assignment of a set of courses to a number of users.
(1) In the eFrontPro UI, click to visit the Groups section. A tabular listing of all
existing groups will be shown, along with an “Add Group” button allowing you to
add a new group.
(2) Click to add a new group. Enter a name for the group (e.g. “class of 2015”)
and optionally select a branch the group will belong to or enter a short
description.
(3) Click to save your new group, and select the newly created group. There are
links to see the list of Users and Courses assigned to it. Begin by assigning the users
you want to the group. Then assign a number of courses to the group.
(4) The final step is to click to enroll all of the group’s users to the group’s courses
(eFrontPro doesn’t perform this automatically behind your back, to give you the
ultimate flexibility to handle it however you like).
Voila: the group’s users are now enrolled to the specified courses without you
having to manually assign each user.
66
How to offer Compliance Training
When a business operates within certain markets or competes for public sector
tenders, compliance with industry standards, laws and regulations is often
necessary. eFrontPro is a great tool for implementing compliance training for
your employees (or even the general public).
In their essence compliance training courses are similar to all other courses. The
main difference is that their content is detailed and outlined exhaustingly in the
relevant standards and laws, and thus they result in a very specific “skill” or
“knowledge set”. You can model this kind of learning in eFrontPro using
certifications.
The way this feature works is that the user sets an (optional) duration for the
certificate (e.g. 6 months), and eFrontPro automatically expires the certificate
after that interval passes.
You can even indicate that you want to reassign the course that the certificate
was assigned from, upon its expiration, or N days prior to expiration, and have
eFrontPro re-enroll the students automatically. When that happens, the course’s
progress for those users is reset, and they have to complete it again to get re-
certified.
From the Certificates section eFrontPro admins can view and edit any defined
certificate templates, and dig in to view the details for each and the courses
67
that award it. (To learn mode about creating and editing certificates, check
the How to customize Certifications chapter).
In the same section, the Users tab displays a listing of all certificates awarded to
your users, the courses they were awarded for and their expiration status.
eFrontPro admins can filter down the user listing and view, edit, and revoke any
particular certification they wish.
68
How to customize your learning portal
Branding is an important part of any modern business and eFrontPro was created
with theming and customizability built-in, making it easy to add your own logo,
favicon, custom theme and even custom javascript in your eFrontPro based
learning portal.
To begin customizing eFrontPro, login with an admin account and visit the
“Identity” section, where you can set your custom domain, as well a your site’s
motto.
Next comes the “Appearance” tab. From there you can start by picking a logo
and favicon from your computer.
It is advisable that the logo is 72 pixels high, while width can be up to 500px, and
that it’s selected to match your header color. As for the favicon (the small icon
that represent your page in the browser taskbar or bookmarks listings), it has to
be square, and will be displayed in a 16x16 resolution by most browsers.
Custom theme settings have their own section, aptly named “Themes”.
In the Themes page you can see the visual layout of eFrontPro, and drag and
drop page building blocks (such as the Catalog, the Sign in panel, etc.) to create
the layout you want. You can also add your own custom blocks to the layout,
e.g. a panel displaying a welcome message, ads, custom widgets, etc.
For ultimate flexibility, eFrontPro allows you to define a custom layout of each
branch of your e-learning service.
Themes sit on top of a layout, and define the various colors, fonts, backgrounds
etc. that the layout is displayed in (if you’re confused think of it like this: the layout
defines the structure of your site – where things are -, whereas themes define its
You can select between several pre-defined themes or install a new one (even
one that you have created) from the “Change Theme” tab. From the themes
listing you can set the active theme, preview themes, and even edit any theme
(a theme being a set of CSS and JS instructions).
69
How to customize the communication emails
In an e-learning environment that lacks the immediacy of physical interaction,
proper and fast communication becomes profoundly important.
In this area too, eFrontPro has you covered, with automated notifications for any
kind of event (user registration, grades posted, etc.), as well as custom on-
demand messages to any user or group.
Notifications are sent to their recipients as emails, which means that any web,
desktop or mobile mail client can be used to read them.
To create a notification, visit the Notifications section. In there you’ll see a list of
Clicking on “Add Notification” will display a form that you have to fill in to create
a new notification. You get to select the specific event that will trigger the
notification, the recipients (which can be individual users, administrators, course
professors, etc.), the exact time to send the notification when the event is
triggered, an optional branch, a subject (title), and finally the body of the
notification, which is the message that will be shown to the recipients.
1) Select an Event that will trigger the notification. We select “User Completed
Course”.
4) We select the course that this notification will apply to. For example, “History
101”.
6) We add the message we want the recipient to see. We have the option to
create different messages for each language group (English, French, etc
70
students) and to use keywords that will be automatically filled in by the LMS, such
as the date/time, the recipients name, etc.
Let’s write a simple message, such as “Student … completed the course, …., at
….”. To fill-in the blacks, click the buttons below the body field, and automatically
replaceable keywords will be inserted. E.g. clicking the “User’s full name” button
inserts the {user_name} keyword in the notification body. This will be replaced by
the actual student’s name in the message that will be send for each individual
user that completes this course.
This works the same as Work / Excel’s “mail merge” function, in case you’re familiar
with that.
71
What is the difference between Branches and Groups
eFrontPro was designed to offer many ways to customize its operation to cater
how different organizations and businesses operate. To keep all this
customization power simple, we based it on a few key organizational entities,
such as Branches and Groups.
While Branches and Groups might look similar, they serve different purposes and
roles within eFrontPro.
Groups organize users into logical entities, allowing them to treat all of them as a
single entity. You can communicate to the members of a group directly, assign
them courses, and see aggregate reports on all of them. Groups also come with
mass actions to synchronize their users with their courses.
You create groups based on any criteria you like, e.g. “Medical Students”, “Class
of 2015”, etc., and you can assign students and courses to them.
Branches on the other hand allow you to divide your e-learning offering into
different logical units (or “departments”), each with its own courses, users,
professors and branding (sub-domain, theme, logo, etc.). Branches can be a flat
list or form a nested hierarchy.
Branches are a much larger logical entity than groups (a group can belong to a
branch, but not vice versa), and might be overkill for smaller deployments, but
are a good way to separate and customize your e –learning offering for different
company departments, units, geographical sections, etc.
72
How to work with Mass Actions
Mass actions allow you to eliminate repetitive work by automating tasks to be
performed to multiple users (e.g. to all members of a group).
It’s in enabling mass actions that eFrontPro’s organizational units (from groups
and branches to courses and skills) are especially helpful.
Mass actions can be easily accessed from the Reports section, in the “Mass
Actions” dropdown that appears in the Users tab.
To apply a Mass Action, first select the users you want to have it applied. The
default listing in the Users tab shows all Users, but you can narrow it down using
the filter function to select users of a specific Type, Group, Job, Skill, Audience or
Branch.
When you have selected the users you want, you can apply any of the several
mass actions available:
- Deactivate
- Activate
Depending on the action, you will be asked to select a course or group to add
the users to, or to confirm that you want it to go throu.
You can also use mass actions outside of the Reports page. Specifically, mass
action buttons at the Group and Curriculum pages allow you to:
curriculums”)
73
How eFrontPro supports Instructor Led Training
We designed eFrontPro as a multi-paradigm LMS, that is, to be able t adapt to
the way you work. It can adapt to small and big teams, local units and
geographically dispersed branches, hybrid remote and classroom-based
learning and to lots of other use cases. One of its core characteristics though is
its support for Instructor Led Training.
eFrontPro allows for Instructor Led Training and blended learning through its
introduction of the classroom (ILT) course type that takes place in the physical
world but is organized and moderated online. Such a classroom course can
have limited seats, waitlists, meetings and multiple sessions.
Other tools available in eFrontPro that facilitate Instructor Led Training include:
- The instructor user type and related dashboard, that allows instructors to control
their courses and add and edit lessons, tests and multimedia material on the fly.
- Discussions, the eFrontPro forum system, which allows instructors and students
to discuss, collaborate and provide feedback on their courses.
- Reports, which give instructors an overview of how their students are doing and
allow them to perform mass actions pertaining to student groups.
74
How eFrontPro deals with WCAG, Section 508 & ADA
Compliance
According to the Section 508 technical standards a web site has to satisfy
sixteen specific items for web accessibility. These are specific things that can be
done during web site development to ensure that a person who is mobility
impaired or blind, for example, can use your site.
508 standards have drawn on the work of the Web Accessibility Initiative (WAI)
of the World Wide Web Consortium (W3C) that has crafted a set of Web
Content Accessibility Guidelines (WCAG). The WCAG guidelines are grouped
by priority and are very similar to those in the final Section 508 rule. The
Americans with Disabilities Act (ADA), which became law in 1990 is a civil rights
law that prohibits discrimination against people with disabilities. The ADA
generally requires employers, state and local governments and places of
public accommodation to offer reasonable services or tools to insure that
people are not discriminated against on the basis of disability.
Note that there are no related certifications for web-sites and services since
there is no way to make a site 100% compatible with WCAG-2 without
restricting it too much. We can however, reach a level of conformance.
1/ Text Alternatives: Provide text alternatives for any non-text content so that it
can be changed into other forms people need, such as large print, braille,
speech, symbols or simpler language.
4/ Distinguishable: Make it easier for users to see and hear content including
separating foreground from background.
6/ Enough Time: Provide users enough time to read and use content.
75
7/ Seizures: Do not design content in a way that is known to cause seizures.
8/ Navigable: Provide ways to help users navigate, find content, and determine
where they are.
10/ Predictable: Make Web pages appear and operate in predictable ways.
12/ Compatible: Maximize compatibility with current and future user agents,
including assistive technologies.
There are 3 elements that play a role on whether a web platform can meet
those requirements:
- The LMS software. eFrontPro has taken into its design the above requirements
and makes sure that it meets them as good as possible. For example, we offer
alternatives for all images (alt tags), we make no-use of iframes / Java or Flash
and we do not use strictly colors to convey information. We also offer a
consistent navigation to make the system predictable.
76
How to integrate eFrontPro with your system
eFrontPRO provides a comprehensive REST JSON API that allows interaction
with remote services. Authentication is based on an API key that is defined
under your installation’s system settings. The functionality provided focuses on
performing tasks meaningful for a remote service, such as user creation, course
assignment, listing courses etc. In addition, one can use the API to provide
basic SSO for users.
You can download the eFrontPro SDK and read the related documentation on
GitHub.
77
How to work with content conversions
eFrontPro integrates with the EncodeMagic service to offer seamless,
automatic conversions of various file types to a web-friendly format, ensuring
that content delivery and compatibility is optimal across a multitude of devices.
Currently most video and audio types are supported, as well as Powerpoint
(.ppt) presentations.
In order to setup the service, you must first obtain an API key and secret from
your vendor. Once you have these, then visit the System settings page, click on
Integrations→EncodeMagic and input this information.
That's it! Next time you upload a video, audio, or document file, it will be sent to
Encode Magic, transcoded on the fly and delivered back to the system. The
whole process usually takes a few minutes, during which the unit will be in a
waiting state. Once it's done, you can visit your content and see the converted
file in action.
78
How to work with Videoconferencing
Discuss the offered video conferencing integrations and how they work
79
Appendix 1: eFrontPro Plugin Guide
Quick start
Can’t wait to start creating a plugin? Read on for a very quick walkthrough on how to put
together a simple plugin in just a few minutes:
1. Make sure you have a working eFrontPro installation, and you have access to its files
(with permission to change them). See Installation for instructions on how to install
eFrontPro.
2. Visit your eFrontPro system, sign in as an administrator and click on Plugins.
3. Click on the Create plugin button. Enter a name1), title and description for your
plugin, for example:
name: AcmeReports
title: Acme Reports
description: This is a fully-functional plugin that is created as part of eFrontPro's
plugin guide.
Now click on Save. You will be redirected to the new plugin’s main page (which is
empty). The “Acme reports” plugin will be visible in the plugins list, where you can
deactivate or delete it.
4. The plugin has been created inside the server that hosts eFrontPro. You can find its
files at the same location where eFrontPro is installed on the disk, under
the path www/plugins/AcmeReports. You have to gain access to these files, in
order to change them according to your needs. You can either:
Access the files directly on the server, if you have access, and edit them directly.
Under admin→plugins, click on the download link next to the “AcmeReports”
entry, to download a zip file containing your files. You can then change them at
your local environment; once you’re done, compress them into a zip file and click
on the upgrade icon next to the entry.
Read on for a step-by-step walkthrough on how to create a general-purpose plugin.
Introduction
Creating a plugin can be a simple or complicated process, based on your requirements. We’ll
try to make your life as easy as possible, regardless of whether you’re an experienced or a
new developer. The following guide assumes you have some very basic knowledge of PHP
5. You will also need a working eFrontPro installation. If you don’t have one,
see Installationfor instructions on how to install it. If you don’t have access to a working
eFrontPro installation for development purposes,contact us.
80
Reports on the total number of users, courses and certificates
Presents a list of users that have not used the system recently
Presents a list of users that have not completed a specific course
Emails the list to a specified user
Allows saving and retrieving past reports
Scaffolding
Plugins are always located under the www/plugins folder of your eFrontPro installation. In
general, a plugin can have any file structure its creator wants, but it’s highly recommended
that you follow this structure:
www/plugins/
---- AcmeReports
-------- assets/
------------ images/
---------------- plug.svg
------------ AcmeReportsController.php
-------- i18n/
------------ en_US/
---------------- LC_MESSAGES/
-------- Model/
------------ AcmeReports.php
------------ AcmeReportsPlugin.php
-------- View/
------------ acmeReports.tpl
-------- plugin.ini
Heads up! Don’t bother with creating all these folders and files by hand; Use the “Create
new plugin” option from admin→plugins to have the system create them for you.
Installing/Configuring
A plugin needs to include at a minimum 2 files, one for configuring it called plugin.ini,
and one for running it, called <name>Plugin.php(AcmeReportsPlugin.php in our
example)
Heads up! If you have used the “Create new plugin” button, the files described below are
already created for you, and the plugin is already installed. You can skip directly to Req. 1:
Reports on the total number of users, courses and certificates (but don’t, because it’s worth
reading nevertheless)
The file plugin.ini is used by the system to initialize the plugin. In our case, it should
contain the following:
81
[plugin]
class = Efront\Plugin\AcmeReports\Model\AcmeReportsPlugin
name = AcmeReports ;must match the path name under Plugins
title = Acme Report version = 1.0 ;The plugin version, change when
upgrade is needed
requires = 4.1.0 ;minimum supported eFrontPro version
compatibility = 4.1.0 ;maximum compatible eFrontPro version
author = John Doe
description = This is a fully-functional plugin that is created as part
of eFrontPro's plugin guide
where:
The file AcmeReportsPlugin.php serves as the glue between the core system and our
plugin. It extends the class AbstractPlugin and implements all functions defined in
the Plugin API. For now, we only need the bare minimum for this file, which is to implement
the 3 abstract functions of theAbstractPlugin class. Here is the contents it can have:
82
public function upgradePlugin() {}
}
Heads up! You always have to implement the 3 abstract functions shown above, even if
they’re left empty
That’s it! All we have to do now is to install the plugin into our eFrontPro system (if it’s not
already installed). This can be done with 2 ways:
Go to Admin → Plugins → Install new plugin, and click to install your plugin, which you
must have compressed as a zip file.
Note that you have to compress the files inside the plugin folder and not the folder itself
Or copy the plugin files directly to the www/plugins/ folder on the eFrontPro server.
Then go to Admin → plugins and the plugin will appear as “not installed” in the list.
Click on the “plus” icon next to it to install it.
After the plugin is installed successfully, it will display as such in the plugins list. Use the
handles provided to deactivate it, download its files or upload a new version of your plugin.
Capturing an event
Events are fired throughout the system multiple times during the execution of the script,
for example when a user is created, a course is deleted, etc. A plugin may listen for these
events to perform some action, via the onEvent() method. onEvent() is called for every
event that happens in the system, so the plugin must make sure it picks out the one that it is
interested in and ignores the rest. For example, to perform an action each time a user signs
in or signs out, we would implement onEvent() like this:
83
//perform an action for users that signed in
break;
case 'Efront\Model\Event\UserSignedout':
//perform an action for users that signed out
break;
default:
break;
}
}
For a complete list of available Events, see the Event Reference section.
$user = User::getCurrentUser()
Update an object:
Delete an object:
84
$user = new User(321);
$user->delete();
//Get the users that haven’t signed in for more than a month, order by
last_login column
Database::getInstance()->getTableData(
User::DATABASE_TABLE,
'id,name,surname,email',
'last_login<'.time()-86400,
'last_login'
);
Heads up! Although you can directly update data in the database table, it is strongly
discouraged to do so, because eFrontPro utilizes an automatic caching mechanism, and
directly changing the database will not update cached entries. Always
use $obj→setFields() to change an object’s properties and $obj→delete()to delete an
entry.
85
Setting access links and icons
Our plugin is now installed, but does nothing. Since this plugin will be used by administrators,
we will create a link to its page from the administrator’s dashboard. To do this, we employ
the Plugin API’s onLoadIconList() function, inside the AcmeReportsPlugin file:
Heads up! The […] symbol in any code snippets, refers to code created previously that is
present but has been omitted, for the sake of simplicity.
use Efront\Model\AbstractPlugin;
use Efront\Model\User;
use Efront\Controller\UrlhelperController;
The snippet above will make an icon appear in the Administrator’s dashboard.
For determining the current user’s type, see User types and restrictions
Each plugin can have a page of its own, for example under /AcmeReports.
See Creating URLs on how to define its link, using theURLHelperController class
Note the 2 use statements we put on top
There are a few “icon lists” like the administrator’s dashboard in the system. Each has its
own distinctive name, which you have to specify in an if clause when implementing
the onLoadIconList() function
86
Creating a dedicated page
Now that we have a link to our plugin’s page, it’s time to create the page itlself. For this, we
will need a few new files:
Model/AcmeReports.php,
Controller/AcmeReportsController.php
View/acmereports.tpl
First, we will create a model class, that will hold the bulk of our implementation. For now,
we’ll leave it to the bare minimum:
Now, we need to tell the system that every time the plugin page is requested, its controller
will be loaded. To do this, we implement the onCtg() method in
ourAcmeReportsPlugin class:
if ($ctg == $this->plugin->name) {
BaseController::getSmartyInstance()
->assign("T_CTG", 'plugin')
->assign("T_PLUGIN_FILE",
$this>plugin_dir.'/View/AcmeReports.tpl');
87
}
}
onCtg() is called whenever we need to decide where to route a request. $ctg always
contains the first part of the request URL. For example, if our installation is installed
on http://efrontpro.example.com/ and we request http://efrontpro.example.com/foo,
then $ctg will contain ‘foo’. This determines which controller will take effect. In our case, the
controller used is AcmeReports, so the icon link we created earlier points to /AcmeReports.
Our onCtg()implementation ensures that AcmeReportsController is invoked, and that the
proper view file, AcmeReports.tpl will be used.
Heads up! If you use a name of a controller that already exists, the system will never reach
it, since plugins are checked after all controllers have failed to initialize.
Now that we have a target for our link, let’s create the controller itself, which must extend
the BaseController class:
$smarty->assign("T_PLUGIN_TITLE", $this->plugin->title)
->assign("T_PLUGIN_NAME", $this->plugin->name)
->assign("T_BASE_URL", $this->_base_url);
}
}
88
function called automatically by the system. Basecontroller includes an implementation
for index(), so if you don’t implement it, the parent’s will be invoked
The first line adds the “AcmeReports” part on the system’s breadcrumb (path) bar. The last
line prints a standard html div block, containing all the html markup defined inside the
referenced capture code. We will add more in our template right below, but see our 1-minute
introduction to smarty to get a quick idea of how smarty works.
Heads up! The plugin code, as it is created until now, can be found in Github,
as AcmeReports-initial
We are now ready to get down on implementing the actual logic of our plugin. As we
described earlier, Acme wants a plugin that:
Let’s create a triplet of functions that retrieve this information, inside our Model
class, AcmeReports.php:
use Efront\Model\BaseModel;
89
use Efront\Model\User;
use Efront\Model\Course;
use Efront\Model\UserCertificate;
Finally, we edit our template file, AcmeReports.tpl, to display these numbers inside some
pretty panels:
90
{eF_template_appendTitle title = $T_PLUGIN_TITLE link = $T_BASE_URL}
That’s it! Our plugin page now displays the totals we were requested to display:
Heads up! The plugin code, as it is created until now, can be found in Github,
as AcmeReports-step1
Req. 2: Presents a list of users that have not used the system recently
Lists are best presented using Data Grids, like those found in the system
under admin→users, admin→courses etc. To implement one, we are first going to create the
table in the view file:
91
<table style = "width:100%;" class = "sortedTable table" data-sort =
"last_login" size = "{$T_TABLE_SIZE}" id = "reportsTable" data-ajax =
"1" data-rows = "{$smarty.const.G_DEFAULT_TABLE_SIZE}" url =
"{$smarty.server.REQUEST_URI}">
<tr>
<td class = "topTitle"
name="formatted_name">{"User"|eF_translate}</td>
<td class = "topTitle" name = "last_login" data-order="desc">{"Last
login"|eF_translate}</td>
<td class = "topTitle noSort
centerAlign">{"Operations"|eF_translate}</td>
</tr>
{foreach name = 'users_list' key = 'key' item = 'user' from =
$T_DATA_SOURCE}
<tr class = "{cycle values = "oddRowColor, evenRowColor"} {if
!$user.active}text-danger{/if}" >
<td>{$user.formatted_name}</td>
<td>{$user.last_login}</td>
<td class = "centerAlign nowrap"> <img src =
'assets/images/transparent.gif' class = 'ajaxHandle icon-trafficlight_{if
$user.active == 1}green{else}red{/if} small ef-grid-toggle-active'
data-url = "{eF_template_url url = ['ctg'=>'users','toggle'=>$user.id]}"
alt = "{"Toggle"|eF_translate}" title = "{"Toggle"|eF_translate}">
</td>
</tr>
{foreachelse}
<tr class = "defaultRowHeight oddRowColor">
<td class = "emptyCategory" colspan = "100%">-</td>
</tr>
{/foreach}
</table>
</div> <!--/ajax:reportsTable-->
{/capture}
92
use Efront\Model\User;
$this->_listUsers(); }
else {
$total_users = $this->_model->getTotalUsers();
[...]
}
}
$entries = User::getAll($constraints);
$totalEntries = User::countAll($constraints);
$grid = new GridController($entries,
$totalEntries,
$_GET['ajax'], true
);
$grid->show();
} catch (\Exception $e) {
handleAjaxExceptions($e);
}
}
}
You can now see a list of all users, sorted by the last_login field. However, this field appears
as timestamp, rather than in a human-readable format. We’ll fix this in
the _listUsers() function of our controller:
93
protected function _listUsers() {
try {
$constraints = GridController::createConstraintsFromSortedTable();
$entries = User::getAll($constraints);
$total_entries = User::countAll($constraints);
foreach ($entries as $key=>$value) {
$entries[$key]['last_login'] =
formatTimestamp($entries[$key]['last_login'], 'time_nosec');
}
$grid = new GridController($entries, $total_entries, $_GET['ajax'],
true);
$grid->show();
} catch (\Exception $e) {
handleAjaxExceptions($e);
}
}
That’s it! Notice that we also added a “toggle active” handle in our list, that can be used to
set a user as active/inactive. This handle does not have any implementation associated,
because it calls the core system’s UserController to perform the action. Here’s how our
plugin page now looks, after adding the datagrid:
94
Heads up! The plugin code, as it is created until now, can be found in Github,
as AcmeReports-step2
Req. 3: Present a list of users that have not completed a specific course
We first need to create a drop-down list of courses that have a certificate associated, so that
the user can select one. In our controller, we do:
The code above retrieves all active, unarchived courses and assigns them to the template.
Heads up! Users, courses and lessons may be “archived”, meaning that they have a value
set for the “archive” field. This signifies that these entries are set as “deleted” and moved to
the archive. Special care should be taken, so that such entries are never taken into account
for calculations.
95
Heads up! Giving the ef-select class to any <select> element, will convert it to a
searchable drop-down
The tricky part now is to have this drop-down box interact with the grid, so that it displays
only users that possess the selected course but have not completed it. We will employ some
javascript and jquery magic for this:
<script>
$('#ef-select-course').on('change', function(event) {
if ($(this).val()) {
var url =
$.fn.st.getAjaxUrl('reportsTable')
.replace(/\/courses_ID\/[\w\d]*/, '')+'/courses_ID/'+$(this)
.val();
} else {
var url =
$.fn.st.getAjaxUrl('reportsTable')
.replace(/\/courses_ID\/[\w\d]*/, '');
}
$.fn.st.setAjaxUrl('reportsTable', url);
$.fn.st.redrawPage('reportsTable', true); });
</script>
This will change our Grid’s target URL, so that it also sends the selected course’s ID. We will
need to handle this accordingly to our Controller function as well:
[...]
use Efront\Model\Courses\CourseToUser;
[...]
[...]
96
protected function _listCourseUsers($course_id) {
try {
$this->checkId($course_id);
$course = new Course();
$course->init($course_id);
User::getCurrentUser()->canRead($course);
$constraints = GridController::createConstraintsFromSortedTable();
$conditions = array('condition'=>'u.archive=0 AND u.active=1 and
status !="'.CourseToUser::STATUS_COMPLETED.'"');
$entries = $course->getUsers($constraints+$conditions, array('u.*'));
$total_entries = $course->countUsers($constraints+$conditions);
foreach ($entries as $key=>$value) {
$entries[$key]['last_login'] =
formatTimestamp($entries[$key]['last_login'], 'time_nosec');
}
$grid = new GridController($entries,
$total_entries,
$_GET['ajax'],
true);
$grid->show();
} catch (\Exception $e) {
handleAjaxExceptions($e);
}
}
97
Heads up! The plugin code, as it is created until now, can be found in Github,
as AcmeReports-step3
On to our next task: Create an export and email it to the specified user
All grids contain a handy export button, that dumps its output as a CSV file (next to the filter
box). Based on this functionality, we will create a button that delivers the report to the
specified recipient, instead of prompting the user to download it. First, let’s create the button
in our template file:
Notice how we hide it by default. This is because we want it to appear only when the user
has selected a course, so we change the ef-select-coursehandling and add the
necessary scripting:
[...]
<script>
$('#ef-email-list').on('click', function(evt) {
$.fn.efront('modal',
{'header':'Select recipient', 'id':'ef-select-recipient-div'}
);
});
$('#ef-select-recipient').on('click', function(evt) {
var url = $.fn.st.getAjaxUrl('reportsTable',
true)+'?email=reportsTable&columns=formatted_name:User,last_login:Last%20
login';
98
$.fn.efront('ajax', url, {
data: { recipients:$('input[name="recipient"]').val().replace(/users-
/,'')}
}, function(response) {
$.fn.efront('modal', { close:true});
});
});
$('#ef-select-course').on('change', function(event) {
if ($(this).val()) {
var url =
$.fn.st.getAjaxUrl('reportsTable')
.replace(/\/courses_ID\/[\w\d]*/, '')+'/courses_ID/'+$(this)
.val();
$('.ef-report-handles').fadeIn();
} else {
var url =
$.fn.st.getAjaxUrl('reportsTable')
.replace(/\/courses_ID\/[\w\d]*/, '');
$('.ef-report-handles').fadeOut();
}
$.fn.st.setAjaxUrl('reportsTable', url);
$.fn.st.redrawPage('reportsTable', true);
});
</script>
[...]
The code above will make a modal appear, where the user can select recipients for the email,
and send an ajax request to our controller. We now have to implement the logic in our
controller that handles this request:
[...]
use Efront\Model\File;
use Efront\Model\Configuration;
use Efront\Model\MailQueue;
[...]
99
$file = $grid->exportData();
$this->_sendEmail($file, $_GET['recipients']);
$this->jsonResponse();
} else {
$grid->show();
}
} catch (\Exception $e) {
handleAjaxExceptions($e);
}
}
if (empty($recipients)) {
throw new EfrontException("You haven't specified a recipient");
}
if (!empty($messages)) {
$mail_queue = new MailQueue();
$mail_queue->addToQueue($messages);
}
}
100
Sending an email is as simple as creating an array holding the email data (recipient email,
title, body) and adding it to a MailQueue instance. See Sending emails for more information.
Here’s how our plugin page looks now, after clicking on the “Email list” button:
Heads up! The plugin code, as it is created until now, can be found in Github,
as AcmeReports-step4
We’re almost through with our plugin, the only thing remaining is to save reports to the
database. We will employ our model for this, which will be converted to describe a database
entry. But first, we need to set up our database table, using
our AcmeReportsPlugin class’ onInstall(), onUninstall() andonUpgrade() methods:
101
102
try {
Database::getInstance()->execute($sql);
} catch (\Exception $e) {
$this->uninstallPlugin();
//so that any installed tables are removed
//and we're able to restart fresh
}
return $this;
}
[...]
Simply refresh your page to allow the plugin’s onUpgrade() to run.Now that our database
table is in place, let’s extend our Model’s implementation:
103
<?php namespace Efront\Plugin\AcmeReports\Model;
[...]
[...]
That’s it! All we had to do is to define a DATABASE_TABLE constant and create an array with
the database table’s fields, as well as a public variable for each field. Being
a BaseModel class, our Model already contains all the necessary functions to
handle create/update/read/delete operations (see Creating a new Model + Database
table). We can now work on our controller to take advantage of this functionality. But first we
must create the necessary button and functionality in the View component:
[...]
[...]
<script>
$('#ef-save-list').on('click', function(evt) {
var url = $.fn.st.getAjaxUrl('reportsTable',
true)+'?save=reportsTable&columns=formatted_name:User,last_login:Last%20l
ogin';
$.fn.efront('ajax', url, { data: { 'save':true } },
function(response) {
bootbox.dialog({message: '<h4>{"Report
Saved!"|eF_dtranslate:$T_PLUGIN_NAME}</h4>',
104
//title: 'Report saved',
buttons: { cancel: { label: $.fn.efront('translate', "Close"),
className: "btn-primary"}}
});
});
});
[...]
This will send a request, similar to the previous, only this time specifying we need to save
instead of emailing. Our controller implements this logic as follows:
[...]
[...]
That’s it! Our plugin now saves the report, along with a timestamp. The only thing left now,
is to present the list of saved reports to the user. We will do so by implementing a second
Grid, in a different tab. First, let’s consider our template. We will create a {capture} section
that will hold our new grid:
105
[...] {capture name = "t_saved_reports"}
<!--ajax:savedReportsTable-->
<div class="table-responsive">
<table style = "width:100%;" class = "sortedTable table" data-sort =
"last_login" size = "{$T_TABLE_SIZE}" id = "savedReportsTable" data-ajax
= "1" data-rows = "{$smarty.const.G_DEFAULT_TABLE_SIZE}" url =
"{$smarty.server.REQUEST_URI}">
<tr>
<td class = "topTitle" name =
"timestamp">{"Timestamp"|eF_translate}
</td>
<td class = "topTitle noSort
centerAlign">{"Operations"|eF_translate}
</td>
</tr>
{foreach name = 'users_list' key = 'key' item = 'report' from =
$T_DATA_SOURCE}
<tr class = "{cycle values = "oddRowColor, evenRowColor"}" >
<td>{$report.timestamp}</td>
<td class = "centerAlign nowrap">
<a href = "{eF_template_url extend = $T_BASE_URL url
['view'=>$report.id]}" target = "_new">
<img src = 'assets/images/transparent.gif'
class = 'icon-search small'
alt = "{"View"|eF_translate}"
title = "{"View"|eF_translate}">
</a>
<img src = 'assets/images/transparent.gif'
class = 'ef-grid-delete ajaxHandle icon-error_delete small'
data-url = "{eF_template_url extend=$T_BASE_URL
url=['delete'=>$report.id]}" alt =
"{"Delete"|eF_translate}" title =
"{"Delete"|eF_translate}"/>
</td>
</tr>
{foreachelse}
<tr class = "defaultRowHeight oddRowColor">
<td class = "emptyCategory" colspan = "100%">-</td>
</tr>
{/foreach}
</table>
</div> <!--/ajax:savedReportsTable-->
{/capture}
[...]
106
We need this capture, to create tabs. We must add all the other code inside
another {capture}, and then create the tabs using {eF_template_printTabs}. In the end
it looks like this:
The code above prints 2 tabs, one for each grid. The saved reports grid is handled in our
controller with a _listReports() function, similar to the previous grid:
[...]
107
$entries = AcmeReports::getAll($constraints);
$total_entries = AcmeReports::countAll($constraints);
[...]
But that’s not all! Our saved reports grid also contains a couple of handles: One for
downloading a report and one for deleting it. Here’s the controller code that implements both
of these:
[...] }
108
Heads up! The plugin code, as it is created until now, can be found in Github,
as AcmeReports-final
Overriding templates
One common customization requirement is to change substantially the look and feel of a
certain page. For example, someone might need to provide a totally different implementation
for the navbar, with changes that cannot be achieved using CSS and Javascript (which can
be altered using custom themes). In such a case, a plugin can be used, as follows:
2. Locate the template file you wish to override. In our example, that would
be libraries/Efront/View/layout/navbar.tpl. Then create a file with the
same name at the respective folder of your plugin. In our AcmeReports example, we
would create the filewww/plugins/AcmeReports/View/layout/navbar.tpl
3. The system now will read your plugin’s file, instead of the default one. However, if you
still want to reference the original file (for example, if we simply want to add some
code), you can do this as follows:
4. A different option is to extend a plugin, rather than completely overriding. In this case, if
the core file contains any named {block} sections, you can override these specifically.
For example, the file lessons/lesson_dashboard.tpl, contains the following
block for displaying the two columns in the dashboard:
109
[...]
You can now extend this particular piece of code in your plugin’s
lesson/lesson_dashboard.tpl file. For example, the code below would add an additional
column in the middle, making the lesson dashboard’s layout to have 3 columns, instead of
2:
Manipulating forms
Forms in general is a complicated issue, but in eFrontPro steps have been taken to simplify
them as much as possible. Forms are usually implemented as part of the Model class.
See Creating forms for more information on how to create a form. Every form can be
manipulated from within a plugin using
theonCreateForm(), onBeforeHandleForm() and onAfterHandleForm() functions. All of
these functions accept as argument the form name and the Formobject
onCreateForm() is called right after the form is populated with fields, but before any
processing happens. This is suitable for adding or removing fields from the form.
onBeforeHandleForm is called right after the submit button is pressed, but before any
actual processing takes place. This is suitable for completely overriding the default
form handling, or for pre-processing POST variables
onAfterHandleForm() is called after all processing is finished. This is suitable for
performing post-processing operations.
Heads up! Make sure your plugin only handles the correct form, by checking its name,
otherwise it will process all forms!
Internationalization
You may have noticed that in many examples, we use translate()/dtranslate() (PHP)
and eF_translate/eF_dtranslate (template) for outputting strings that should appear
localized. That’s because eFrontPro uses Gettext to handle the translations of its
110
messages. translate() and eF_translatewill use the system’s existing translations, and
are used for cases where a string already exists in the core. For strings that are specific to
your plugin, follow a few simple steps as described below:
1. A message of your plugin which require translation, will properly be translated if you
use 2 functions. The function dtranslate(“myMessage”, “<plugin_name>”) must
be used when the message exists into a class and not a template inside your plugins
scope. In the other case (template), you have to use
the “myMessage”|eF_dtranslate:<plugin_name>. Replace <plugin_name> with the
name of your plugin
2. Visit the page /<plugin>/parse_language/1 (For
example, http://efrontpro.example.com/AcmeReports/parse_language/1). This will
create all the required language specific folders and .po files inside the plugin’s i18n
folder and a php file with name translations.php.
3. Open each .po file with poedit. Poedit can be found here.
4. Click on the “Update” button to parse the plugin files and fill the list of strings that need
translation.
5. Translate all string literals.
6. Press the “Save” button to save your work. Make sure you have write access to the
folders created in step 1.
7. Restart your server, in case that the translations aren’t changed.
Heads up! Make sure that the file “translations.php” is a valid PHP file. If it’s not, check your
template files again. All translations must be enclosed in double quotes, not single.
Sending emails
When creating a plugin, you don’t have to actually send an email. All you have to do is to
pass the email data to the MailQueue handler, and your email will queued to be delivered
upon the next iteration. Example:
<?php
[...]
111
'body' => $body,
'timestamp' => $timestamp
);
}
$mail_queue = new MailQueue();
$mail_queue->addToQueue($messages);
That’s it! You have now 3 emails in the mail queue, waiting to be delivered. You can examine
the queue’s contents from admin→Notifications→Queue
Heads up! Setting the email’s timestamp at some point in the future, will make the email
stay in queue until then.
Error handling
It is a good practice to have your code throw an exception whenever an error occurs. When
catching exceptions, you should discriminate between exceptions that are thrown during the
normal flow of your program, or during an ajax request, and handle them differently,
using handelNormalFlowExceptions() orhandleAjaxExceptions() respectively:
<?php
[...]
try {
//some normal flow stuff here
throw new \Exception("Testing exceptions");
} catch (\Exception $e) {
handleNormalFlowExceptions($e);
}
if (!empty($_GET[‘ajax’])) {
try {
//some ajax flow stuff here
throw new \Exception("Testing exceptions");
} catch (\Exception $e) {
handleAjaxExceptions($e);
}
}
This will ensure that the error message will always display properly in the end user.
Heads up! If your plugin throws an exception while handling an event, using
the onEvent() call, the exception will be suppressed, to prevent the operation from stopping.
112
You should handle any exceptions that your plugin might generate during an onEvent() call
yourself
Upgrading
A plugin typically requires upgrade, when its associated database schema needs changing.
The plugin upgrading process can be automated in eFrontPro and is described as a step-
by-step process:
Imagine that you have a plugin named “AcmeReports” which is in version 1.0 and needs to
run an alter table query.
1. Edit the plugin class file that extends AbstractPlugin and change the VERSION
constant to a larger number, for example 1.1
2. Edit your upgradePlugin() function to include the SQL code that must be ran. For
example, in order to add a field to a table:
[...]
Database::getInstance()
->execute("alter table plugin_acme_reports add timestamp
int default null");
}
return $this;
}
[...]
3. Once you run any page in your system (e.g. sign in as administrator) The system will
detect that the plugin’s stored version number is different than the one specified in
VERSION, and will execute the plugin’s upgradePlugin() function.
4. Each time a new change is required, increase the VERSION and add the proper lines
inside upgradePlugin(). For example, for 1.2, the function will become:
[...]
if (version_compare('1.1', $this->plugin->version) == 1) {
Database::getInstance()
113
->execute("alter table plugin_acme_reports add timestamp int
default null");
}
if (version_compare('1.2', $this->plugin->version) == 1) {
Database::getInstance()
->execute("alter table plugin_acme_reports add comments
text");
}
return $this;
}
[...]
Heads up! When changing the version, make sure you change it inside your plugin’s
plugin.ini file. In addition, don’t forget to make the same database changes inside
your onInstall() function, and add proper routines in onUninstall(), if needed
Considerations
114
branch context. In order to determine a user object’s type, the simplest way is to call one of
these functions:
When editing a template file, these functions have their smarty counterparts:
{if $T_CURRENT_USER_IS_ADMINISTRATOR}
{elseif $T_CURRENT_USER_IS_SUPERVISOR}
{elseif $T_CURRENT_USER_IS_PROFESSOR}
{elseif $T_CURRENT_USER_IS_STUDENT}
{/if}
When inside a controller, if we need to restrict access to a specific basic type, we must
implement the _requestPermissionFor() function. For example, the following
implementation limits the current plugin to administrator types only:
[...]
[...]
115
[...]
[...]
[...]
[...]
In order to determine whether a user can access or change an entity, one can utilize the
usertype object:
if ($access_level == UserType::USER_TYPE_LEVEL_WRITE) {
//the $user can create/change a course
} else if ($access_level == UserType::USER_TYPE_LEVEL_READ) {
//the $user can only read a course, but not change or delete it,
neither create a new one
} else {
//the $user has no access on course information whatsoever
}
116
To simplify things, all controllers that extend BaseController already include the current
user’s access_level for the entity specified in_requestPermissionFor() (the first
argument), so inside a controller it’s sufficient to do something like this:
When inside a template, a similar approach is possible, especially since all access levels are
already available, as the $T_USER_TYPE_ACCESS variable. For example, if we were to decide
whether to display an “edit” link to a user, we would do:
{if
$T_USER_TYPE_ACCESS['\Efront\Model\UserType::USER_TYPE_PERMISSION_USERS'|
constant] != '\Efront\Model\UserType::USER_TYPE_LEVEL_NONE'|constant}
<a href = "{eF_template_url url=['ctg'=>'users','edit'=>$user.id]}" class
= "editLink">
{$user.formatted_name}
</a>
{else}
{$user.formatted_name}
{/if}
In order to ensure that a user has permissions to view/change an entity, one has to consider
other parameters, besides its user type: For example, if a professor tries to access a course,
is he actually enrolled to it? What about a supervisor trying to view information about a user,
is that user part of his/her branch tree? For such cases, there is a pair of handy functions
one can use, User::canRead() and User::canChange()
$current_user = User::getCurrentUser();
//The currently logged-in user
$course = new Course(321);
//some course that the user is trying to access
117
$user->canRead($course);
//will throw an exception if the user
// should not access the course
$user->canChange($course);
//will throw an exception if the user
//should not update/delete the course
Heads up! canRead() and canWrite() accept as an argument any object deriving from
the BaseModel class. However, they are expensive functions and should never be used in
loops, but only as a last safety precaution.
Prioritization
Plugins in eFrontPro are executed in a “first installed-first served” fashion. This means that,
when waiting for a call from the plugin API, your plugin might not be the first to handle it, so
the output might have changed. In the future, we might add prioritization in plugins, so take
care to not rely on this behaviour.
Coding standards
eFrontPro does not impose any strict coding standards, but encourages the user of the PSR-
2 guidelines, which ensure readability and tidiness.
118
Make sure you leave out archived users, courses and lessons when making
calculations. Archived entities are equivalent to deleted; you can tell that an entity is
archived, because it will have a timestamp for its “archive” field (normal entities have 0
in this field)
All entities are cached, when a caching engine is present. Thus changing an entity
directly in the database (either using the Database class or directly from the command
line) will not have an apparent effect, unless the cache is cleared (with a webserver
restart or from admin→Maintenance→Cache)
Troubleshooting / debugging
Inevitably, you’ll run into all sorts of errors and abnormal situations. Here’s a list of the most
common and their causes
Heads up! Call debug() at any point in your script to turn on full error reporting, and a dump
of all queries executed, until the script ends or debug(false) is called.
Blank screen: This is caused by a fatal error at some very early stage of the system
execution. If the web server’s error log file doesn’t say anything about the error, then
you might have to dive into the core code itself: Edit the
file libraries/Controller/MainController.php, locate thesetup() function
and change the line where it says error_reporting( E_ERROR
); to error_reporting( E_ALL );ini_set(“display_errors”,
true);define(“G_DEBUG”, 1);
Murphy’s law: The standard error page for unhandled errors states quotes Murphy.
Usually this page also displays the error message itself, as well as the file and line
where it occurred. If it’s not clear by the message, then try adding a debug() call early
in your script to help you find out what’s wrong.
Smarty error: The most common error in smarty templates, is when some Javascript
codes contains an opening bracket immediately followed by a character, without a
space, for example {'foo':'bar'}. Change this to { 'foo':'bar'} to prevent
smarty from trying to parse it. Other errors, such as syntax errors, usually display with a
clear message and the file and line number where they occur.
Invalid CSRF Token: This is common when trying to open an ajax request in a new
window. It happens because of an aggressive CSRF filter the system employs in all
Ajax requests. You should only debug ajax calls via your browser’s console.
SyntaxError: Unexpected token <: This error is usually thrown from an ajax request that
did not receive an JSON response, but rather an HTMLresponse. Probable causes are:
You made an ajax request to a controller, but the controller did not provide a JSON
response
The controller responds properly, but you forgot to exit after the response
An error occurred that was not handled with handleAjaxRequest()
119
Plugin API Reference
Below you can find all functions that you can override inside your Plugin class, as found
inside the AbstractPlugin class
/**
* This function is executed every time an event is fired.
* @param Event $event The Event object
*/
public function onEvent(Event $event) { }
/**
* This function is executed right after a form is submitted, but before
* any processing takes place. It may be used to manipulate submitted
values.
* You have to use the $form_name, which is unique for every for, to
* discriminate between various forms
* @param string $from_name The form name
* @param Form $form The form object
*/
public function onBeforeHandleForm($form_name, Form $form) { }
/**
* This function is executed right before a form is submitted.
* It may be used in order to add fields or manipulate existing ones
* You have to use the $form_name, which is unique for every for, to
* discriminate between various forms
* @param string $from_name The form name
* @param Form $form The form object
*/
public function onCreateForm($form_name, Form $form) { }
/**
* This function is executed after a form is submitted and its
* values are processed. It may be used to perform any post-processing
* tasks. You have to use the $form_name, which is unique for every
* for, to discriminate between various forms
* @param string $from_name The form name
* @param Form $form The form object
*/
public function onAfterHandleForm($form_name, Form $form) { }
/**
* This function is called when the controller to be ran is decided,
* or the default controller is about to take over. It can be used in two
* ways: Either to execute some code when a specific controller (page) is
* executed, or to provide a means to access a plugin-specific controller
120
* @param string $ctg The requested controller in the browser, e.g.
'users' or 'lessons' * @return mixed null or a BaseController object
*/
/**
* This function is called by each controller, every time its index
function is executed.
* @param BaseController $controller
*/
public function onControllerIndex(BaseController $controller) { }
/**
* This function is executed every time an icon list is loaded. Each icon
list
* has a distinctive name, so the plugin must discriminate based on the
$list_name
* provided. The icons array is passed by reference, so the plugin may
manipulate
* the list or add icons. This is usually used to add a plugin icon, which
provides
* a link to the plugin page
* @param string $list_name The icon list name
* @param $options The current icon options list
*/
/**
* This function is executed every time the system gets a lesson's
options.
* It can be used to augment or manipulate the options list, which is
passed
* by reference
* @param Lesson $lesson The lesson used
* @param array $lesson_settings The list of current lesson settings
*/
public function setLessonOptions(\Efront\Model\Lesson $lesson, array
121
&$lesson_settings) { }
/**
* This function is executed before any controller takes action
*/
/**
* This function is called before the calendar is displayed. It can be
used
* to manipulate calendar entries, or add new ones
* @param array $calendar_entries The calendar's entries
*/
public function onLoadCalendar(array &$calendar_entries) {
}
/**
* This function is called from the REST API, using a POST method,
* and passes the POST payload to the plugin. It then returns the
* plugin's return value to the caller.
* @param string $method The method used (currently only POST supported)
* @param mixed $data The data passed from the POST request
* @return mixed Any response the plugin needs to send to the requester
*/
public function onApiCall($method, $data) { }
/**
* Implement this function with all the required queries and actions to
* install the plugin
*/
abstract public function installPlugin();
/**
* Implement this function with all the required queries and actions to
* remove the plugin
*/
abstract public function uninstallPlugin();
/**
* Implement this function with all the required queries and actions to
122
* upgrade the plugin to a new version
*/
abstract public function upgradePlugin();
123
Event Reference
Events are fired in various parts of the script’s lifetime. Each event bears one or more objects
as arguments, for example the user that caused the event, the entity it affects etc. Each
event has its own associated class, and you can refer to it for a list of the available properties.
Below is a list of the currently available events:
124
const EVENT_USER_CURRICULUM_ADDED = 'user_curriculum_added';
const EVENT_USER_CURRICULUM_REMOVED = 'user_curriculum_removed';
const EVENT_USER_CURRICULUM_COMPLETED = 'user_curriculum_completed';
const EVENT_USER_CURRICULUM_FAILED = 'user_curriculum_failed';
const EVENT_USER_CERTIFICATE_AWARDED = 'user_certificate_awarded';
const EVENT_USER_CERTIFICATE_EXPIRED = 'user_certificate_expired';
const EVENT_USER_CERTIFICATE_REVOKED = 'user_certificate_revoked';
125
Core API Notes
Creating URLs
It is generally discouraged to hard-code URLs in eFrontPro, but use
the UrlHelperController class for this task. Here are a few usage examples:
You can create a url/link in a template file, using the {eF_template_url} smarty function:
And in javascript:
For this table, we would create a class called Log, with the following contents (we use
the AcmeReports namespace, from our earlier example):
126
<?php namespace Efront\Plugin\AcmeReports\Model;
use Efront\Model\BaseModel;
Since our class inherits BaseModel, it comes with a complete set of functions for performing
CRUD operations (Create/Read/Update/Delete). We only have to specify the database
table name, and its fields. The protected $_fields array is a key-value array, where keys
are the field names and values are optional type-checking attributes. For example, the
line 'id'⇒'id' specifies that, when updating, the value of the “id” element should conform
to the restrictions for an “id” value (positive integer). Similarly, 'time' ⇒
'timestamp' means that the value of the field ‘time’ should be a timestamp (positive
integer, 10 digits). When left empty, the value is only checked against the “generic” type, that
imposes scalar values (and throws an error for arrays, objects etc).
Heads up! If you don’t specify a type check, when saving an object the passed value will be
XSS-filtered. If you want to keep any HTML code present in the value, then use the ‘wysiwig’
value for the field.
After creating the class, you can use it to perform CRUD operations:
127
database entry
$log2->delete(); //Delete the database entry
Heads up! Always use the setFields() and save() functions to alter a database entry and
the delete()function to delete one. Otherwise, the built-in cache manager may not be
updated, leading to unpredictable results.
Creating forms
Forms are easy to create and display. The simplest scenario is when we create a form for a
class that represents a database table. For our previous Logexample, we could add a form
like in the example below:
use Efront\Model\BaseModel;
use Efront\Model\Form;
128
$values['body'] = $form
->handleInlineImages($values['body']);
$fields = array(
'title' => $values['title'],
'content' => $values['content']);
$this->setFields($fields)->save();
$form->success = true;
} catch (\Exception $e) {
handleNormalFlowExceptions($e);
}
}
} catch (\Exception $e) {
handleNormalFlowExceptions($e);
}
return $form;
}
}
In order to output the form, in your controller you must call the form and assign it to the
template:
129
And display it in your template:
{eF_template_printForm form=$T_FORM}
That’s it! The fields will display in the order they were
defined.printForm calls TemplateController::printForm() which supports very
elaborate structures, consult that function’s source for more information.
Heads up! If you use a controller that inherits from BaseController, then
calling parent::index() in your controller will automatically call your
model’s form() function, if the URL contains the /add/1 or /edit/<id>parameters. It will also
assign the form to your template, inside the $T_FORM variable
Javascript functions
eFrontPro comes with a number of high-level javascript functions to simplify common tasks,
through the $.fn.efront extension to jquery
<script>
$.fn.efront('modal', {'header':'My modal title', 'body':'Modal
content'}); //Display a modal with this title and content
</script>
<script>
$.fn.efront(
'confirm',
{
'title':'Confirm',
'body':'Are you sure?',
'success': {
'class_name':'btn-danger',
'label':'Yes',
'callback': function(result) {
/*do something if Yes is clicked */
}
},
'fail': {
'callback': function(result) {
/*do something if No is clicked */
}
130
}
});
</script>
<script>
$.fn.efront('ajax', location.toString(), { data:{ 'ajax':1}},
function(response, textStatus, jqXHR) { /*executes on success*/ },
function(response, textStatus, jqXHR) { /*executes on failure*/ } );
</script>
<?php
$variable = "John Doe";
$smarty->assign(“T_VAR”, $variable);
?>
Conditionals:
131
Loops:
<ul>
{foreach $array_variable as $value}
<li>$value</li>
{/foreach}
</ul>
Variables:
Javascript: Always leave a space after opening brackets, to keep smarty from parsing it as
smarty code:
Had enough yet? Access the Smarty3 manual for the complete documentation
1)
Spaces and special or international characters are not allowed for the plugin name
132