diff --git a/deployed/tflearn/administrator/components/com_tflearn/access.xml b/deployed/tflearn/administrator/components/com_tflearn/access.xml
new file mode 100644
index 00000000..112ad417
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/access.xml
@@ -0,0 +1,12 @@
+
+
+
+
\ No newline at end of file
diff --git a/deployed/tflearn/administrator/components/com_tflearn/config.xml b/deployed/tflearn/administrator/components/com_tflearn/config.xml
new file mode 100644
index 00000000..ef13f7d9
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/config.xml
@@ -0,0 +1,245 @@
+
+
+
+
+
+
+
+ JNO
+ JYES
+
+
+
+ Bootstrap CSS
+ Bootstrap JS
+ Air Grid CSS
+
+
+
+ JNO
+ JYES
+
+
+
+ JNO
+ JYES
+
+
+
+ JNO
+ JYES
+
+
+
+
+
+
+
+
+
+
+
+ id
+ title
+ created
+ modified
+ ordering
+
+
+
+ JGLOBAL_ORDER_DESCENDING
+ JGLOBAL_ORDER_ASCENDING
+
+
+
+ JHIDE
+ JSHOW
+
+
+
+
+
+
+
+
+
+
+
+
+
+ COM_TF_PLAIN
+ COM_TF_ACCORDION
+ COM_TF_TABS
+
+
+
+ JHIDE
+ JSHOW
+
+
+
+ JNO
+ Semicolon Separated
+ Unordered List
+
+
+
+
+
+ JNONE
+ Top
+ Bottom
+ Top and Bottom
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ id
+ title
+ created
+ modified
+ ordering
+
+
+
+ JGLOBAL_ORDER_DESCENDING
+ JGLOBAL_ORDER_ASCENDING
+
+
+
+
+
+
+
+
+
+
+
+ COM_TF_PLAIN
+ COM_TF_ACCORDION
+ COM_TF_TABS
+
+
+
+ id
+ title
+ created
+ modified
+ ordering
+ hits
+ ref
+
+
+
+ JGLOBAL_ORDER_DESCENDING
+ JGLOBAL_ORDER_ASCENDING
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ JNO
+ JYES
+
+
+
+ JNO
+ JYES
+
+
+
+ JNO
+ JYES
+
+
+
+
+
+
+
+
+
+
+
+
+
+ JNO
+ JYES
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ JNO
+ JYES
+
+
+
+ JNO
+ JYES
+
+
+
+
+
+ JNO
+ JYES
+
+
+
+
+
+ JNO
+ JYES
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/deployed/tflearn/administrator/components/com_tflearn/forms/completion.xml b/deployed/tflearn/administrator/components/com_tflearn/forms/completion.xml
new file mode 100644
index 00000000..73ad0b7b
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/forms/completion.xml
@@ -0,0 +1,50 @@
+
+
\ No newline at end of file
diff --git a/deployed/tflearn/administrator/components/com_tflearn/forms/course.xml b/deployed/tflearn/administrator/components/com_tflearn/forms/course.xml
new file mode 100644
index 00000000..f03b6576
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/forms/course.xml
@@ -0,0 +1,85 @@
+
+
\ No newline at end of file
diff --git a/deployed/tflearn/administrator/components/com_tflearn/forms/filter_completions.xml b/deployed/tflearn/administrator/components/com_tflearn/forms/filter_completions.xml
new file mode 100644
index 00000000..facbb19f
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/forms/filter_completions.xml
@@ -0,0 +1,50 @@
+
+
\ No newline at end of file
diff --git a/deployed/tflearn/administrator/components/com_tflearn/forms/filter_courses.xml b/deployed/tflearn/administrator/components/com_tflearn/forms/filter_courses.xml
new file mode 100644
index 00000000..9a2b704c
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/forms/filter_courses.xml
@@ -0,0 +1,30 @@
+
+
\ No newline at end of file
diff --git a/deployed/tflearn/administrator/components/com_tflearn/forms/filter_lessons.xml b/deployed/tflearn/administrator/components/com_tflearn/forms/filter_lessons.xml
new file mode 100644
index 00000000..e55471f1
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/forms/filter_lessons.xml
@@ -0,0 +1,64 @@
+
+
\ No newline at end of file
diff --git a/deployed/tflearn/administrator/components/com_tflearn/forms/filter_modules.xml b/deployed/tflearn/administrator/components/com_tflearn/forms/filter_modules.xml
new file mode 100644
index 00000000..1364b4b2
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/forms/filter_modules.xml
@@ -0,0 +1,27 @@
+
+
\ No newline at end of file
diff --git a/deployed/tflearn/administrator/components/com_tflearn/forms/filter_pages.xml b/deployed/tflearn/administrator/components/com_tflearn/forms/filter_pages.xml
new file mode 100644
index 00000000..ea0d2cb1
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/forms/filter_pages.xml
@@ -0,0 +1,11 @@
+
+
\ No newline at end of file
diff --git a/deployed/tflearn/administrator/components/com_tflearn/forms/filter_questions.xml b/deployed/tflearn/administrator/components/com_tflearn/forms/filter_questions.xml
new file mode 100644
index 00000000..e88008de
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/forms/filter_questions.xml
@@ -0,0 +1,59 @@
+
+
\ No newline at end of file
diff --git a/deployed/tflearn/administrator/components/com_tflearn/forms/filter_scores.xml b/deployed/tflearn/administrator/components/com_tflearn/forms/filter_scores.xml
new file mode 100644
index 00000000..01e63f23
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/forms/filter_scores.xml
@@ -0,0 +1,31 @@
+
+
\ No newline at end of file
diff --git a/deployed/tflearn/administrator/components/com_tflearn/forms/lesson.xml b/deployed/tflearn/administrator/components/com_tflearn/forms/lesson.xml
new file mode 100644
index 00000000..0119bcfe
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/forms/lesson.xml
@@ -0,0 +1,161 @@
+
+
\ No newline at end of file
diff --git a/deployed/tflearn/administrator/components/com_tflearn/forms/module.xml b/deployed/tflearn/administrator/components/com_tflearn/forms/module.xml
new file mode 100644
index 00000000..d4a350b2
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/forms/module.xml
@@ -0,0 +1,21 @@
+
+
\ No newline at end of file
diff --git a/deployed/tflearn/administrator/components/com_tflearn/forms/page.xml b/deployed/tflearn/administrator/components/com_tflearn/forms/page.xml
new file mode 100644
index 00000000..5ee1dd48
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/forms/page.xml
@@ -0,0 +1,25 @@
+
+
\ No newline at end of file
diff --git a/deployed/tflearn/administrator/components/com_tflearn/forms/question.xml b/deployed/tflearn/administrator/components/com_tflearn/forms/question.xml
new file mode 100644
index 00000000..e18ba0c8
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/forms/question.xml
@@ -0,0 +1,108 @@
+
+
\ No newline at end of file
diff --git a/deployed/tflearn/administrator/components/com_tflearn/forms/score.xml b/deployed/tflearn/administrator/components/com_tflearn/forms/score.xml
new file mode 100644
index 00000000..d2f64cef
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/forms/score.xml
@@ -0,0 +1,49 @@
+
+
\ No newline at end of file
diff --git a/deployed/tflearn/administrator/components/com_tflearn/forms/subform_content.xml b/deployed/tflearn/administrator/components/com_tflearn/forms/subform_content.xml
new file mode 100644
index 00000000..7c01054f
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/forms/subform_content.xml
@@ -0,0 +1,20 @@
+
+
\ No newline at end of file
diff --git a/deployed/tflearn/administrator/components/com_tflearn/forms/subform_matching.xml b/deployed/tflearn/administrator/components/com_tflearn/forms/subform_matching.xml
new file mode 100644
index 00000000..1dd83c2f
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/forms/subform_matching.xml
@@ -0,0 +1,14 @@
+
+
\ No newline at end of file
diff --git a/deployed/tflearn/administrator/components/com_tflearn/forms/subform_modules.xml b/deployed/tflearn/administrator/components/com_tflearn/forms/subform_modules.xml
new file mode 100644
index 00000000..b2792742
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/forms/subform_modules.xml
@@ -0,0 +1,20 @@
+
+
\ No newline at end of file
diff --git a/deployed/tflearn/administrator/components/com_tflearn/forms/subform_options.xml b/deployed/tflearn/administrator/components/com_tflearn/forms/subform_options.xml
new file mode 100644
index 00000000..1b46e9f8
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/forms/subform_options.xml
@@ -0,0 +1,16 @@
+
+
\ No newline at end of file
diff --git a/deployed/tflearn/administrator/components/com_tflearn/forms/subform_questions.xml b/deployed/tflearn/administrator/components/com_tflearn/forms/subform_questions.xml
new file mode 100644
index 00000000..0e33f7d4
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/forms/subform_questions.xml
@@ -0,0 +1,9 @@
+
+
\ No newline at end of file
diff --git a/deployed/tflearn/administrator/components/com_tflearn/forms/subform_resources.xml b/deployed/tflearn/administrator/components/com_tflearn/forms/subform_resources.xml
new file mode 100644
index 00000000..5806f563
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/forms/subform_resources.xml
@@ -0,0 +1,19 @@
+
+
\ No newline at end of file
diff --git a/deployed/tflearn/administrator/components/com_tflearn/language/en-GB/en-GB.com_tflearn.ini b/deployed/tflearn/administrator/components/com_tflearn/language/en-GB/en-GB.com_tflearn.ini
new file mode 100644
index 00000000..2142cd4d
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/language/en-GB/en-GB.com_tflearn.ini
@@ -0,0 +1,342 @@
+; Used by All
+COM_TF_ACCORDION="Accordion"
+COM_TF_ACTIONS="Actions"
+
+COM_TF_ALL_RECORDS_DELETED="All Records Deleted"
+COM_TF_ASSOCIATION="Association"
+COM_TF_AVAILABLE_COLUMNS="Available Columns"
+COM_TF_AUTHOR_TYPE="Author Type"
+
+COM_TF_BUTTON="Button"
+COM_TF_BUTTON_TEXT="Button Text"
+COM_TF_BUTTON_CLASS="Button Class"
+
+COM_TF_CUSTOM="Custom"
+
+COM_TF_GENERAL="General"
+COM_TF_CONFIG_GENERAL_DESC="These settings apply for overall working of component."
+COM_TF_NOTIFY="Notifications"
+COM_TF_CONFIG_NOTIFY_DESC="These settings apply for email notifications."
+
+COM_TF_COLUMN="Column"
+COM_TF_COLUMN_SAVE="Column to Save"
+COM_TF_COLUMNS="Columns"
+COM_TF_CONFIGURATION="Configuration"
+COM_TF_CREATED_BY="Created By"
+COM_TF_CSV_FILE="CSV File"
+COM_TF_CUSTOM_FIELD="Custom Field"
+COM_TF_CUSTOM_FIELDS="Custom Fields"
+
+COM_TF_DASHBOARD="Dashboard"
+COM_TF_DATE_FORMAT="d M Y H:i"
+COM_TF_DEFAULT="Default"
+COM_TF_DELETE="Delete"
+COM_TF_DOCUMENTATION="Documentation"
+
+COM_TF_EMPTY_TABLE="Empty Table"
+COM_TF_EXPORT="Export"
+COM_TF_EXPORT_PRO="Export (Upgrade to Pro)"
+COM_TF_EXPORT_COLUMNS_DESC="Enter column names as comma separated values"
+COM_TF_EXPORT_TYPE_DESC="Select table or data source"
+COM_TF_EXTENSIONS="Extensions"
+
+COM_TF_ERROR_SELECT_FIELDS="Fields cannot be empty"
+COM_TF_ERROR_INVALID_FILE="Uploaded file is not valid"
+
+COM_TF_FEED_SUMMARY_LIMIT="Feed Summary Limit"
+
+COM_TF_FIELDSET_BUTTON="Button"
+COM_TF_FIELDSET_BUTTON_STYLE="Button Style"
+COM_TF_FIELDSET_STYLES="Styles"
+
+COM_TF_FILTER="Filter"
+COM_TF_FILTER_FIELD="Filter Field"
+COM_TF_FILTER_OPERATOR="Filter Operator"
+COM_TF_FILTER_VALUE="Filter Value"
+
+COM_TF_IGNORE_FIRST_ROW="Ignore First Row"
+COM_TF_IMAGE="Image"
+COM_TF_IMPORT="Import"
+COM_TF_IMPORT_PRO="Import (Upgrade to Pro)"
+COM_TF_IMPORT_CSV="CSV Import"
+COM_TF_IMPORT_CSV_DESC="Import data from CSV files."
+COM_TF_IMPORT_TYPE_DESC="Select table or data destination"
+COM_TF_IMPORT_COLUMNS_DESC="Enter column names as comma separated values"
+
+COM_TF_KEY="Key"
+
+COM_TF_LABEL="Label"
+COM_TF_LAYOUT="Layout"
+COM_TF_LIMIT="Limit"
+
+COM_TF_N_ITEMS_DELETED_1="One item deleted"
+COM_TF_N_ITEMS_DELETED_MORE="%d items deleted"
+COM_TF_N_ITEMS_PUBLISHED="%d item(s) published"
+COM_TF_N_ITEMS_UNPUBLISHED="%d item(s) unpublished"
+COM_TF_N_ITEMS_TRASHED="%d item(s) trashed"
+COM_TF_N_ITEMS_ARCHIVED="%d item(s) archived"
+
+COM_TF_NAME="Name"
+COM_TF_NUM="#"
+COM_TF_NOTE="Note"
+
+COM_TF_OFFSET="Offset"
+COM_TF_ORDER="Order"
+COM_TF_ORDER_BY="Order By"
+COM_TF_ORDER_COLUMN="Order Column"
+COM_TF_ORDER_DIRECTION="Order Direction"
+COM_TF_ORDERING="Ordering"
+COM_TF_ORDERING_NOTE_ASC="Note ascending"
+COM_TF_ORDERING_NOTE_DESC="Note descending"
+
+COM_TF_PLAIN="Plain"
+COM_TF_PREMIUM="Premium"
+COM_TF_PROCESS="Process"
+COM_TF_PUBLISHER_LOGO="Publisher Logo"
+COM_TF_PUBLISHER_LOGO_DESC="Should be jpg or png file of 60x600px rectangle"
+COM_TF_PUBLISHER_NAME="Publisher Name"
+
+COM_TF_QUERY="Query"
+COM_TF_QUERY_PRO="Query (Upgrade to Pro)"
+COM_TF_QUERY_TOOL="Query Tool"
+COM_TF_QUERY_COLUMN_DESC="Database column name or custom field id for joomla content and users"
+COM_TF_QUERY_TYPE_DESC="Select database table"
+
+COM_TF_RECORD_SAVED="Record saved"
+COM_TF_RECORDS_UPDATED="records updated."
+COM_TF_RECORDS_IMPORTED="records imported."
+COM_TF_RECORDS_EXISTS="records already exists."
+COM_TF_REVIEW="Review"
+
+COM_TF_SELECT="- Select -"
+COM_TF_SUPPORT="Support"
+COM_TF_SCHEMA_TYPE="Schema Type"
+COM_TF_SHOW_DATE="Show Date"
+COM_TF_SHOW_SEARCH="Show Search"
+COM_TF_SHOW_SD="Structured Data"
+
+COM_TF_TABS="Tabs"
+COM_TF_TEXT="Text"
+COM_TF_TOOLBAR_EXPORT="Export"
+COM_TF_TOOLBAR_IMPORT="Import"
+COM_TF_TOOLBAR_PREVIEW="Preview"
+COM_TF_TOOLBAR_PROCESS="Process"
+COM_TF_TOOLBAR_QUERY="Query"
+COM_TF_TOTAL_RECORDS="Total Records: "
+COM_TF_TRUNCATE_TABLE="Truncate Table"
+COM_TF_TYPE="Type"
+
+COM_TF_USER="User"
+COM_TF_USER_ID="User ID"
+COM_TF_USERS="Users"
+COM_TF_USER_FIELD="User Field"
+COM_TF_USER_FIELDS="User Fields"
+COM_TF_USER_GROUP="User Group"
+COM_TF_USER_GROUPS="User Groups"
+
+COM_TF_VALUE="Value"
+COM_TF_WHERE_CONDITIONS="Where Conditions"
+
+; Extension Specific
+COM_TFLEARN_ANSWER="Answer"
+COM_TFLEARN_ATTEMPTS="Attempts"
+COM_TFLEARN_ATTEMPT_GAP="Attempt Gap"
+
+COM_TFLEARN_BUTTON_DETAILS="Details Button Text"
+COM_TFLEARN_BUTTON_ENROL="Enrol Button Text"
+COM_TFLEARN_BUTTON_CAPTION="Button Caption"
+CON_TFLEARN_BUTTON_CLASS="Button Class"
+
+COM_TFLEARN_COLUMN_A="Column A"
+COM_TFLEARN_COLUMN_B="Column B"
+
+COM_TFLEARN_COMPLETION="Completion"
+COM_TFLEARN_COMPLETIONS="Completions"
+COM_TFLEARN_COMPLETION_TYPE="Completion Type"
+COM_TFLEARN_COMPLETION_ADD="Completion: New"
+COM_TFLEARN_COMPLETION_EDIT="Completion: Edit"
+
+COM_TFLEARN_CONTENT="Content"
+COM_TFLEARN_CONTENT_IDS="Content IDs"
+COM_TFLEARN_CONTENT_ID="Content ID"
+
+COM_TFLEARN_CORRECT="Correct"
+
+COM_TFLEARN_COURSE_ADD="Course: New"
+COM_TFLEARN_COURSE_EDIT="Course: Edit"
+COM_TFLEARN_COURSE_ID="Course ID"
+COM_TFLEARN_COURSE="Course"
+COM_TFLEARN_COURSE_TYPE="Course Type"
+COM_TFLEARN_COURSES="Courses"
+
+CON_TFLEARN_CUSTOM_MESSAGE="Custom Message"
+CON_TFLEARN_CUSTOM_REDIRECT="Custom Redirect"
+
+COM_TFLEARN_DEPEND="Depend"
+
+COM_TFLEARN_EMAIL="Email"
+COM_TFLEARN_ENROL="Enrol"
+COM_TFLEARN_ENROLMENT="Enrolment"
+COM_TFLEARN_EXPLANATION="Explanation"
+
+COM_TFLEARN_FRONT="Front"
+
+COM_TFLEARN_GRADE="Grade"
+COM_TFLEARN_GRADE_TYPE="Grade Type"
+
+COM_TFLEARN_IMAGE="Image"
+COM_TFLEARN_INTEGRATIONS="Integrations"
+
+COM_TFLEARN_JOOMLA_ARTICLE_ID="Joomla ID"
+
+COM_TFLEARN_LESSON_ADD="Lesson: New"
+COM_TFLEARN_LESSON_EDIT="Lesson: Edit"
+COM_TFLEARN_LESSONS="Lessons"
+COM_TFLEARN_LESSON="Lesson"
+COM_TFLEARN_LINK="Link"
+
+COM_TFLEARN_MARKS="Marks"
+
+COM_TFLEARN_MODULE_ADD="Module: New"
+COM_TFLEARN_MODULE_EDIT="Module: Edit"
+COM_TFLEARN_MODULE_ID="Module ID"
+COM_TFLEARN_MODULE="Module"
+COM_TFLEARN_MODULES="Modules"
+COM_TFLEARN_MULTIPLE_ATTEMPTS="Multiple Attempts"
+
+COM_TFLEARN_NEXT_DATE="Next Date"
+COM_TFLEARN_NOTIFICATIONS="Notifications"
+
+COM_TFLEARN_OPTION="Option"
+COM_TFLEARN_OPTION_REF="Option Reference"
+COM_TFLEARN_ORDERING="Ordering"
+
+COM_TFLEARN_ORDERING_COMPLETION_TYPE_ASC="Completion type ascending"
+COM_TFLEARN_ORDERING_COMPLETION_TYPE_DESC="Completion type descending"
+COM_TFLEARN_ORDERING_COURSE_TYPE_ASC="Type ascending"
+COM_TFLEARN_ORDERING_COURSE_TYPE_DESC="Type descending"
+COM_TFLEARN_ORDERING_CREATED_BY_ASC="User ID ascending"
+COM_TFLEARN_ORDERING_CREATED_BY_DESC="User ID descending"
+COM_TFLEARN_ORDERING_CREATED_ASC="Date ascending"
+COM_TFLEARN_ORDERING_CREATED_DESC="Date descending"
+COM_TFLEARN_ORDERING_FRONT_ASC="Front ascending"
+COM_TFLEARN_ORDERING_FRONT_DESC="Front descending"
+COM_TFLEARN_ORDERING_GRADE_ASC="Grade ascending"
+COM_TFLEARN_ORDERING_GRADE_DESC="Grade descending"
+COM_TFLEARN_ORDERING_GROUP_ID_ASC="Group ID ascending"
+COM_TFLEARN_ORDERING_GROUP_ID_DESC="Group ID descending"
+COM_TFLEARN_ORDERING_LESSON_TYPE_ASC="Type ascending"
+COM_TFLEARN_ORDERING_LESSON_TYPE_DESC="Type descending"
+COM_TFLEARN_ORDERING_LESSON_ASC="Lesson ascending"
+COM_TFLEARN_ORDERING_LESSON_DESC="Lesson descending"
+COM_TFLEARN_ORDERING_MOD_NAME_ASC="Module ascending"
+COM_TFLEARN_ORDERING_MOD_NAME_DESC="Module descending"
+COM_TFLEARN_ORDERING_Q_TYPE_ASC="Type ascending"
+COM_TFLEARN_ORDERING_Q_TYPE_DESC="Type descending"
+COM_TFLEARN_ORDERING_REF_ASC="Reference ascending"
+COM_TFLEARN_ORDERING_REF_DESC="Reference descending"
+COM_TFLEARN_ORDERING_USER_ID_ASC="User ID ascending"
+COM_TFLEARN_ORDERING_USER_ID_DESC="User ID descending"
+
+COM_TFLEARN_PAGE="Page"
+COM_TFLEARN_PAGES="Pages"
+COM_TFLEARN_PAGE_ADD="Page: New"
+COM_TFLEARN_PAGE_EDIT="Page: Edit"
+COM_TFLEARN_PATH="Path"
+COM_TFLEARN_PATHS="Paths"
+COM_TFLEARN_PERCENT="Percent"
+
+COM_TFLEARN_QUESTION_IDS="Question IDs"
+COM_TFLEARN_QUESTION="Question"
+COM_TFLEARN_QUESTIONS="Questions"
+COM_TFLEARN_QUESTION_ADD="Question: New"
+COM_TFLEARN_QUESTION_EDIT="Question: Edit"
+COM_TFLEARN_QUESTION_SOURCE="Question Source"
+
+COM_TFLEARN_REFERENCE="Reference"
+COM_TFLEARN_RESOURCES="Resources"
+COM_TFLEARN_REQUIRED="Required"
+
+COM_TFLEARN_SCORE="Score"
+COM_TFLEARN_SCORES="Scores"
+COM_TFLEARN_SCORE_EDIT="Score: Edit"
+
+COM_TFLEARN_SELECT_MODULE="Select Module"
+COM_TFLEARN_SHOW_TITLE="Show Title"
+COM_TFLEARN_SHOW_CAPTCHA="Show Captcha"
+COM_TFLEARN_SEO="SEO"
+COM_TFLEARN_SHORT_DESC="Short Description"
+COM_TFLEARN_START_DATE="Start Date"
+
+COM_TFLEARN_TAGS="Tags"
+COM_TFLEARN_TARGET_WINDOW="Target Window"
+COM_TFLEARN_TEST="Test"
+
+COM_TFLEARN_USER_ID="User ID"
+COM_TFLEARN_USER="User"
+COM_TFLEARN_USERS="Users"
+COM_TFLEARN_USER_GROUP="User Group"
+
+COM_TFLEARN_VALUE="Value"
+
+; Emptystate
+COM_TFLEARN_COURSES_EMPTYSTATE_CONTENT="Courses are main learning areas. Courses contain lessons organised in modules."
+COM_TFLEARN_COURSES_EMPTYSTATE_BUTTON_ADD="Add your first course"
+COM_TFLEARN_MODULES_EMPTYSTATE_CONTENT="Modules are way of organising lessons in the course. They are in between courses and lessons. One module can be used in multiple courses."
+COM_TFLEARN_MODULES_EMPTYSTATE_BUTTON_ADD="Add your first module"
+COM_TFLEARN_LESSONS_EMPTYSTATE_CONTENT="Lessons are like chapters. Lessons can contain text, pages, Joomla articles, external links or quiz."
+COM_TFLEARN_LESSONS_EMPTYSTATE_BUTTON_ADD="Add your first lesson"
+COM_TFLEARN_PAGES_EMPTYSTATE_CONTENT="Pages are basic learning units which are used to create lessons."
+COM_TFLEARN_PAGES_EMPTYSTATE_BUTTON_ADD="Add your first page"
+COM_TFLEARN_QUESTIONS_EMPTYSTATE_CONTENT="You can add a test or a quiz to a lesson by adding questions."
+COM_TFLEARN_QUESTIONS_EMPTYSTATE_BUTTON_ADD="Add your first question"
+COM_TFLEARN_COMPLETIONS_EMPTYSTATE_CONTENT="Here you can see the status of the lessons completed by the users and the score obtained."
+COM_TFLEARN_SCORES_EMPTYSTATE_CONTENT="Here, you can see all the attempts of the tests or quizzes."
+
+; Managers
+COM_TFLEARN_MANAGER_CONFIGURATION="TF Learn: Configuration"
+COM_TFLEARN_MANAGER_DASHBOARD="TF Learn: Dashboard"
+COM_TFLEARN_MANAGER_COURSES="TF Learn: Courses"
+COM_TFLEARN_MANAGER_MODULES="TF Learn: Modules"
+COM_TFLEARN_MANAGER_LESSONS="TF Learn: Lessons"
+COM_TFLEARN_MANAGER_PAGES="TF Learn: Pages"
+COM_TFLEARN_MANAGER_QUESTIONS="TF Learn: Questions"
+COM_TFLEARN_MANAGER_COMPLETIONS="TF Learn: Completions"
+COM_TFLEARN_MANAGER_SCORES="TF Learn: Scores"
+
+; Ordering
+COM_TFLEARN_COURSE_ASC="Course ascending"
+COM_TFLEARN_COURSE_DESC="Course descending"
+COM_TFLEARN_CREATED_ASC="Course ascending"
+COM_TFLEARN_CREATED_DESC="Course descending"
+COM_TFLEARN_LESSON_ASC="Lesson ascending"
+COM_TFLEARN_LESSON_DESC="Lesson descending"
+COM_TFLEARN_MODULE_ASC="Module ascending"
+COM_TFLEARN_MODULE_DESC="Module descending"
+COM_TFLEARN_ORDERING_ASC="Ordering ascending"
+COM_TFLEARN_ORDERING_DESC="Odering descending"
+COM_TFLEARN_PUBLISHED_ASC="Status ascending"
+COM_TFLEARN_PUBLISHED_DESC="Status descending"
+COM_TFLEARN_TITLE_ASC="Title ascending"
+COM_TFLEARN_TITLE_DESC="Title descending"
+COM_TFLEARN_TYPE_ASC="Type ascending"
+COM_TFLEARN_TYPE_DESC="Type descending"
+COM_TFLEARN_USER_ASC="User ascending"
+COM_TFLEARN_USER_DESC="User descending"
+
+; Configuration
+COM_TFLEARN_CONFIG_COURSES_DESC="These settings apply for courses view."
+COM_TFLEARN_CONFIG_COURSE_DESC="These settings apply for single course view."
+COM_TFLEARN_CONFIG_PATHS_DESC="These settings apply for learning paths (all courses user is enrolled in) view."
+COM_TFLEARN_CONFIG_PATH_DESC="These settings apply for single learning path view."
+COM_TFLEARN_CONFIG_PAGE_DESC="These settings apply for single page view."
+COM_TFLEARN_CONFIG_ENROL_DESC="These settings apply for enrolment form view."
+COM_TFLEARN_CONFIG_TEST_DESC="These settings apply for test or quiz view."
+COM_TFLEARN_CONFIG_INTEGRATIONS_DESC="These settings determine how the component will integrate with other extensions."
+COM_TFLEARN_CONFIG_NOTIFICATIONS_DESC="These settings are for email notifications."
+COM_TFLEARN_CONFIG_SEO_DESC="These settings are for SEO for search results."
+
+COM_TFLEARN_N_ITEMS_DELETED_1="One item deleted"
+COM_TFLEARN_N_ITEMS_DELETED_MORE="%d items deleted"
+COM_TFLEARN_N_ITEMS_PUBLISHED="%d item(s) published"
+COM_TFLEARN_N_ITEMS_UNPUBLISHED="%d item(s) unpublished"
\ No newline at end of file
diff --git a/deployed/tflearn/administrator/components/com_tflearn/language/en-GB/en-GB.com_tflearn.sys.ini b/deployed/tflearn/administrator/components/com_tflearn/language/en-GB/en-GB.com_tflearn.sys.ini
new file mode 100644
index 00000000..c3e4d08f
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/language/en-GB/en-GB.com_tflearn.sys.ini
@@ -0,0 +1,29 @@
+COM_TFLEARN="TF Learn"
+COM_TFLEARN_DESC="Joomla component for Learning Management System"
+
+COM_TFLEARN_MENU="TF Learn"
+
+COM_TFLEARN_SUBMENU_DASHBOARD="Dashboard"
+COM_TFLEARN_SUBMENU_COURSES="Courses"
+COM_TFLEARN_SUBMENU_MODULES="Modules"
+COM_TFLEARN_SUBMENU_LESSONS="Lessons"
+COM_TFLEARN_SUBMENU_PAGES="Pages"
+COM_TFLEARN_SUBMENU_QUESTIONS="Questions"
+COM_TFLEARN_SUBMENU_COMPLETIONS="Completions"
+COM_TFLEARN_SUBMENU_SCORES="Scores"
+
+; Frontend Menu Views
+COM_TFLEARN_ENROL_FORM_VIEW_TITLE="Enrol"
+COM_TFLEARN_ENROL_FORM_VIEW_DESC="Create enrolment form to enrol users in the course."
+
+; Frontend Menu Options
+COM_TFLEARN_SHOW_CAPTCHA="Show Captcha"
+COM_TFLEARN_BUTTON_CAPTION="Button Caption"
+CON_TFLEARN_BUTTON_CLASS="Button Class"
+CON_TFLEARN_CUSTOM_REDIRECT="Custom Redirect"
+CON_TFLEARN_CUSTOM_MESSAGE="Custom Message"
+COM_TFLEARN_SHOW_COURSE_TITLE="Course Title"
+COM_TFLEARN_SHOW_COURSE_DESCRIPTION="Course Description"
+
+; Configuration
+COM_TFLEARN_CONFIGURATION="TF Learn: Options"
\ No newline at end of file
diff --git a/deployed/tflearn/administrator/components/com_tflearn/script.php b/deployed/tflearn/administrator/components/com_tflearn/script.php
new file mode 100644
index 00000000..6ed5f571
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/script.php
@@ -0,0 +1,61 @@
+getParent()->setRedirectURL('index.php?option=' . $this->extension);
+ }
+
+ // 02. Called after component is updated
+ public function update(InstallerAdapter $adapter)
+ {
+ $adapter->getParent()->setRedirectURL('index.php?option=' . $this->extension);
+
+ $new_version = $adapter->getManifest()->version;
+ }
+
+ // 03. Called before installation
+ public function preflight($type, InstallerAdapter $adapter)
+ {
+ if ($type == 'update')
+ {
+ foreach ($this->admin_folders as $admin_folder)
+ {
+ $path = JPATH_ADMINISTRATOR . '/components/' . $this->extension . '/' . $admin_folder;
+ if (Folder::exists($path))
+ {
+ Folder::delete($path);
+ }
+ }
+
+ foreach ($this->site_folders as $site_folder)
+ {
+ $path = JPATH_SITE . '/components/' . $this->extension . '/' . $site_folder;
+ if (Folder::exists($path))
+ {
+ Folder::delete($path);
+ }
+ }
+ }
+
+ return true;
+ }
+}
\ No newline at end of file
diff --git a/deployed/tflearn/administrator/components/com_tflearn/services/provider.php b/deployed/tflearn/administrator/components/com_tflearn/services/provider.php
new file mode 100644
index 00000000..634abed1
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/services/provider.php
@@ -0,0 +1,47 @@
+registerServiceProvider(new MVCFactory('\\TechFry\\Component\\TfLearn'));
+ $container->registerServiceProvider(new ComponentDispatcherFactory('\\TechFry\\Component\\TfLearn'));
+ $container->registerServiceProvider(new CategoryFactory('\\TechFry\\Component\\TfLearn'));
+ $container->registerServiceProvider(new RouterFactory('\\TechFry\\Component\\TfLearn'));
+
+ $container->set(
+ ComponentInterface::class,
+ function (Container $container)
+ {
+ $component = new TfLearnComponent($container->get(ComponentDispatcherFactoryInterface::class));
+
+ $component->setMVCFactory($container->get(MVCFactoryInterface::class));
+ $component->setCategoryFactory($container->get(CategoryFactoryInterface::class));
+ $component->setRouterFactory($container->get(RouterFactoryInterface::class));
+
+ return $component;
+ }
+ );
+ }
+};
\ No newline at end of file
diff --git a/deployed/tflearn/administrator/components/com_tflearn/sql/install.mysql.utf8.sql b/deployed/tflearn/administrator/components/com_tflearn/sql/install.mysql.utf8.sql
new file mode 100644
index 00000000..c6b9e6f6
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/sql/install.mysql.utf8.sql
@@ -0,0 +1,150 @@
+CREATE TABLE IF NOT EXISTS `#__tfl_courses` (
+ `id` INT(11) NOT NULL AUTO_INCREMENT,
+ `title` VARCHAR(400),
+ `alias` VARCHAR(400),
+ `image` VARCHAR(400),
+ `published` TINYINT(3),
+ `description` TEXT,
+ `short_desc` VARCHAR(400),
+ `course_type` VARCHAR(400),
+ `front` TINYINT(3),
+ `group_id` INT(10),
+ `modules` TEXT,
+ `enrol` VARCHAR(100),
+ `enrol_link` VARCHAR(400),
+ `ordering` INT(11),
+ `created` DATETIME,
+ `modified` DATETIME,
+ `created_by` INT(10),
+ `hits` INT(10) UNSIGNED,
+ `access` tinyint(4) NOT NULL DEFAULT '0',
+ PRIMARY KEY (`id`)
+)
+ ENGINE=InnoDB
+ AUTO_INCREMENT=0
+ DEFAULT CHARSET=utf8mb4;
+
+CREATE TABLE IF NOT EXISTS `#__tfl_modules` (
+ `id` INT(11) NOT NULL AUTO_INCREMENT,
+ `title` VARCHAR(400),
+ `description` TEXT,
+ `published` TINYINT(3),
+ `created` DATETIME,
+ `modified` DATETIME,
+ `created_by` INT(10),
+ PRIMARY KEY (`id`)
+)
+ ENGINE=InnoDB
+ AUTO_INCREMENT=0
+ DEFAULT CHARSET=utf8mb4;
+
+CREATE TABLE IF NOT EXISTS `#__tfl_lessons` (
+ `id` INT(11) NOT NULL AUTO_INCREMENT,
+ `title` VARCHAR(400),
+ `description` TEXT,
+ `short_desc` VARCHAR(1000),
+ `lesson_type` VARCHAR(400),
+ `completion_type` VARCHAR(400),
+ `jids` TEXT,
+ `content_source` VARCHAR(255),
+ `resources` TEXT,
+ `questions` TINYINT(3),
+ `marks` TINYINT(3),
+ `pass_percent` TINYINT(3),
+ `multiple_attempts` TINYINT(3),
+ `grade_type` VARCHAR(100),
+ `attempt_gap` TINYINT(3),
+ `ref` VARCHAR(100),
+ `published` TINYINT(3),
+ `module` INT(11),
+ `created` DATETIME,
+ `modified` DATETIME,
+ `created_by` INT(10),
+ `ordering` INT(11),
+ `hits` INT(10) UNSIGNED,
+ PRIMARY KEY (`id`)
+)
+ ENGINE=InnoDB
+ AUTO_INCREMENT=0
+ DEFAULT CHARSET=utf8mb4;
+
+CREATE TABLE IF NOT EXISTS `#__tfl_pages` (
+ `id` INT(11) NOT NULL AUTO_INCREMENT,
+ `title` VARCHAR(400),
+ `alias` VARCHAR(400),
+ `published` TINYINT(3),
+ `description` TEXT,
+ `created` DATETIME,
+ `modified` DATETIME,
+ `created_by` INT(10),
+ `note` VARCHAR(255),
+ `hits` INT(10) UNSIGNED,
+ `ref` VARCHAR(100),
+ PRIMARY KEY (`id`)
+)
+ ENGINE=InnoDB
+ AUTO_INCREMENT=0
+ DEFAULT CHARSET=utf8mb4;
+
+CREATE TABLE IF NOT EXISTS `#__tfl_questions` (
+ `id` INT(11) NOT NULL AUTO_INCREMENT,
+ `title` VARCHAR(400),
+ `alias` VARCHAR(400),
+ `published` TINYINT(3),
+ `lesson_id` INT(11),
+ `description` TEXT,
+ `q_type` VARCHAR(400),
+ `options` MEDIUMTEXT,
+ `matching` MEDIUMTEXT,
+ `answer` VARCHAR(400),
+ `explanation` TEXT,
+ `depend` TINYINT(3),
+ `created` DATETIME,
+ `modified` DATETIME,
+ `created_by` INT(10),
+ PRIMARY KEY (`id`)
+)
+ ENGINE=InnoDB
+ AUTO_INCREMENT=0
+ DEFAULT CHARSET=utf8mb4;
+
+CREATE TABLE IF NOT EXISTS `#__tfl_scores` (
+ `id` INT(11) NOT NULL AUTO_INCREMENT,
+ `published` TINYINT(3),
+ `lesson_id` INT(11),
+ `created_by` INT(11),
+ `email` VARCHAR(400),
+ `attempts` TEXT,
+ `grade` TINYINT(11),
+ `created` DATETIME,
+ `modified` DATETIME,
+ `hits` INT(10) UNSIGNED,
+ PRIMARY KEY (`id`)
+)
+ ENGINE=InnoDB
+ AUTO_INCREMENT=0
+ DEFAULT CHARSET=utf8mb4;
+
+CREATE TABLE IF NOT EXISTS `#__tfl_completion` (
+ `id` INT(11) NOT NULL AUTO_INCREMENT,
+ `published` TINYINT(3),
+ `lesson_id` INT(11),
+ `user_id` INT(11),
+ `complete` TINYINT(3),
+ `created` DATETIME,
+ `modified` DATETIME,
+ PRIMARY KEY (`id`)
+)
+ ENGINE=InnoDB
+ AUTO_INCREMENT=0
+ DEFAULT CHARSET=utf8mb4;
+
+CREATE TABLE IF NOT EXISTS `#__mentor_map` (
+ `course_id` INT(10) UNSIGNED DEFAULT 0,
+ `mentor_id` INT(10) UNSIGNED DEFAULT 0,
+ `student_id` INT(10) UNSIGNED DEFAULT 0,
+ PRIMARY KEY(`course_id`, `mentor_id`, `student_id`)
+)
+ ENGINE=InnoDB
+ DEFAULT CHARSET=utf8mb4
+ DEFAULT COLLATE=utf8mb4_unicode_ci;
\ No newline at end of file
diff --git a/deployed/tflearn/administrator/components/com_tflearn/sql/uninstall.mysql.utf8.sql b/deployed/tflearn/administrator/components/com_tflearn/sql/uninstall.mysql.utf8.sql
new file mode 100644
index 00000000..e69de29b
diff --git a/deployed/tflearn/administrator/components/com_tflearn/sql/updates/mysql/1.0.3.sql b/deployed/tflearn/administrator/components/com_tflearn/sql/updates/mysql/1.0.3.sql
new file mode 100644
index 00000000..e2dd95c3
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/sql/updates/mysql/1.0.3.sql
@@ -0,0 +1 @@
+ALTER TABLE `#__tfl_courses` ADD `alias` VARCHAR(400) AFTER `title`;
\ No newline at end of file
diff --git a/deployed/tflearn/administrator/components/com_tflearn/sql/updates/mysql/1.0.4.sql b/deployed/tflearn/administrator/components/com_tflearn/sql/updates/mysql/1.0.4.sql
new file mode 100644
index 00000000..bcc0eb73
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/sql/updates/mysql/1.0.4.sql
@@ -0,0 +1,3 @@
+ALTER TABLE `#__tfl_courses` ADD `ordering` INT(11);
+
+ALTER TABLE `#__tfl_lessons` ADD `ordering` INT(11);
\ No newline at end of file
diff --git a/deployed/tflearn/administrator/components/com_tflearn/sql/updates/mysql/1.0.8.sql b/deployed/tflearn/administrator/components/com_tflearn/sql/updates/mysql/1.0.8.sql
new file mode 100644
index 00000000..11763171
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/sql/updates/mysql/1.0.8.sql
@@ -0,0 +1 @@
+ALTER TABLE `#__tfl_courses` ADD `short_desc` VARCHAR(400) AFTER `description`;
\ No newline at end of file
diff --git a/deployed/tflearn/administrator/components/com_tflearn/sql/updates/mysql/1.1.1.sql b/deployed/tflearn/administrator/components/com_tflearn/sql/updates/mysql/1.1.1.sql
new file mode 100644
index 00000000..e69de29b
diff --git a/deployed/tflearn/administrator/components/com_tflearn/sql/updates/mysql/1.1.4.sql b/deployed/tflearn/administrator/components/com_tflearn/sql/updates/mysql/1.1.4.sql
new file mode 100644
index 00000000..b869dcac
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/sql/updates/mysql/1.1.4.sql
@@ -0,0 +1,23 @@
+ALTER TABLE `#__tfl_courses` ADD `created` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00' AFTER `ordering`;
+
+ALTER TABLE `#__tfl_courses` ADD `modified` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00' AFTER `created`;
+
+ALTER TABLE `#__tfl_courses` ADD `access` tinyint(4) NOT NULL DEFAULT '0' AFTER `modified`;
+
+ALTER TABLE `#__tfl_modules` ADD `created` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00' AFTER `published`;
+
+ALTER TABLE `#__tfl_modules` ADD `modified` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00' AFTER `created`;
+
+ALTER TABLE `#__tfl_lessons` ADD `created` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00' AFTER `module`;
+
+ALTER TABLE `#__tfl_lessons` ADD `modified` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00' AFTER `created`;
+
+ALTER TABLE `#__tfl_pathways` ADD `created` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00' AFTER `published`;
+
+ALTER TABLE `#__tfl_pathways` ADD `modified` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00' AFTER `created`;
+
+ALTER TABLE `#__tfl_config` ADD `courses` MEDIUMTEXT AFTER `id`;
+
+ALTER TABLE `#__tfl_config` ADD `paths` MEDIUMTEXT AFTER `courses`;
+
+ALTER TABLE `#__tfl_config` ADD `enrol` MEDIUMTEXT AFTER `paths`;
\ No newline at end of file
diff --git a/deployed/tflearn/administrator/components/com_tflearn/sql/updates/mysql/1.1.7.sql b/deployed/tflearn/administrator/components/com_tflearn/sql/updates/mysql/1.1.7.sql
new file mode 100644
index 00000000..c68bd6cf
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/sql/updates/mysql/1.1.7.sql
@@ -0,0 +1,35 @@
+CREATE TABLE IF NOT EXISTS `#__tfl_questions` (
+ `id` INT(11) NOT NULL AUTO_INCREMENT,
+ `title` VARCHAR(400),
+ `alias` VARCHAR(400),
+ `published` TINYINT(3),
+ `lesson_id` INT(11),
+ `description` TEXT,
+ `q_type` VARCHAR(400),
+ `options` MEDIUMTEXT,
+ `answer` VARCHAR(400),
+ `explain` TEXT,
+ `depend` TINYINT(3),
+ `marks` TINYINT(3),
+ `created` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
+ `modified` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
+ PRIMARY KEY (id)
+)
+ ENGINE=InnoDB
+ AUTO_INCREMENT=0
+ DEFAULT CHARSET=utf8mb4;
+
+CREATE TABLE IF NOT EXISTS `#__tfl_scores` (
+ `id` INT(11) NOT NULL AUTO_INCREMENT,
+ `published` TINYINT(3),
+ `lesson_id` INT(11),
+ `user_id` INT(11),
+ `attempts` TEXT,
+ `grade` TINYINT(11),
+ `created` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
+ `modified` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
+ PRIMARY KEY (id)
+)
+ ENGINE=InnoDB
+ AUTO_INCREMENT=0
+ DEFAULT CHARSET=utf8mb4;
\ No newline at end of file
diff --git a/deployed/tflearn/administrator/components/com_tflearn/sql/updates/mysql/1.1.8.sql b/deployed/tflearn/administrator/components/com_tflearn/sql/updates/mysql/1.1.8.sql
new file mode 100644
index 00000000..d4affcce
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/sql/updates/mysql/1.1.8.sql
@@ -0,0 +1 @@
+ALTER TABLE `#__tfl_config` ADD `test` MEDIUMTEXT AFTER `enrol`;
\ No newline at end of file
diff --git a/deployed/tflearn/administrator/components/com_tflearn/sql/updates/mysql/1.1.9.sql b/deployed/tflearn/administrator/components/com_tflearn/sql/updates/mysql/1.1.9.sql
new file mode 100644
index 00000000..68840dd3
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/sql/updates/mysql/1.1.9.sql
@@ -0,0 +1,9 @@
+ALTER TABLE `#__tfl_config` ADD `path` MEDIUMTEXT AFTER `paths`;
+
+ALTER TABLE `#__tfl_config` ADD `course` MEDIUMTEXT AFTER `courses`;
+
+ALTER TABLE `#__tfl_config` ADD `attempts` MEDIUMTEXT AFTER `enrol`;
+
+ALTER TABLE `#__tfl_config` ADD `attempt` MEDIUMTEXT AFTER `attempts`;
+
+ALTER TABLE `#__tfl_scores` ADD `email` VARCHAR(400) AFTER `user_id`;
\ No newline at end of file
diff --git a/deployed/tflearn/administrator/components/com_tflearn/sql/updates/mysql/1.2.0.sql b/deployed/tflearn/administrator/components/com_tflearn/sql/updates/mysql/1.2.0.sql
new file mode 100644
index 00000000..37463ec0
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/sql/updates/mysql/1.2.0.sql
@@ -0,0 +1,3 @@
+ALTER TABLE `#__tfl_lessons` ADD `questions` TINYINT(3) AFTER `lesson_type`;
+
+ALTER TABLE `#__tfl_lessons` ADD `marks` TINYINT(3) AFTER `questions`;
\ No newline at end of file
diff --git a/deployed/tflearn/administrator/components/com_tflearn/sql/updates/mysql/1.2.2.sql b/deployed/tflearn/administrator/components/com_tflearn/sql/updates/mysql/1.2.2.sql
new file mode 100644
index 00000000..e69de29b
diff --git a/deployed/tflearn/administrator/components/com_tflearn/sql/updates/mysql/1.2.4.sql b/deployed/tflearn/administrator/components/com_tflearn/sql/updates/mysql/1.2.4.sql
new file mode 100644
index 00000000..088f6351
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/sql/updates/mysql/1.2.4.sql
@@ -0,0 +1,17 @@
+CREATE TABLE IF NOT EXISTS `#__tfl_completion` (
+ `id` INT(11) NOT NULL AUTO_INCREMENT,
+ `published` TINYINT(3),
+ `lesson_id` INT(11),
+ `user_id` INT(11),
+ `complete` TINYINT(3),
+ `created` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
+ `modified` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
+ PRIMARY KEY (id)
+)
+ ENGINE=InnoDB
+ AUTO_INCREMENT=0
+ DEFAULT CHARSET=utf8mb4;
+
+ALTER TABLE `#__tfl_lessons` DROP COLUMN `jid`;
+
+ALTER TABLE `#__tfl_lessons` ADD COLUMN `jids` TEXT AFTER `lesson_type`;
\ No newline at end of file
diff --git a/deployed/tflearn/administrator/components/com_tflearn/sql/updates/mysql/1.2.6.sql b/deployed/tflearn/administrator/components/com_tflearn/sql/updates/mysql/1.2.6.sql
new file mode 100644
index 00000000..e69de29b
diff --git a/deployed/tflearn/administrator/components/com_tflearn/sql/updates/mysql/1.2.8.sql b/deployed/tflearn/administrator/components/com_tflearn/sql/updates/mysql/1.2.8.sql
new file mode 100644
index 00000000..82479c93
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/sql/updates/mysql/1.2.8.sql
@@ -0,0 +1 @@
+ALTER TABLE `#__tfl_lessons` ADD COLUMN `completion_type` VARCHAR(400) AFTER `lesson_type`;
\ No newline at end of file
diff --git a/deployed/tflearn/administrator/components/com_tflearn/sql/updates/mysql/1.2.9.sql b/deployed/tflearn/administrator/components/com_tflearn/sql/updates/mysql/1.2.9.sql
new file mode 100644
index 00000000..e69de29b
diff --git a/deployed/tflearn/administrator/components/com_tflearn/sql/updates/mysql/1.3.0.sql b/deployed/tflearn/administrator/components/com_tflearn/sql/updates/mysql/1.3.0.sql
new file mode 100644
index 00000000..c4b80954
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/sql/updates/mysql/1.3.0.sql
@@ -0,0 +1,3 @@
+ALTER TABLE `#__tfl_courses` ADD COLUMN `group_id` INT(10) AFTER `front`;
+
+ALTER TABLE `#__tfl_courses` DROP COLUMN `tfmail`;
\ No newline at end of file
diff --git a/deployed/tflearn/administrator/components/com_tflearn/sql/updates/mysql/1.3.2.sql b/deployed/tflearn/administrator/components/com_tflearn/sql/updates/mysql/1.3.2.sql
new file mode 100644
index 00000000..8ba68890
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/sql/updates/mysql/1.3.2.sql
@@ -0,0 +1 @@
+DROP TABLE `#__tfl_pathways`;
\ No newline at end of file
diff --git a/deployed/tflearn/administrator/components/com_tflearn/sql/updates/mysql/1.3.4.sql b/deployed/tflearn/administrator/components/com_tflearn/sql/updates/mysql/1.3.4.sql
new file mode 100644
index 00000000..ec5eb16e
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/sql/updates/mysql/1.3.4.sql
@@ -0,0 +1,7 @@
+ALTER TABLE `#__tfl_courses` ADD `created_by` INT(10) AFTER `modified`;
+
+ALTER TABLE `#__tfl_modules` ADD `created_by` INT(10) AFTER `modified`;
+
+ALTER TABLE `#__tfl_lessons` ADD `created_by` INT(10) AFTER `modified`;
+
+ALTER TABLE `#__tfl_questions` ADD `created_by` INT(10) AFTER `modified`;
\ No newline at end of file
diff --git a/deployed/tflearn/administrator/components/com_tflearn/sql/updates/mysql/1.3.7.sql b/deployed/tflearn/administrator/components/com_tflearn/sql/updates/mysql/1.3.7.sql
new file mode 100644
index 00000000..efecbe07
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/sql/updates/mysql/1.3.7.sql
@@ -0,0 +1 @@
+ALTER TABLE `#__tfl_lessons` ADD COLUMN `short_desc` VARCHAR(1000) AFTER `description`;
\ No newline at end of file
diff --git a/deployed/tflearn/administrator/components/com_tflearn/sql/updates/mysql/1.3.9.sql b/deployed/tflearn/administrator/components/com_tflearn/sql/updates/mysql/1.3.9.sql
new file mode 100644
index 00000000..a204e535
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/sql/updates/mysql/1.3.9.sql
@@ -0,0 +1 @@
+ALTER TABLE `#__tfl_lessons` ADD COLUMN `pass_percent` TINYINT(3) AFTER `marks`;
\ No newline at end of file
diff --git a/deployed/tflearn/administrator/components/com_tflearn/sql/updates/mysql/1.4.0.sql b/deployed/tflearn/administrator/components/com_tflearn/sql/updates/mysql/1.4.0.sql
new file mode 100644
index 00000000..e69de29b
diff --git a/deployed/tflearn/administrator/components/com_tflearn/sql/updates/mysql/1.4.1.sql b/deployed/tflearn/administrator/components/com_tflearn/sql/updates/mysql/1.4.1.sql
new file mode 100644
index 00000000..1bb47ea9
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/sql/updates/mysql/1.4.1.sql
@@ -0,0 +1 @@
+ALTER TABLE `#__tfl_questions` CHANGE `explain` `explanation` TEXT;
\ No newline at end of file
diff --git a/deployed/tflearn/administrator/components/com_tflearn/sql/updates/mysql/1.4.4.sql b/deployed/tflearn/administrator/components/com_tflearn/sql/updates/mysql/1.4.4.sql
new file mode 100644
index 00000000..c4e30aed
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/sql/updates/mysql/1.4.4.sql
@@ -0,0 +1,17 @@
+ALTER TABLE `#__tfl_lessons` DROP COLUMN `qsource`;
+
+ALTER TABLE `#__tfl_lessons` DROP COLUMN `qids`;
+
+ALTER TABLE `#__tfl_questions` DROP COLUMN `marks`;
+
+ALTER TABLE `#__tfl_lessons` ADD COLUMN `multiple_attempts` TINYINT(3) AFTER `pass_percent`;
+
+ALTER TABLE `#__tfl_lessons` ADD COLUMN `grade_type` VARCHAR(100) AFTER `multiple_attempts`;
+
+ALTER TABLE `#__tfl_lessons` ADD COLUMN `attempt_gap` TINYINT(3) AFTER `grade_type`;
+
+ALTER TABLE `#__tfl_lessons` ADD COLUMN `hits` INT(10) UNSIGNED AFTER `ordering`;
+
+ALTER TABLE `#__tfl_courses` ADD COLUMN `hits` INT(10) UNSIGNED AFTER `created_by`;
+
+ALTER TABLE `#__tfl_scores` ADD COLUMN `hits` INT(10) UNSIGNED AFTER `modified`;
\ No newline at end of file
diff --git a/deployed/tflearn/administrator/components/com_tflearn/sql/updates/mysql/1.4.5.sql b/deployed/tflearn/administrator/components/com_tflearn/sql/updates/mysql/1.4.5.sql
new file mode 100644
index 00000000..008cbe56
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/sql/updates/mysql/1.4.5.sql
@@ -0,0 +1 @@
+ALTER TABLE `#__tfl_scores` CHANGE `user_id` `created_by` INT(11);
\ No newline at end of file
diff --git a/deployed/tflearn/administrator/components/com_tflearn/sql/updates/mysql/1.4.8.sql b/deployed/tflearn/administrator/components/com_tflearn/sql/updates/mysql/1.4.8.sql
new file mode 100644
index 00000000..bddcf390
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/sql/updates/mysql/1.4.8.sql
@@ -0,0 +1 @@
+DROP TABLE `#__tfl_config`;
\ No newline at end of file
diff --git a/deployed/tflearn/administrator/components/com_tflearn/sql/updates/mysql/1.5.3.sql b/deployed/tflearn/administrator/components/com_tflearn/sql/updates/mysql/1.5.3.sql
new file mode 100644
index 00000000..b881f18c
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/sql/updates/mysql/1.5.3.sql
@@ -0,0 +1 @@
+ALTER TABLE `#__tfl_questions` ADD COLUMN `matching` MEDIUMTEXT AFTER `options`;
\ No newline at end of file
diff --git a/deployed/tflearn/administrator/components/com_tflearn/sql/updates/mysql/1.5.6.sql b/deployed/tflearn/administrator/components/com_tflearn/sql/updates/mysql/1.5.6.sql
new file mode 100644
index 00000000..e01aa04a
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/sql/updates/mysql/1.5.6.sql
@@ -0,0 +1,16 @@
+CREATE TABLE IF NOT EXISTS `#__tfl_pages` (
+ `id` INT(11) NOT NULL AUTO_INCREMENT,
+ `title` VARCHAR(400),
+ `alias` VARCHAR(400),
+ `published` TINYINT(3),
+ `description` TEXT,
+ `created` DATETIME,
+ `modified` DATETIME,
+ `created_by` INT(10),
+ `note` VARCHAR(255),
+ `hits` INT(10) UNSIGNED,
+ PRIMARY KEY (`id`)
+)
+ ENGINE=InnoDB
+ AUTO_INCREMENT=0
+ DEFAULT CHARSET=utf8mb4;
\ No newline at end of file
diff --git a/deployed/tflearn/administrator/components/com_tflearn/sql/updates/mysql/1.5.7.sql b/deployed/tflearn/administrator/components/com_tflearn/sql/updates/mysql/1.5.7.sql
new file mode 100644
index 00000000..a11e6d16
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/sql/updates/mysql/1.5.7.sql
@@ -0,0 +1 @@
+ALTER TABLE `#__tfl_lessons` ADD COLUMN `content_source` VARCHAR(255) AFTER `jids`;
\ No newline at end of file
diff --git a/deployed/tflearn/administrator/components/com_tflearn/sql/updates/mysql/1.6.7.sql b/deployed/tflearn/administrator/components/com_tflearn/sql/updates/mysql/1.6.7.sql
new file mode 100644
index 00000000..aadd11eb
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/sql/updates/mysql/1.6.7.sql
@@ -0,0 +1,9 @@
+CREATE TABLE IF NOT EXISTS `#__mentor_map` (
+ `course_id` INT(10) UNSIGNED DEFAULT 0,
+ `mentor_id` INT(10) UNSIGNED DEFAULT 0,
+ `student_id` INT(10) UNSIGNED DEFAULT 0,
+ PRIMARY KEY(`course_id`, `mentor_id`, `student_id`)
+)
+ ENGINE=InnoDB
+ DEFAULT CHARSET=utf8mb4
+ DEFAULT COLLATE=utf8mb4_unicode_ci;
\ No newline at end of file
diff --git a/deployed/tflearn/administrator/components/com_tflearn/sql/updates/mysql/1.7.1.sql b/deployed/tflearn/administrator/components/com_tflearn/sql/updates/mysql/1.7.1.sql
new file mode 100644
index 00000000..13ae947d
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/sql/updates/mysql/1.7.1.sql
@@ -0,0 +1,7 @@
+ALTER TABLE `#__tfl_lessons` DROP COLUMN `link`;
+
+ALTER TABLE `#__tfl_lessons` ADD COLUMN `resources` TEXT AFTER `content_source`;
+
+ALTER TABLE `#__tfl_lessons` ADD COLUMN `ref` VARCHAR(100) AFTER `attempt_gap`;
+
+ALTER TABLE `#__tfl_pages` ADD COLUMN `ref` VARCHAR(100) AFTER `hits`;
\ No newline at end of file
diff --git a/deployed/tflearn/administrator/components/com_tflearn/src/Controller/CompletionController.php b/deployed/tflearn/administrator/components/com_tflearn/src/Controller/CompletionController.php
new file mode 100644
index 00000000..559c122e
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/src/Controller/CompletionController.php
@@ -0,0 +1,16 @@
+ true))
+ {
+ $model = parent::getModel($name, $prefix, $config);
+
+ return $model;
+ }
+}
\ No newline at end of file
diff --git a/deployed/tflearn/administrator/components/com_tflearn/src/Controller/CourseController.php b/deployed/tflearn/administrator/components/com_tflearn/src/Controller/CourseController.php
new file mode 100644
index 00000000..b224916a
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/src/Controller/CourseController.php
@@ -0,0 +1,16 @@
+ true))
+ {
+ $model = parent::getModel($name, $prefix, $config);
+
+ return $model;
+ }
+}
\ No newline at end of file
diff --git a/deployed/tflearn/administrator/components/com_tflearn/src/Controller/DisplayController.php b/deployed/tflearn/administrator/components/com_tflearn/src/Controller/DisplayController.php
new file mode 100644
index 00000000..033a2fd1
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/src/Controller/DisplayController.php
@@ -0,0 +1,21 @@
+ true))
+ {
+ $model = parent::getModel($name, $prefix, $config);
+
+ return $model;
+ }
+}
\ No newline at end of file
diff --git a/deployed/tflearn/administrator/components/com_tflearn/src/Controller/ModuleController.php b/deployed/tflearn/administrator/components/com_tflearn/src/Controller/ModuleController.php
new file mode 100644
index 00000000..92b176f3
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/src/Controller/ModuleController.php
@@ -0,0 +1,16 @@
+ true))
+ {
+ $model = parent::getModel($name, $prefix, $config);
+
+ return $model;
+ }
+}
\ No newline at end of file
diff --git a/deployed/tflearn/administrator/components/com_tflearn/src/Controller/PageController.php b/deployed/tflearn/administrator/components/com_tflearn/src/Controller/PageController.php
new file mode 100644
index 00000000..1b20f73e
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/src/Controller/PageController.php
@@ -0,0 +1,16 @@
+ true))
+ {
+ $model = parent::getModel($name, $prefix, $config);
+
+ return $model;
+ }
+}
\ No newline at end of file
diff --git a/deployed/tflearn/administrator/components/com_tflearn/src/Controller/QueryController.php b/deployed/tflearn/administrator/components/com_tflearn/src/Controller/QueryController.php
new file mode 100644
index 00000000..76a03c30
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/src/Controller/QueryController.php
@@ -0,0 +1,16 @@
+ true))
+ {
+ $model = parent::getModel($name, $prefix, $config);
+
+ return $model;
+ }
+}
\ No newline at end of file
diff --git a/deployed/tflearn/administrator/components/com_tflearn/src/Controller/ScoreController.php b/deployed/tflearn/administrator/components/com_tflearn/src/Controller/ScoreController.php
new file mode 100644
index 00000000..3997f69c
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/src/Controller/ScoreController.php
@@ -0,0 +1,16 @@
+ true))
+ {
+ $model = parent::getModel($name, $prefix, $config);
+
+ return $model;
+ }
+}
\ No newline at end of file
diff --git a/deployed/tflearn/administrator/components/com_tflearn/src/Extension/TfLearnComponent.php b/deployed/tflearn/administrator/components/com_tflearn/src/Extension/TfLearnComponent.php
new file mode 100644
index 00000000..05f8b5b8
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/src/Extension/TfLearnComponent.php
@@ -0,0 +1,33 @@
+table_name = 'tfl_completion';
+
+ $this->subform_fields = array('modules');
+
+ parent::__construct($config);
+ }
+
+// *****************************************************************************
+
+ // 01. Get latest score for lesson and user (Check its usage and shift to Helper)
+ public function getScore($user_id, $lesson_id)
+ {
+ $db = Factory::getDbo();
+ $query = $db->getQuery(true);
+
+ $query
+ ->select($db->quoteName(array('grade')))
+ ->from($db->quoteName('#__tfl_scores'))
+ ->where($db->quoteName('user_id') . ' = '. $db->quote($user_id))
+ ->andWhere($db->quoteName('lesson_id') . ' = '. $db->quote($lesson_id))
+ ->order('created DESC')
+ ->setLimit('1');
+
+ $db->setQuery($query);
+
+ $result = $db->loadResult();
+
+ return $result;
+ }
+}
\ No newline at end of file
diff --git a/deployed/tflearn/administrator/components/com_tflearn/src/Model/CompletionsModel.php b/deployed/tflearn/administrator/components/com_tflearn/src/Model/CompletionsModel.php
new file mode 100644
index 00000000..47369791
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/src/Model/CompletionsModel.php
@@ -0,0 +1,149 @@
+table_name = 'tfl_completion';
+
+ $this->select_fields = array('a.id', 'a.user_id', 'a.published', 'a.lesson_id', 'a.complete', 'a.created', 'b.questions', 'b.marks', 'b.title as lesson');
+
+ $this->joins = array(
+ array('table' => 'tfl_lessons', 'on' => 'lesson_id')
+ );
+
+ $this->filters['user'] = 'user_id';
+ $this->filters['lesson_id'] = 'a.lesson_id';
+
+ array_push($this->sorting_fields, 'a.created', 'lesson', 'user_id');
+
+ parent::__construct($config);
+ }
+
+// *****************************************************************************
+
+ // 01. Get modules from course (Check its usage and shift to Helper)
+ public function getModules($course_id)
+ {
+ $db = Factory::getDbo();
+ $query = $db->getQuery(true);
+
+ $query
+ ->select($db->quoteName(array('modules')))
+ ->from($db->quoteName('#__tfl_courses'))
+ ->where($db->quoteName('id') . ' = '. $db->quote($course_id))
+ ->setLimit('1');
+
+ $db->setQuery($query);
+
+ $result = $db->loadResult();
+
+ $result = json_decode($result, true);
+
+ return $result;
+ }
+
+ // 02. Get lessons for modules (Check its usage and shift to Helper)
+ public function getLessons($module_id)
+ {
+ $db = Factory::getDbo();
+ $query = $db->getQuery(true);
+
+ $query
+ ->select('*')
+ ->from($db->quoteName('#__tfl_lessons'))
+ ->where($db->quoteName('module') . ' = '. $db->quote($module_id))
+ ->andWhere($db->quoteName('published') . ' = '. $db->quote(1))
+ ->order($db->quoteName('ordering') . ' ASC');
+
+ $db->setQuery($query);
+
+ $rows = $db->loadAssocList();
+
+ return $rows;
+ }
+
+ // 03. Get latest score for lesson and user (Check its usage and shift to Helper)
+ public function getScore($user_id, $lesson_id)
+ {
+ $db = Factory::getDbo();
+ $query = $db->getQuery(true);
+
+ $query
+ ->select($db->quoteName(array('grade')))
+ ->from($db->quoteName('#__tfl_scores'))
+ ->where($db->quoteName('created_by') . ' = '. $db->quote($user_id))
+ ->andWhere($db->quoteName('lesson_id') . ' = '. $db->quote($lesson_id))
+ ->order('created DESC')
+ ->setLimit('1');
+
+ $db->setQuery($query);
+
+ $result = $db->loadResult();
+
+ return $result;
+ }
+
+ // 04. Get completion status for lesson and user (Check its usage and shift to Helper)
+ public function getCompletion($lesson_id, $user_id)
+ {
+ $db = Factory::getDbo();
+ $query = $db->getQuery(true);
+
+ $query
+ ->select($db->quoteName(array('complete')))
+ ->from($db->quoteName('#__tfl_completion'))
+ ->where($db->quoteName('lesson_id') . ' = '. $db->quote($lesson_id))
+ ->andWhere($db->quoteName('user_id') . ' = '. $db->quote($user_id))
+ ->setLimit('1');
+
+ $db->setQuery($query);
+
+ $result = $db->loadResult();
+
+ return $result;
+ }
+
+ // 05. Get total number of lessons in course (Check its usage and shift to Helper)
+ public function totalLessons($modules)
+ {
+ $module_ids = array();
+ if (is_array($modules))
+ {
+ foreach ($modules as $module)
+ {
+ $module_ids[] = $module['module_id'];
+ }
+ }
+ if (empty($module_ids))
+ {
+ return false;
+ }
+
+ $db = Factory::getDbo();
+ $query = $db->getQuery(true);
+
+ $query
+ ->select('COUNT(*)')
+ ->from($db->quoteName('#__tfl_lessons'))
+ ->where($db->quoteName('module') . ' IN (' . implode(',', $module_ids) . ')')
+ ->andWhere($db->quoteName('published') . ' = '. $db->quote(1));
+
+ $db->setQuery($query);
+
+ $result = $db->loadResult();
+
+ return $result;
+ }
+}
\ No newline at end of file
diff --git a/deployed/tflearn/administrator/components/com_tflearn/src/Model/CourseModel.php b/deployed/tflearn/administrator/components/com_tflearn/src/Model/CourseModel.php
new file mode 100644
index 00000000..6f5d0f45
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/src/Model/CourseModel.php
@@ -0,0 +1,23 @@
+table_name = 'tfl_courses';
+
+ $this->subform_fields = array('modules');
+
+ parent::__construct($config);
+ }
+}
\ No newline at end of file
diff --git a/deployed/tflearn/administrator/components/com_tflearn/src/Model/CoursesModel.php b/deployed/tflearn/administrator/components/com_tflearn/src/Model/CoursesModel.php
new file mode 100644
index 00000000..f68a7f58
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/src/Model/CoursesModel.php
@@ -0,0 +1,25 @@
+table_name = 'tfl_courses';
+
+ $this->select_fields = array('a.id', 'a.title', 'a.alias', 'a.published', 'a.course_type', 'a.ordering', 'a.front', 'a.group_id', 'a.hits');
+
+ array_push($this->sorting_fields, 'a.course_type', 'a.front', 'a.group_id');
+
+ parent::__construct($config);
+ }
+}
\ No newline at end of file
diff --git a/deployed/tflearn/administrator/components/com_tflearn/src/Model/DashboardModel.php b/deployed/tflearn/administrator/components/com_tflearn/src/Model/DashboardModel.php
new file mode 100644
index 00000000..0d12bdaf
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/src/Model/DashboardModel.php
@@ -0,0 +1,16 @@
+export_tables = array(
+ 'courses' => 'tfl_courses',
+ 'modules' => 'tfl_modules',
+ 'lessons' => 'tfl_lessons',
+ 'pages' => 'tfl_pages',
+ 'questions' => 'tfl_questions',
+ 'completions' => 'tfl_completion',
+ 'scores' => 'tfl_scores',
+ 'joomla_content' => 'content');
+
+ parent::__construct($config);
+ }
+}
\ No newline at end of file
diff --git a/deployed/tflearn/administrator/components/com_tflearn/src/Model/ImportModel.php b/deployed/tflearn/administrator/components/com_tflearn/src/Model/ImportModel.php
new file mode 100644
index 00000000..07870b6e
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/src/Model/ImportModel.php
@@ -0,0 +1,26 @@
+import_tables = array(
+ 'courses' => 'tfl_courses',
+ 'modules' => 'tfl_modules',
+ 'lessons' => 'tfl_lessons',
+ 'pages' => 'tfl_pages',
+ 'questions' => 'tfl_questions');
+
+ parent::__construct($config);
+ }
+}
\ No newline at end of file
diff --git a/deployed/tflearn/administrator/components/com_tflearn/src/Model/LessonModel.php b/deployed/tflearn/administrator/components/com_tflearn/src/Model/LessonModel.php
new file mode 100644
index 00000000..c86c7656
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/src/Model/LessonModel.php
@@ -0,0 +1,23 @@
+table_name = 'tfl_lessons';
+
+ $this->subform_fields = array('jids', 'resources');
+
+ parent::__construct($config);
+ }
+}
\ No newline at end of file
diff --git a/deployed/tflearn/administrator/components/com_tflearn/src/Model/LessonsModel.php b/deployed/tflearn/administrator/components/com_tflearn/src/Model/LessonsModel.php
new file mode 100644
index 00000000..73b5c1e8
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/src/Model/LessonsModel.php
@@ -0,0 +1,33 @@
+table_name = 'tfl_lessons';
+
+ $this->select_fields = array('a.id', 'a.title', 'a.published', 'a.lesson_type', 'a.ordering', 'a.completion_type', 'a.pass_percent', 'a.hits', 'a.ref', 'b.title as mod_name');
+
+ $this->joins = array(
+ array('table' => 'tfl_modules', 'on' => 'module')
+ );
+
+ $this->filters['module'] = 'module';
+ $this->filters['lesson_type'] = 'a.lesson_type';
+ $this->filters['completion_type'] = 'a.completion_type';
+
+ array_push($this->sorting_fields, 'a.lesson_type', 'a.completion_type', 'mod_name', 'a.ref');
+
+ parent::__construct($config);
+ }
+}
\ No newline at end of file
diff --git a/deployed/tflearn/administrator/components/com_tflearn/src/Model/ModuleModel.php b/deployed/tflearn/administrator/components/com_tflearn/src/Model/ModuleModel.php
new file mode 100644
index 00000000..d7464a4a
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/src/Model/ModuleModel.php
@@ -0,0 +1,21 @@
+table_name = 'tfl_modules';
+
+ parent::__construct($config);
+ }
+}
\ No newline at end of file
diff --git a/deployed/tflearn/administrator/components/com_tflearn/src/Model/ModulesModel.php b/deployed/tflearn/administrator/components/com_tflearn/src/Model/ModulesModel.php
new file mode 100644
index 00000000..b83b6826
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/src/Model/ModulesModel.php
@@ -0,0 +1,23 @@
+table_name = 'tfl_modules';
+
+ $this->select_fields = array('a.id', 'a.title', 'a.published');
+
+ parent::__construct($config);
+ }
+}
\ No newline at end of file
diff --git a/deployed/tflearn/administrator/components/com_tflearn/src/Model/PageModel.php b/deployed/tflearn/administrator/components/com_tflearn/src/Model/PageModel.php
new file mode 100644
index 00000000..c21affa6
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/src/Model/PageModel.php
@@ -0,0 +1,21 @@
+table_name = 'tfl_pages';
+
+ parent::__construct($config);
+ }
+}
\ No newline at end of file
diff --git a/deployed/tflearn/administrator/components/com_tflearn/src/Model/PagesModel.php b/deployed/tflearn/administrator/components/com_tflearn/src/Model/PagesModel.php
new file mode 100644
index 00000000..9731c80a
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/src/Model/PagesModel.php
@@ -0,0 +1,25 @@
+table_name = 'tfl_pages';
+
+ $this->select_fields = array('a.id', 'a.title', 'a.alias', 'a.published', 'a.modified', 'a.hits', 'a.ref');
+
+ $this->sorting_fields[] = 'a.ref';
+
+ parent::__construct($config);
+ }
+}
\ No newline at end of file
diff --git a/deployed/tflearn/administrator/components/com_tflearn/src/Model/QueryModel.php b/deployed/tflearn/administrator/components/com_tflearn/src/Model/QueryModel.php
new file mode 100644
index 00000000..53e133af
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/src/Model/QueryModel.php
@@ -0,0 +1,22 @@
+action_tables = array('courses' => 'tfl_courses', 'modules' => 'tfl_modules', 'lessons' => 'tfl_lessons', 'questions' => 'tfl_questions',
+ 'completions' => 'tfl_completion', 'scores' => 'tfl_scores', 'users' => 'users');
+
+ parent::__construct($config);
+ }
+}
\ No newline at end of file
diff --git a/deployed/tflearn/administrator/components/com_tflearn/src/Model/QuestionModel.php b/deployed/tflearn/administrator/components/com_tflearn/src/Model/QuestionModel.php
new file mode 100644
index 00000000..3e5dde10
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/src/Model/QuestionModel.php
@@ -0,0 +1,23 @@
+table_name = 'tfl_questions';
+
+ $this->subform_fields = array('options', 'matching');
+
+ parent::__construct($config);
+ }
+}
\ No newline at end of file
diff --git a/deployed/tflearn/administrator/components/com_tflearn/src/Model/QuestionsModel.php b/deployed/tflearn/administrator/components/com_tflearn/src/Model/QuestionsModel.php
new file mode 100644
index 00000000..8d38a3d9
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/src/Model/QuestionsModel.php
@@ -0,0 +1,49 @@
+table_name = 'tfl_questions';
+
+ $this->select_fields = array('a.id', 'a.title', 'a.published', 'a.q_type', 'b.title as lesson');
+
+ $this->joins = array(
+ array('table' => 'tfl_lessons', 'on' => 'lesson_id')
+ );
+
+ $this->filters['lesson'] = 'lesson_id';
+ $this->filters['q_type'] = 'a.q_type';
+
+ array_push($this->sorting_fields, 'a.q_type', 'lesson');
+
+ parent::__construct($config);
+ }
+
+// *****************************************************************************
+
+ public function get_question_type($id)
+ {
+ $question_types = array(
+ 'Not Defined',
+ 'Multiple Choice - Single',
+ 'Multiple Choice - Multi',
+ 'Numerical', 'Short Answer',
+ 'Matching',
+ 'True False',
+ 'Description'
+ );
+
+ return $question_types[$id];
+ }
+}
\ No newline at end of file
diff --git a/deployed/tflearn/administrator/components/com_tflearn/src/Model/ScoreModel.php b/deployed/tflearn/administrator/components/com_tflearn/src/Model/ScoreModel.php
new file mode 100644
index 00000000..33e4f04b
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/src/Model/ScoreModel.php
@@ -0,0 +1,40 @@
+table_name = 'tfl_scores';
+
+ $this->subform_fields = array('modules');
+
+ parent::__construct($config);
+ }
+
+// *****************************************************************************
+
+ public function getAttempts($attempts)
+ {
+ $qModel = new QuestionModel;
+ $questions = array();
+
+ foreach ($attempts as $k => $v)
+ {
+ $qid = substr($k, 1);
+ $questions[] = $qModel->getItem($qid);
+ }
+
+ return $questions;
+ }
+}
\ No newline at end of file
diff --git a/deployed/tflearn/administrator/components/com_tflearn/src/Model/ScoresModel.php b/deployed/tflearn/administrator/components/com_tflearn/src/Model/ScoresModel.php
new file mode 100644
index 00000000..4bf9f7d7
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/src/Model/ScoresModel.php
@@ -0,0 +1,28 @@
+table_name = 'tfl_scores';
+
+ $this->select_fields = array('a.id', 'a.published', 'a.grade', 'a.created', 'a.created_by', 'b.title as lesson');
+
+ $this->joins = array(
+ array('table' => 'tfl_lessons', 'on' => 'lesson_id'));
+
+ array_push($this->sorting_fields, 'a.grade', 'a.created_by', 'a.created', 'lesson');
+
+ parent::__construct($config);
+ }
+}
\ No newline at end of file
diff --git a/deployed/tflearn/administrator/components/com_tflearn/src/Table/CompletionTable.php b/deployed/tflearn/administrator/components/com_tflearn/src/Table/CompletionTable.php
new file mode 100644
index 00000000..3e5f100e
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/src/Table/CompletionTable.php
@@ -0,0 +1,20 @@
+
+
+ COM_TFLEARN
+ Tech Fry
+ August 2022
+ Tech Fry
+ http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL
+ mail@techfry.com
+ https://www.techfry.com
+ 1.7.5
+ COM_TFLEARN_DESC
+
+ TechFry\Component\TfLearn
+
+ script.php
+
+
+
+ sql/install.mysql.utf8.sql
+
+
+
+
+ sql/uninstall.mysql.utf8.sql
+
+
+
+
+ sql/updates/mysql
+
+
+
+
+ forms
+ language
+ src
+ tmpl
+
+
+
+ COM_TFLEARN_MENU
+
+ COM_TFLEARN_SUBMENU_DASHBOARD
+ COM_TFLEARN_SUBMENU_COURSES
+ COM_TFLEARN_SUBMENU_MODULES
+ COM_TFLEARN_SUBMENU_LESSONS
+ COM_TFLEARN_SUBMENU_PAGES
+ COM_TFLEARN_SUBMENU_QUESTIONS
+ COM_TFLEARN_SUBMENU_COMPLETIONS
+ COM_TFLEARN_SUBMENU_SCORES
+
+
+ access.xml
+ config.xml
+ forms
+ language
+ services
+ sql
+ src
+ tmpl
+
+
+
+
+ https://labs.techfry.com/joomla/components/com_tflearn/extension_free.xml
+
+
diff --git a/deployed/tflearn/administrator/components/com_tflearn/tmpl/completion/edit.php b/deployed/tflearn/administrator/components/com_tflearn/tmpl/completion/edit.php
new file mode 100644
index 00000000..59fe42b0
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/tmpl/completion/edit.php
@@ -0,0 +1,16 @@
+
+
+start_form_layout(); ?>
+
+ add_tab_forms(array('general', 'options'), 'COM_TFLEARN_COMPLETION'); ?>
+
+ add_tab_form('details', 'JDETAILS'); ?>
+
+end_form_layout(); ?>
\ No newline at end of file
diff --git a/deployed/tflearn/administrator/components/com_tflearn/tmpl/completions/default.php b/deployed/tflearn/administrator/components/com_tflearn/tmpl/completions/default.php
new file mode 100644
index 00000000..3e8d1059
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/tmpl/completions/default.php
@@ -0,0 +1,51 @@
+ths = array(
+ array('COM_TFLEARN_LESSON', 'lesson'),
+ array('COM_TFLEARN_USER', 'a.user_id'),
+ array('COM_TFLEARN_COMPLETION'),
+ array('COM_TFLEARN_SCORE'),
+ array('JGLOBAL_CREATED', 'created')
+ );
+?>
+
+start_list_layout(); ?>
+
+ items)) : ?>
+
+ items as $i => $row) :
+ $link = Route::_('index.php?option=com_tflearn&view=completion&layout=edit&id=' . $row->id);
+
+ $score = $this->getModel()->getScore($row->user_id, $row->lesson_id);
+ if ($score) {$total_marks = $row->questions * $row->marks;}
+ $score_display = $score ? $score . ' / ' . $total_marks : '-';
+ ?>
+
+ tr = array(
+ $this->get_link($link, $row->lesson),
+
+ $this->get_user($row->user_id),
+
+ $this->get_binary($row->complete),
+
+ $score_display,
+
+ $this->get_date($row->created)
+ );
+
+ echo $this->add_tr($i, $row);
+ ?>
+
+
+
+
+end_list_layout(); ?>
diff --git a/deployed/tflearn/administrator/components/com_tflearn/tmpl/completions/emptystate.php b/deployed/tflearn/administrator/components/com_tflearn/tmpl/completions/emptystate.php
new file mode 100644
index 00000000..81d2a971
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/tmpl/completions/emptystate.php
@@ -0,0 +1,10 @@
+
+
+es_layout(); ?>
\ No newline at end of file
diff --git a/deployed/tflearn/administrator/components/com_tflearn/tmpl/course/edit.php b/deployed/tflearn/administrator/components/com_tflearn/tmpl/course/edit.php
new file mode 100644
index 00000000..7c1cbc72
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/tmpl/course/edit.php
@@ -0,0 +1,20 @@
+
+
+start_form_layout(); ?>
+
+ add_tab_forms(array('description', 'options'), 'COM_TFLEARN_COURSE'); ?>
+
+ add_tab_form('modulesinfo', 'COM_TFLEARN_MODULES'); ?>
+
+ add_tab_form('imageinfo', 'COM_TFLEARN_IMAGE'); ?>
+
+ add_tab_form('details', 'JDETAILS'); ?>
+
+end_form_layout(); ?>
\ No newline at end of file
diff --git a/deployed/tflearn/administrator/components/com_tflearn/tmpl/courses/default.php b/deployed/tflearn/administrator/components/com_tflearn/tmpl/courses/default.php
new file mode 100644
index 00000000..b53d9780
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/tmpl/courses/default.php
@@ -0,0 +1,58 @@
+ths = array(
+ array('JGRID_HEADING_ORDERING', 'a.ordering'),
+ array('JGLOBAL_TITLE', 'a.title'),
+ array('COM_TFLEARN_USER_GROUP', 'a.group_id'),
+ array('COM_TFLEARN_USERS'),
+ array('COM_TFLEARN_FRONT', 'a.front'),
+ array('COM_TF_TYPE', 'a.course_type'),
+ array('JGLOBAL_HITS', 'a.hits')
+ );
+?>
+
+start_list_layout(); ?>
+
+ items)) : ?>
+
+ items as $i => $row) :
+ $link = Route::_('index.php?option=com_tflearn&view=course&layout=edit&id=' . $row->id);
+
+ $total_users = TfUser::total_users_by_group($row->group_id);
+
+ $group = TfDb::get_item('usergroups', $row->group_id);
+ ?>
+
+ tr = array(
+ $row->ordering,
+
+ $this->get_link($link, $row->title) . $this->get_small($row->alias),
+
+ $group->title . $this->get_small('Group ID: ' . $row->group_id),
+
+ $this->get_number($total_users),
+
+ $this->get_binary($row->front),
+
+ $row->course_type,
+
+ $this->get_number($row->hits, 'info')
+ );
+
+ echo $this->add_tr($i, $row);
+ ?>
+
+
+
+end_list_layout(); ?>
diff --git a/deployed/tflearn/administrator/components/com_tflearn/tmpl/courses/emptystate.php b/deployed/tflearn/administrator/components/com_tflearn/tmpl/courses/emptystate.php
new file mode 100644
index 00000000..81d2a971
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/tmpl/courses/emptystate.php
@@ -0,0 +1,10 @@
+
+
+es_layout(); ?>
\ No newline at end of file
diff --git a/deployed/tflearn/administrator/components/com_tflearn/tmpl/dashboard/default.php b/deployed/tflearn/administrator/components/com_tflearn/tmpl/dashboard/default.php
new file mode 100644
index 00000000..8dc3507d
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/tmpl/dashboard/default.php
@@ -0,0 +1,26 @@
+tiles_table = array(
+ array('courses', 'tfl_courses', 'graduation-cap'),
+ array('modules', 'tfl_modules', 'tags'),
+ array('lessons', 'tfl_lessons', 'book-open'),
+ array('pages', 'tfl_pages', 'file-alt'),
+ array('questions', 'tfl_questions', 'puzzle-piece'),
+ array('scores', 'tfl_scores', 'award'),
+ array('completions', 'tfl_completion', 'tasks')
+ );
+
+$this->doc_link = 'https://www.techfry.com/docs/tf-learn';
+
+$this->review_link = 'https://extensions.joomla.org/extension/tf-learn/';
+?>
+
+start_dashboard_layout(); ?>
+
+end_dashboard_layout(); ?>
\ No newline at end of file
diff --git a/deployed/tflearn/administrator/components/com_tflearn/tmpl/export/default.php b/deployed/tflearn/administrator/components/com_tflearn/tmpl/export/default.php
new file mode 100644
index 00000000..653386b6
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/tmpl/export/default.php
@@ -0,0 +1,16 @@
+
+
+start_form_layout(); ?>
+
+ add_tab_forms(array('general', 'options'), 'COM_TF_EXPORT', array(6, 6)); ?>
+
+ add_tab_form('filters', 'COM_TF_FILTER'); ?>
+
+end_form_layout(); ?>
\ No newline at end of file
diff --git a/deployed/tflearn/administrator/components/com_tflearn/tmpl/import/default.php b/deployed/tflearn/administrator/components/com_tflearn/tmpl/import/default.php
new file mode 100644
index 00000000..02dc07d4
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/tmpl/import/default.php
@@ -0,0 +1,10 @@
+import_layout();
+?>
\ No newline at end of file
diff --git a/deployed/tflearn/administrator/components/com_tflearn/tmpl/lesson/edit.php b/deployed/tflearn/administrator/components/com_tflearn/tmpl/lesson/edit.php
new file mode 100644
index 00000000..10f59b6d
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/tmpl/lesson/edit.php
@@ -0,0 +1,24 @@
+
+
+start_form_layout(); ?>
+
+ add_tab_forms(array('description', 'options'), 'COM_TFLEARN_LESSON'); ?>
+
+ add_tab_form('lessoninfo', 'JGLOBAL_FIELDSET_OPTIONS'); ?>
+
+ add_tab_form('contents', 'COM_TFLEARN_CONTENT'); ?>
+
+ add_tab_form('resources', 'COM_TFLEARN_RESOURCES'); ?>
+
+ add_tab_form('questions', 'COM_TFLEARN_QUESTIONS'); ?>
+
+ add_tab_form('details', 'JDETAILS'); ?>
+
+end_form_layout(); ?>
\ No newline at end of file
diff --git a/deployed/tflearn/administrator/components/com_tflearn/tmpl/lessons/default.php b/deployed/tflearn/administrator/components/com_tflearn/tmpl/lessons/default.php
new file mode 100644
index 00000000..f10947ee
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/tmpl/lessons/default.php
@@ -0,0 +1,58 @@
+ths = array(
+ array('JGRID_HEADING_ORDERING', 'a.ordering'),
+ array('COM_TFLEARN_REFERENCE', 'a.ref'),
+ array('JGLOBAL_TITLE', 'a.title'),
+ array('COM_TFLEARN_QUESTIONS'),
+ array('COM_TF_TYPE', 'a.lesson_type'),
+ array('COM_TFLEARN_COMPLETION', 'a.completion_type'),
+ array('COM_TFLEARN_MODULE', 'mod_name'),
+ array('JGLOBAL_HITS', 'a.hits')
+ );
+?>
+
+start_list_layout(); ?>
+
+ items)) : ?>
+
+ items as $i => $row) :
+ $link = Route::_('index.php?option=com_tflearn&&view=lesson&layout=edit&id=' . $row->id);
+
+ $total_questions = $this->getModel()->count_items('tfl_questions', 'lesson_id', $row->id);
+ ?>
+
+ tr = array(
+ $row->ordering,
+
+ $row->ref,
+
+ $this->get_link($link, $row->title),
+
+ $this->get_number($total_questions),
+
+ $row->lesson_type,
+
+ $row->completion_type . $this->get_small(($row->completion_type == 'score') ? $row->pass_percent . '%': ''),
+
+ $row->mod_name,
+
+ $this->get_number($row->hits, 'info')
+ );
+
+ echo $this->add_tr($i, $row);
+ ?>
+
+
+
+
+end_list_layout(); ?>
diff --git a/deployed/tflearn/administrator/components/com_tflearn/tmpl/lessons/emptystate.php b/deployed/tflearn/administrator/components/com_tflearn/tmpl/lessons/emptystate.php
new file mode 100644
index 00000000..81d2a971
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/tmpl/lessons/emptystate.php
@@ -0,0 +1,10 @@
+
+
+es_layout(); ?>
\ No newline at end of file
diff --git a/deployed/tflearn/administrator/components/com_tflearn/tmpl/module/edit.php b/deployed/tflearn/administrator/components/com_tflearn/tmpl/module/edit.php
new file mode 100644
index 00000000..53039763
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/tmpl/module/edit.php
@@ -0,0 +1,16 @@
+
+
+start_form_layout(); ?>
+
+ add_tab_forms(array('description', 'options'), 'COM_TFLEARN_MODULE'); ?>
+
+ add_tab_form('details', 'JDETAILS'); ?>
+
+end_form_layout(); ?>
\ No newline at end of file
diff --git a/deployed/tflearn/administrator/components/com_tflearn/tmpl/modules/default.php b/deployed/tflearn/administrator/components/com_tflearn/tmpl/modules/default.php
new file mode 100644
index 00000000..504fdcbe
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/tmpl/modules/default.php
@@ -0,0 +1,40 @@
+ths = array(
+ array('JGLOBAL_TITLE', 'a.title'),
+ array('COM_TFLEARN_LESSONS')
+ );
+?>
+
+start_list_layout(); ?>
+
+ items)) : ?>
+
+ items as $i => $row) :
+ $link = Route::_('index.php?option=com_tflearn&view=module&layout=edit&id=' . $row->id);
+
+ $total_lessons = $this->getModel()->count_items('tfl_lessons', 'module', $row->id);
+ ?>
+
+ tr = array(
+ $this->get_link($link, $row->title),
+
+ $this->get_number($total_lessons)
+ );
+
+ echo $this->add_tr($i, $row);
+ ?>
+
+
+
+
+end_list_layout(); ?>
diff --git a/deployed/tflearn/administrator/components/com_tflearn/tmpl/modules/emptystate.php b/deployed/tflearn/administrator/components/com_tflearn/tmpl/modules/emptystate.php
new file mode 100644
index 00000000..81d2a971
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/tmpl/modules/emptystate.php
@@ -0,0 +1,10 @@
+
+
+es_layout(); ?>
\ No newline at end of file
diff --git a/deployed/tflearn/administrator/components/com_tflearn/tmpl/page/edit.php b/deployed/tflearn/administrator/components/com_tflearn/tmpl/page/edit.php
new file mode 100644
index 00000000..81f225e1
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/tmpl/page/edit.php
@@ -0,0 +1,16 @@
+
+
+start_form_layout(); ?>
+
+ add_tab_forms(array('description', 'options'), 'COM_TFLEARN_PAGE'); ?>
+
+ add_tab_form('details', 'JDETAILS'); ?>
+
+end_form_layout(); ?>
\ No newline at end of file
diff --git a/deployed/tflearn/administrator/components/com_tflearn/tmpl/pages/default.php b/deployed/tflearn/administrator/components/com_tflearn/tmpl/pages/default.php
new file mode 100644
index 00000000..90af6605
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/tmpl/pages/default.php
@@ -0,0 +1,44 @@
+ths = array(
+ array('COM_TFLEARN_REFERENCE', 'a.ref'),
+ array('JGLOBAL_TITLE', 'a.title'),
+ array('JGLOBAL_MODIFIED', 'a.modified'),
+ array('JGLOBAL_HITS', 'a.hits')
+ );
+?>
+
+start_list_layout(); ?>
+
+ items)) : ?>
+
+ items as $i => $row) :
+ $link = Route::_('index.php?option=com_tflearn&&view=page&layout=edit&id=' . $row->id);
+ ?>
+
+ tr = array(
+ $row->ref,
+
+ $this->get_link($link, $row->title) . $this->get_small($row->alias),
+
+ $this->get_date($row->modified),
+
+ $this->get_number($row->hits, 'info')
+ );
+
+ echo $this->add_tr($i, $row);
+ ?>
+
+
+
+
+end_list_layout(); ?>
diff --git a/deployed/tflearn/administrator/components/com_tflearn/tmpl/pages/emptystate.php b/deployed/tflearn/administrator/components/com_tflearn/tmpl/pages/emptystate.php
new file mode 100644
index 00000000..81d2a971
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/tmpl/pages/emptystate.php
@@ -0,0 +1,10 @@
+
+
+es_layout(); ?>
\ No newline at end of file
diff --git a/deployed/tflearn/administrator/components/com_tflearn/tmpl/query/default.php b/deployed/tflearn/administrator/components/com_tflearn/tmpl/query/default.php
new file mode 100644
index 00000000..c30fa7ef
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/tmpl/query/default.php
@@ -0,0 +1,14 @@
+
+
+start_form_layout(); ?>
+
+ add_tab_forms(array('general', 'filters'), 'COM_TF_QUERY', array(3, 9)); ?>
+
+end_form_layout(); ?>
\ No newline at end of file
diff --git a/deployed/tflearn/administrator/components/com_tflearn/tmpl/question/edit.php b/deployed/tflearn/administrator/components/com_tflearn/tmpl/question/edit.php
new file mode 100644
index 00000000..69452d50
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/tmpl/question/edit.php
@@ -0,0 +1,18 @@
+
+
+start_form_layout(); ?>
+
+ add_tab_forms(array('description', 'options'), 'COM_TFLEARN_QUESTION'); ?>
+
+ add_tab_forms(array('questioninfo', 'answerinfo'), 'JGLOBAL_FIELDSET_OPTIONS'); ?>
+
+ add_tab_form('details', 'JDETAILS'); ?>
+
+end_form_layout(); ?>
\ No newline at end of file
diff --git a/deployed/tflearn/administrator/components/com_tflearn/tmpl/questions/default.php b/deployed/tflearn/administrator/components/com_tflearn/tmpl/questions/default.php
new file mode 100644
index 00000000..68e2dbd4
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/tmpl/questions/default.php
@@ -0,0 +1,42 @@
+ths = array(
+ array('JGLOBAL_TITLE', 'a.title'),
+ array('COM_TF_TYPE', 'a.q_type'),
+ array('COM_TFLEARN_LESSON', 'lesson')
+ );
+?>
+
+start_list_layout(); ?>
+
+ items)) : ?>
+
+ items as $i => $row) :
+ $link = Route::_('index.php?option=com_tflearn&&view=question&layout=edit&id=' . $row->id);
+ ?>
+
+ tr = array(
+ $this->get_link($link, $row->title),
+
+ $this->getModel()->get_question_type($row->q_type),
+
+ $row->lesson
+ );
+
+ echo $this->add_tr($i, $row);
+ ?>
+
+
+
+
+
+end_list_layout(); ?>
diff --git a/deployed/tflearn/administrator/components/com_tflearn/tmpl/questions/emptystate.php b/deployed/tflearn/administrator/components/com_tflearn/tmpl/questions/emptystate.php
new file mode 100644
index 00000000..81d2a971
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/tmpl/questions/emptystate.php
@@ -0,0 +1,10 @@
+
+
+es_layout(); ?>
\ No newline at end of file
diff --git a/deployed/tflearn/administrator/components/com_tflearn/tmpl/score/edit.php b/deployed/tflearn/administrator/components/com_tflearn/tmpl/score/edit.php
new file mode 100644
index 00000000..7480016b
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/tmpl/score/edit.php
@@ -0,0 +1,18 @@
+
+
+start_form_layout(); ?>
+
+ add_tab_forms(array('general', 'options'), 'COM_TFLEARN_SCORE'); ?>
+
+ add_tab_tmpl('attempts', 'COM_TFLEARN_ATTEMPTS'); ?>
+
+ add_tab_form('details', 'JDETAILS'); ?>
+
+end_form_layout(); ?>
\ No newline at end of file
diff --git a/deployed/tflearn/administrator/components/com_tflearn/tmpl/score/edit_attempts.php b/deployed/tflearn/administrator/components/com_tflearn/tmpl/score/edit_attempts.php
new file mode 100644
index 00000000..ed45ae39
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/tmpl/score/edit_attempts.php
@@ -0,0 +1,40 @@
+item->attempts, true);
+$questions = $this->getModel()->getAttempts($attempts);
+
+foreach ($questions as $question)
+{
+ $options_arr = json_decode($question->options, true);
+ $qname = 'q' . $question->id;
+ $i = 0;
+
+ echo '' . $question->description . ' ';
+ echo '';
+ foreach ($options_arr as $option)
+ {
+ echo '';
+ if ($attempts[$qname] == $i)
+ {
+ $icon = isset($option['is_correct']) ? 'publish' : 'unpublish';
+ echo ' ';
+ }
+ echo $option['opt'];
+ if (isset($option['is_correct']) && $option['is_correct'])
+ {
+ echo ' ';
+ }
+ echo ' ';
+ $i++;
+ }
+ echo ' ';
+
+ echo ' ';
+}
+?>
\ No newline at end of file
diff --git a/deployed/tflearn/administrator/components/com_tflearn/tmpl/scores/default.php b/deployed/tflearn/administrator/components/com_tflearn/tmpl/scores/default.php
new file mode 100644
index 00000000..4f91cdd1
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/tmpl/scores/default.php
@@ -0,0 +1,44 @@
+ths = array(
+ array('COM_TFLEARN_LESSON', 'lesson'),
+ array('COM_TFLEARN_USER', 'a.created_by'),
+ array('COM_TFLEARN_GRADE', 'a.grade'),
+ array('JGLOBAL_CREATED', 'a.created')
+ );
+?>
+
+start_list_layout(); ?>
+
+ items)) : ?>
+
+ items as $i => $row) :
+ $link = Route::_('index.php?option=com_tflearn&view=score&layout=edit&id=' . $row->id);
+ ?>
+
+ tr = array(
+ $this->get_link($link, $row->lesson),
+
+ $this->get_user($row->created_by),
+
+ $row->grade,
+
+ $this->get_date($row->created)
+ );
+
+ echo $this->add_tr($i, $row);
+ ?>
+
+
+
+
+end_list_layout(); ?>
diff --git a/deployed/tflearn/administrator/components/com_tflearn/tmpl/scores/emptystate.php b/deployed/tflearn/administrator/components/com_tflearn/tmpl/scores/emptystate.php
new file mode 100644
index 00000000..81d2a971
--- /dev/null
+++ b/deployed/tflearn/administrator/components/com_tflearn/tmpl/scores/emptystate.php
@@ -0,0 +1,10 @@
+
+
+es_layout(); ?>
\ No newline at end of file
diff --git a/deployed/tflearn/components/com_tflearn/forms/test.xml b/deployed/tflearn/components/com_tflearn/forms/test.xml
new file mode 100644
index 00000000..8d36ce9e
--- /dev/null
+++ b/deployed/tflearn/components/com_tflearn/forms/test.xml
@@ -0,0 +1,29 @@
+
+
\ No newline at end of file
diff --git a/deployed/tflearn/components/com_tflearn/language/en-GB/en-GB.com_tflearn.ini b/deployed/tflearn/components/com_tflearn/language/en-GB/en-GB.com_tflearn.ini
new file mode 100644
index 00000000..b72405be
--- /dev/null
+++ b/deployed/tflearn/components/com_tflearn/language/en-GB/en-GB.com_tflearn.ini
@@ -0,0 +1,57 @@
+COM_TFLEARN_ALL_PAGES="All Pages"
+
+COM_TFLEARN_CAPTCHA="Captcha"
+
+COM_TFLEARN_COMPLETION_STATUS="Completion Status"
+COM_TFLEARN_COMPLETED="Completed"
+
+COM_TFLEARN_COURSE_COMPLETE="My Course is Complete"
+COM_TFLEARN_COURSE_COMPLETE_SUCCESSFUL="You have completed the course."
+
+COM_TFLEARN_EMAIL="Email"
+COM_TFLEARN_EMAIL_NEW_ENROLMENT="New Enrollment By"
+
+COM_TFLEARN_EMAIL_SUBJECT_TEST="Your Test Score"
+COM_TFLEARN_EMAIL_TEST_BY="Test By"
+
+COM_TFLEARN_ENROL_NOW="Enrol Now"
+COM_TFLEARN_ENROL_SUCCESSFUL="You have successfully enrolled in the course."
+
+COM_TFLEARN_GUEST="Guest"
+
+COM_TFLEARN_MARK_COMPLETE="Mark as Complete"
+COM_TFLEARN_MARK_INCOMPLETE="Mark as Incomplete"
+
+COM_TFLEARN_MESSAGE_ALREADY_ENROLLED="You are already enrolled in the course."
+COM_TFLEARN_MESSAGE_ATTEMPT_GAP="You can take this test again after "
+COM_TFLEARN_MESSAGE_LESSON_COMPLETE="Lesson marked as complete."
+COM_TFLEARN_MESSAGE_LESSON_INCOMPLETE="Lesson marked as incomplete."
+COM_TFLEARN_MESSAGE_SINGLE_ATTEMPT="You can take this test only once."
+COM_TFLEARN_MESSAGE_ENROL_NOT_SETUP="Enrollment form is not ready."
+
+COM_TFLEARN_NAME="Name"
+
+COM_TFLEARN_PASSWORD="Password"
+
+COM_TFLEARN_SCORE="Score"
+
+COM_TFLEARN_TEST="Test"
+
+COM_TFLEARN_TEXT_GO_TO_COURSE="Go to course"
+COM_TFLEARN_TEXT_LESSONS_COMPLETED="Lessons Completed:"
+COM_TFLEARN_TEXT_TOTAL_LESSONS="Total Lessons:"
+COM_TFLEARN_TEXT_TOTAL_MARKS="Total Marks:"
+COM_TFLEARN_TEXT_TOTAL_QUESTIONS="Total Questions:"
+
+COM_TFLEARN_USERNAME="Username"
+
+; Used by All
+COM_TF_BUTTON_SEARCH="Search"
+COM_TF_ERROR_INCORRECT_CAPTCHA="Incorrect captcha. Please try again."
+COM_TF_FEED_READMORE="Read More"
+COM_TF_GUEST="Guest"
+COM_TF_INVALID_FILE_EXTENSION="Uploaded file extension is not valid. Please try again."
+COM_TF_INVALID_FILE_SIZE="Uploaded file size exceeds maximum limit. Please try again."
+COM_TF_MESSAGE_LOGIN="Please login or create an account to continue."
+COM_TF_PLACEHOLDER_SEARCH="Search"
+COM_TF_LOGIN_TO_CONTINUE="You don't have permission to access this. Please login to continue."
\ No newline at end of file
diff --git a/deployed/tflearn/components/com_tflearn/src/Controller/CompletionController.php b/deployed/tflearn/components/com_tflearn/src/Controller/CompletionController.php
new file mode 100644
index 00000000..495c00a0
--- /dev/null
+++ b/deployed/tflearn/components/com_tflearn/src/Controller/CompletionController.php
@@ -0,0 +1,51 @@
+input->get('id', 0, 'int');
+
+ $lesson_id = $this->input->get('lesson_id', 0, 'int');
+
+ $user = Factory::getUser();
+
+ $model = $this->getModel('Completion');
+ $model->change_state($lesson_id, $user->id, 1);
+
+ $this->app->enqueueMessage(Text::_('COM_TFLEARN_MESSAGE_LESSON_COMPLETE'), 'success');
+
+ $this->app->redirect(Route::_('index.php?option=com_tflearn&view=path&id=' . $id, false));
+ }
+
+ // 02. Mark lesson as incomplete
+ public function incomplete()
+ {
+ $id = $this->input->get('id', 0, 'int');
+
+ $lesson_id = $this->input->get('lesson_id', 0, 'int');
+
+ $user = Factory::getUser();
+
+ $model = $this->getModel('Completion');
+ $model->change_state($lesson_id, $user->id, 0);
+
+ $this->app->enqueueMessage(Text::_('COM_TFLEARN_MESSAGE_LESSON_INCOMPLETE'), 'warning');
+
+ $this->app->redirect(Route::_('index.php?option=com_tflearn&view=path&id=' . $id, false));
+ }
+}
\ No newline at end of file
diff --git a/deployed/tflearn/components/com_tflearn/src/Controller/CourseController.php b/deployed/tflearn/components/com_tflearn/src/Controller/CourseController.php
new file mode 100644
index 00000000..7c2c56cb
--- /dev/null
+++ b/deployed/tflearn/components/com_tflearn/src/Controller/CourseController.php
@@ -0,0 +1,121 @@
+getModel();
+
+ $course_id = $this->input->get('id', '', 'INT');
+
+ $user = Factory::getUser();
+
+ // Guest users should be redirected to enrol form url or login
+ if ($user->guest)
+ {
+ $enrol_url = $model->get_param('enrol_url', '');
+ if (empty($enrol_url))
+ {
+ $enrol_url = Route::_('index.php?option=com_users&view=login');
+ }
+
+ $this->setRedirect($enrol_url);
+ }
+ else
+ {
+ $course = $model->getItem($course_id);
+
+ // Check if user is already enrolled (Course group id is in user group ids)
+ if (in_array($course->group_id, $user->getAuthorisedGroups()))
+ {
+ $this->setMessage(Text::_('COM_TFLEARN_MESSAGE_ALREADY_ENROLLED'), 'info');
+ }
+ else
+ {
+ TfUser::add_user_to_group($user->id, $course->group_id);
+
+ // Notification email to admin
+ if ($model->get_param('notify_admin_enrol', 1))
+ {
+ TfNotify::notify_admin(Text::_('COM_TFLEARN_EMAIL_NEW_ENROLMENT'), $this->get_email_body($user, $course));
+ }
+
+ // Send email to user
+ if ($model->get_param('notify_user_enrol', 0) && ComponentHelper::isEnabled('com_tfmail'))
+ {
+ $q = new \stdClass();
+ $date = Factory::getDate();
+
+ $q->user_id = $user->id;
+ $q->mail_id = $this->get_param('notify_enrol_mail_id');
+ $q->priority = 2;
+ $q->send_date = $date->toSQL();
+
+ TfDb::insert_update('tfm_queue', $q, false);
+ }
+
+ $this->setMessage(Text::_('COM_TFLEARN_ENROL_SUCCESSFUL'), 'success');
+ }
+
+ $this->setRedirect(Route::_('index.php?option=com_tflearn&view=paths', false));
+ }
+ }
+
+ // When course is completed by user
+ public function complete()
+ {
+ $course_id = $this->input->get('id', '', 'INT');
+
+ $user = Factory::getUser();
+
+ // Send email to administrator
+ $model = $this->getModel();
+ $course = $model->getItem($course_id);
+
+ $subject = Text::_('COM_TFLEARN_COURSE_COMPLETE') . ': ' . $user->username;
+ $body = 'The user has completed the course: ' . $course->title . ' .
';
+ $body .= 'User ID: ' . $user->id . '
';
+ $body .= 'Name: ' . $user->name . '
';
+ $body .= 'Email ' . $user->email . '
';
+
+ TfNotify::notify_admin($subject, $body);
+
+ $this->setMessage(Text::_('COM_TFLEARN_COURSE_COMPLETE_SUCCESSFUL'));
+
+ $this->SetRedirect(Route::_('index.php?option=com_tflearn&view=paths', false));
+ }
+
+ public function get_email_body($user, $course)
+ {
+ $body = '';
+
+ $groups = TfUser::get_user_groups($user->id);
+
+ $body .= 'Course' . ' : ' . $course->title . '
';
+ $body .= 'User ID' . ' : ' . $user->id . '
';
+ $body .= 'Name' . ' : ' . $user->name . '
';
+ $body .= 'Username' . ' : ' . $user->username . '
';
+ $body .= 'Email' . ' : ' . $user->email . '
';
+ $body .= 'User Groups' . ' : ' . implode(', ', $groups) . '
';
+
+ return $body;
+ }
+}
\ No newline at end of file
diff --git a/deployed/tflearn/components/com_tflearn/src/Controller/DisplayController.php b/deployed/tflearn/components/com_tflearn/src/Controller/DisplayController.php
new file mode 100644
index 00000000..014b5e17
--- /dev/null
+++ b/deployed/tflearn/components/com_tflearn/src/Controller/DisplayController.php
@@ -0,0 +1,20 @@
+input->get('id', '', 'INT');
+
+ $lesson_id = $this->input->get('lesson_id', '', 'INT');
+
+ $this->setRedirect(Route::_('index.php?option=com_tflearn&view=test&course=' . $course_id . '&id=' . $lesson_id, false));
+ }
+
+ public function score()
+ {
+ $course_id = $this->input->get('id', '', 'INT');
+
+ $lesson_id = $this->input->get('lesson_id', '', 'INT');
+
+ $this->setRedirect(Route::_('index.php?option=com_tflearn&view=score&lesson_id=' . $lesson_id, false));
+ }
+}
\ No newline at end of file
diff --git a/deployed/tflearn/components/com_tflearn/src/Model/CompletionModel.php b/deployed/tflearn/components/com_tflearn/src/Model/CompletionModel.php
new file mode 100644
index 00000000..9c20573a
--- /dev/null
+++ b/deployed/tflearn/components/com_tflearn/src/Model/CompletionModel.php
@@ -0,0 +1,76 @@
+check($lesson_id, $user_id);
+ if ($result == null)
+ {
+ $data['id'] = 0;
+ $data['created'] = $date->toSQL();
+ $data['modified'] = $date->toSQL();
+ }
+ else
+ {
+ $data['id'] = $result->id;
+ $data['modified'] = $date->toSQL();
+ }
+
+ $data['published'] = 1;
+ $data['lesson_id'] = $lesson_id;
+ $data['user_id'] = $user_id;
+ $data['complete'] = $complete;
+
+ $this->direct_save($data, 'tfl_completion');
+ }
+
+ // 02. Check if completion exists or not
+ public function check($lesson_id, $user_id)
+ {
+ $db = Factory::getDbo();
+ $query = $db->getQuery(true);
+
+ $query
+ ->select($db->quoteName(array('id', 'complete')))
+ ->from($db->quoteName('#__tfl_completion'))
+ ->where($db->quoteName('lesson_id') . ' = '. $db->quote($lesson_id))
+ ->andWhere($db->quoteName('user_id') . ' = '. $db->quote($user_id))
+ ->setLimit('1');
+
+ $db->setQuery($query);
+
+ $result = $db->loadObject();
+
+ return $result;
+ }
+}
\ No newline at end of file
diff --git a/deployed/tflearn/components/com_tflearn/src/Model/CourseModel.php b/deployed/tflearn/components/com_tflearn/src/Model/CourseModel.php
new file mode 100644
index 00000000..a70d96c9
--- /dev/null
+++ b/deployed/tflearn/components/com_tflearn/src/Model/CourseModel.php
@@ -0,0 +1,34 @@
+table_name = 'tfl_courses';
+
+ parent::__construct($config);
+ }
+
+// *****************************************************************************
+
+ public function get_lesson_title($content_id, $source)
+ {
+ $table = ($source == 'joomla') ? 'content' : 'tfl_pages';
+
+ $lesson = TfDb::get_item($table, $content_id);
+
+ return $lesson->title;
+ }
+}
\ No newline at end of file
diff --git a/deployed/tflearn/components/com_tflearn/src/Model/CoursesModel.php b/deployed/tflearn/components/com_tflearn/src/Model/CoursesModel.php
new file mode 100644
index 00000000..1e1cfc42
--- /dev/null
+++ b/deployed/tflearn/components/com_tflearn/src/Model/CoursesModel.php
@@ -0,0 +1,36 @@
+table_name = 'tfl_courses';
+
+ $this->select_fields = '*';
+
+ $input = Factory::getApplication()->input;
+ $course_type = $input->get('course_type', '0');
+
+ $this->where = array(array('front', '=', 1));
+ if ($course_type)
+ {
+ $this->where[] = array('course_type', '=', $course_type);
+ }
+
+ $this->orderby = $this->get_param('courses_order_col', 'id') . ' ' . $this->get_param('courses_order_dirn', 'DESC');
+
+ parent::__construct($config, $factory);
+ }
+}
\ No newline at end of file
diff --git a/deployed/tflearn/components/com_tflearn/src/Model/PageModel.php b/deployed/tflearn/components/com_tflearn/src/Model/PageModel.php
new file mode 100644
index 00000000..997f5d5a
--- /dev/null
+++ b/deployed/tflearn/components/com_tflearn/src/Model/PageModel.php
@@ -0,0 +1,78 @@
+table_name = 'tfl_lessons';
+
+ $this->json_fields = array('jids');
+
+ parent::__construct($config);
+ }
+
+ // 02. Get Joomla Article
+ public function getArticle($article_id)
+ {
+ $conditions = array(
+ array('id', '=', $article_id),
+ array('state', '=', 1)
+ );
+
+ $record = TfDb::get_record('content', $conditions, null, 'title', 'introtext', 'fulltext');
+
+ return $record;
+ }
+
+ // 03. Get Navigation Links
+ public function getNav($current_lesson, $module_id)
+ {
+ $nav = array();
+
+ $lessons_order_col = $this->get_param('lessons_order_col', 'id');
+ $lessons_order_dirn = $this->get_param('lessons_order_dirn', 'ASC');
+
+ $order = $lessons_order_col . ' ' . $lessons_order_dirn;
+
+ $conditions = array(
+ array('published', '=', 1),
+ array('module', '=', $module_id)
+ );
+
+ $lessons = TfDb::get_records('tfl_lessons', 'id, title, lesson_type', $conditions, $order);
+
+ foreach ($lessons as $k => $lesson)
+ {
+ if ($lesson->id == $current_lesson)
+ {
+ $nav['next'] = $lessons[$k+1];
+ $nav['pre'] = $lessons[$k-1];
+ }
+ }
+
+ return $nav;
+ }
+
+ // 04. Mark lesson as complete
+ public function mark_complete($lesson_id, $user_id)
+ {
+ $compModel = new CompletionModel;
+
+ $compModel->change_state($lesson_id, $user_id, 1);
+ }
+}
\ No newline at end of file
diff --git a/deployed/tflearn/components/com_tflearn/src/Model/PathModel.php b/deployed/tflearn/components/com_tflearn/src/Model/PathModel.php
new file mode 100644
index 00000000..76de8c14
--- /dev/null
+++ b/deployed/tflearn/components/com_tflearn/src/Model/PathModel.php
@@ -0,0 +1,100 @@
+table_name = 'tfl_courses';
+
+ $this->json_fields = array('modules');
+
+ parent::__construct($config);
+ }
+
+ // 01. Get total number of lessons in course
+ public function total_lessons($modules)
+ {
+ $module_ids = array();
+ foreach ($modules as $module_obj)
+ {
+ $module = (array) $module_obj;
+ $module_ids[] = $module['module_id'];
+ }
+
+ $conditions = array(
+ array('module', 'IN (' . implode(',', $module_ids) . ')')
+ );
+
+ $result = TfDb::total_rows('tfl_lessons', $conditions);
+
+ return $result;
+ }
+
+ // 02. Get latest score for lesson and user
+ public function get_score($user_id, $lesson_id)
+ {
+ $lesson = TfDb::get_item('tfl_lessons', $lesson_id);
+
+ $db = Factory::getDbo();
+ $query = $db->getQuery(true);
+
+ if ($lesson->grade_type == 'maximum')
+ {
+ $query->select('MAX(grade)');
+ }
+ elseif ($lesson->grade_type == 'average')
+ {
+ $query->select('AVG(grade)');
+ }
+ else
+ {
+ $query->select($db->quoteName('grade'));
+ $query->setLimit('1');
+ }
+
+ $query
+ ->from($db->quoteName('#__tfl_scores'))
+ ->where($db->quoteName('created_by') . ' = '. $db->quote($user_id))
+ ->andWhere($db->quoteName('lesson_id') . ' = '. $db->quote($lesson_id))
+ ->order('id DESC');
+
+ $db->setQuery($query);
+
+ $result = $db->loadResult();
+
+ return $result;
+ }
+
+ // 03. Get completion status for lesson and user
+ public function get_completion($lesson_id, $user_id)
+ {
+ $db = Factory::getDbo();
+ $query = $db->getQuery(true);
+
+ $query
+ ->select($db->quoteName(array('complete')))
+ ->from($db->quoteName('#__tfl_completion'))
+ ->where($db->quoteName('lesson_id') . ' = '. $db->quote($lesson_id))
+ ->andWhere($db->quoteName('user_id') . ' = '. $db->quote($user_id))
+ ->setLimit('1');
+
+ $db->setQuery($query);
+
+ $result = $db->loadResult();
+
+ return $result;
+ }
+}
\ No newline at end of file
diff --git a/deployed/tflearn/components/com_tflearn/src/Model/PathsModel.php b/deployed/tflearn/components/com_tflearn/src/Model/PathsModel.php
new file mode 100644
index 00000000..4fb4aeb3
--- /dev/null
+++ b/deployed/tflearn/components/com_tflearn/src/Model/PathsModel.php
@@ -0,0 +1,87 @@
+table_name = 'tfl_courses';
+
+ $this->select_fields = 'id, title, modules';
+
+ $user = Factory::getUser();
+ $ugs = implode(',', $user->getAuthorisedGroups());
+
+ $this->where = array('group_id IN (' . $ugs . ')');
+
+ $this->orderby = $this->get_param('paths_order_col') . ' ' . $this->get_param('paths_order_dirn');
+
+ parent::__construct($config, $factory);
+ }
+
+// *****************************************************************************
+
+ // 01. Get total number of lessons in course
+ public function total_lessons($modules)
+ {
+ $module_ids = array();
+ foreach ($modules as $module)
+ {
+ $module_ids[] = $module['module_id'];
+ }
+
+ $conditions = array(
+ array('module', 'IN (' . implode(',', $module_ids) . ')')
+ );
+
+ $result = TfDb::total_rows('tfl_lessons', $conditions);
+
+ return $result;
+ }
+
+ // 02. Get completed lessons for a user
+ public function get_completion($user_id, $modules)
+ {
+ $complete = 0;
+ foreach ($modules as $module)
+ {
+ $lessons = TfDb::get_items('tfl_lessons', array(array('module', '=', $module['module_id'])));
+
+ foreach ($lessons as $lesson)
+ {
+ $db = Factory::getDbo();
+ $query = $db->getQuery(true);
+
+ $query
+ ->select($db->quoteName(array('complete')))
+ ->from($db->quoteName('#__tfl_completion'))
+ ->where($db->quoteName('lesson_id') . ' = '. $db->quote($lesson->id))
+ ->andWhere($db->quoteName('user_id') . ' = '. $db->quote($user_id))
+ ->setLimit('1');
+
+ $db->setQuery($query);
+
+ $result = $db->loadResult();
+
+ if ($result)
+ {
+ $complete++;
+ }
+ }
+ }
+
+ return $complete;
+ }
+}
\ No newline at end of file
diff --git a/deployed/tflearn/components/com_tflearn/src/Model/ScoreModel.php b/deployed/tflearn/components/com_tflearn/src/Model/ScoreModel.php
new file mode 100644
index 00000000..7b300ce2
--- /dev/null
+++ b/deployed/tflearn/components/com_tflearn/src/Model/ScoreModel.php
@@ -0,0 +1,48 @@
+table_name = 'tfl_scores';
+
+ $this->select_fields = array('attempts', 'created', 'grade');
+
+ $input = Factory::getApplication()->input;
+ $lesson_id = $input->get('lesson_id');
+
+ $user = Factory::getUser();
+
+ $this->where = array(array('lesson_id', '=', $lesson_id), array('created_by', '=', $user->id));
+
+ $this->orderby = 'id DESC';
+
+ parent::__construct($config, $factory);
+ }
+
+ public function get_attempts($attempts)
+ {
+ $questions = array();
+
+ foreach ($attempts as $k => $v)
+ {
+ $qid = substr($k, 1);
+ $questions[] = TfDb::get_item('tfl_questions', $qid);
+ }
+
+ return $questions;
+ }
+}
\ No newline at end of file
diff --git a/deployed/tflearn/components/com_tflearn/src/Model/ScoresModel.php b/deployed/tflearn/components/com_tflearn/src/Model/ScoresModel.php
new file mode 100644
index 00000000..61da579d
--- /dev/null
+++ b/deployed/tflearn/components/com_tflearn/src/Model/ScoresModel.php
@@ -0,0 +1,38 @@
+table_name = 'tfl_scores';
+
+ $this->select_fields = array('lesson_id', 'created', 'grade');
+
+ $user = Factory::getUser();
+ $this->where = array(array('created_by', '=', $user->id));
+
+ $this->orderby = 'id DESC';
+
+ parent::__construct($config, $factory);
+ }
+
+ public function get_lesson_title($lesson_id)
+ {
+ $lesson = TfDb::get_item('tfl_lessons', $lesson_id);
+
+ return $lesson->title;
+ }
+}
\ No newline at end of file
diff --git a/deployed/tflearn/components/com_tflearn/src/Model/TestModel.php b/deployed/tflearn/components/com_tflearn/src/Model/TestModel.php
new file mode 100644
index 00000000..6813a5d0
--- /dev/null
+++ b/deployed/tflearn/components/com_tflearn/src/Model/TestModel.php
@@ -0,0 +1,303 @@
+table_name = 'tfl_scores';
+
+ $this->loadData = false;
+
+ parent::__construct($config, $factory, $formFactory);
+ }
+
+ public function getTable($name = 'Score', $prefix = 'Administrator', $options = array())
+ {
+ return parent::getTable($name, $prefix, $options);
+ }
+
+// *****************************************************************************
+
+ public function save($data)
+ {
+ $lesson = TfDb::get_item('tfl_lessons', $data['lesson_id']);
+ $data['published'] = 1;
+
+ // Grade
+ $data['grade'] = 0;
+ $correct = 0;
+ foreach ($data['attempts'] as $k => $v)
+ {
+ if ($this->check_answer($k, $v))
+ {
+ $data['grade'] = $data['grade'] + $data['marks'];
+ $correct++;
+ }
+ }
+
+ // Calculate percentage
+ $total_marks = $lesson->questions * $lesson->marks;
+ $percentage = ($data['grade']/$total_marks) * 100;
+ $percentage = round($percentage, 2);
+
+ // unset($data['marks']);
+
+ // Convert array to JSON string
+ $data['attempts'] = json_encode($data['attempts']);
+
+ $return = parent::save($data);
+
+ // Mark completed if completion type is score and percent achieved
+ if ($percentage >= $lesson->pass_percent && $lesson->completion_type == 'score')
+ {
+ $compModel = $this->getModel('Completion');
+
+ $compModel->change_state($data['lesson_id'], $data['created_by'], 1);
+ }
+
+ // Notify administrator of new test submission
+ if ($this->get_param('notify_admin_test', 1))
+ {
+ TfNotify::notify_admin(Text::_('COM_TFLEARN_EMAIL_TEST_BY'), $data);
+ }
+
+ // Email score to the test taker
+ if ($this->get_param('notify_user_test', 0) && ComponentHelper::isEnabled('com_tfmail'))
+ {
+ $q = new \stdClass();
+ $date = Factory::getDate();
+
+ $q->user_id = $data['created_by'];
+ $q->mail_id = $model->get_param('notify_test_mail_id');
+ $q->priority = 2;
+ $q->send_date = $date->toSql();
+
+ TfDb::insert_update('tfm_queue', $q, false);
+ }
+
+ $test_report = 'Correct Attempts: ' . $correct . ' ';
+ $test_report .= 'Score: ' . $data['grade'] . ' ';
+ $test_report .= 'Percentage: ' . $percentage . '%';
+
+ $this->set_message($test_report, 'info');
+
+ return $return;
+ }
+
+ // 01. Get questions for a lesson
+ public function getQuestions()
+ {
+ $input = Factory::getApplication()->input;
+ $lesson_id = $input->get('id', '', 'INT');
+
+ $db = Factory::getDbo();
+ $query = $db->getQuery(true);
+
+ $query
+ ->select('id, description, options, matching, answer, q_type')
+ ->from($db->quoteName('#__tfl_questions'))
+ ->where($db->quoteName('published') . ' = ' . $db->quote(1));
+
+ if ($lesson_id != null)
+ {
+ $query->andWhere($db->quoteName('lesson_id') . ' = ' . $db->quote($lesson_id));
+
+ $lesson = TfDb::get_item('tfl_lessons', $lesson_id);
+
+ if (isset($lesson->questions))
+ {
+ $query->setLimit($lesson->questions);
+ }
+ $query->order('RAND()');
+ }
+
+ $db->setQuery($query);
+
+ $rows = $db->loadAssocList();
+
+ return $rows;
+ }
+
+ public function getLesson($pk = null)
+ {
+ if ($pk == null)
+ {
+ $input = Factory::getApplication()->input;
+ $pk = $input->get('id', '', 'INT');
+ }
+
+ $db = Factory::getDbo();
+ $query = $db->getQuery(true);
+
+ $query
+ ->select('*')
+ ->from($db->quoteName('#__tfl_lessons'))
+ ->where($db->quoteName('id') . ' = '. $db->quote($pk))
+ ->andWhere($db->quoteName('published') . ' = 1')
+ ->setLimit('1');
+
+ $db->setQuery($query);
+
+ $row = $db->loadObject();
+
+ return $row;
+ }
+
+ // Check whether answer given is correct or not
+ public function check_answer($qname, $answer)
+ {
+ $qid = substr($qname, 1); // $qname is like q34
+
+ $question = TfDb::get_item('tfl_questions', $qid);
+
+ if ($question->q_type == 1) // MCQ - Single Correct
+ {
+ $options_arr = json_decode($question->options, true);
+ $num = 0;
+ foreach ($options_arr as $option)
+ {
+ if (isset($option['is_correct']))
+ {
+ if ($option['is_correct'])
+ {
+ $correct_answer = $num;
+ }
+ }
+ $num++;
+ }
+ }
+ elseif ($question->q_type == 2) // MCQ - Multiple Correct
+ {
+ // $answer is array
+
+ $options_arr = json_decode($question->options, true);
+ $num = 0;
+ $correct_answer = array();
+ foreach ($options_arr as $option)
+ {
+ if (isset($option['is_correct']))
+ {
+ if ($option['is_correct'])
+ {
+ $correct_answer[$num] = $num;
+ }
+ }
+ $num++;
+ }
+ }
+ elseif ($question->q_type == 3) // Numerical
+ {
+ $correct_answer = $question->answer;
+ }
+ elseif ($question->q_type == 4) // Short Answer
+ {
+ $correct_answer = strtolower($question->answer);
+ $answer = strtolower($answer);
+ }
+ elseif ($question->q_type == 5) // Matching
+ {
+ // $answer is array
+
+ $matchings = json_decode($question->matching, true);
+ $correct_answer = array();
+
+ foreach ($matchings as $matching)
+ {
+ $correct_answer[] = $matching['col_b'];
+ }
+ }
+ elseif ($question->q_type == 6) // True False
+ {
+ if ($question->answer == 1 || strtoupper($question->answer) == 'T' || strtoupper($question->answer) == 'TRUE')
+ {
+ $correct_answer = 1;
+ }
+ else
+ {
+ $correct_answer = 0;
+ }
+ }
+ else
+ {
+ $correct_answer = $question->answer;
+ }
+
+ return ($answer == $correct_answer) ? true : false;
+ }
+
+ // Check whether student can take test
+ public function check_access($pk = null)
+ {
+ if ($pk == null)
+ {
+ $input = Factory::getApplication()->input;
+ $pk = $input->get('id', '', 'INT');
+ }
+
+ $user = Factory::getUser();
+ $app = Factory::getApplication();
+
+ // Allow guest users to take test
+ if (!$user->id)
+ {
+ return true;
+ }
+
+ // Get lesson
+ $lesson = TfDb::get_item('tfl_lessons', $pk);
+
+ // Get previous attempts
+ $conditions = array(array('lesson_id', '=', $pk), array('created_by', '=', $user->id));
+ $scores = TfDb::get_items('tfl_scores', $conditions, 'id DESC', 1);
+ $scores_arr = (array) $scores;
+ $score = $scores_arr[0];
+
+ if (empty($scores))
+ {
+ return true;
+ }
+
+ if (!$lesson->multiple_attempts)
+ {
+ $app->enqueueMessage(Text::_('COM_TFLEARN_MESSAGE_SINGLE_ATTEMPT'), 'warning');
+ return false;
+ }
+
+ if ($lesson->multiple_attempts && $lesson->attempt_gap == 0)
+ {
+ return true;
+ }
+
+ $interval = new \DateInterval('P' . $lesson->attempt_gap . 'D');
+
+ $date = new Date($score->created);
+ $date->add($interval);
+ $today = new Date();
+
+ if ($today < $date)
+ {
+ $app->enqueueMessage(Text::_('COM_TFLEARN_MESSAGE_ATTEMPT_GAP') . $date->format('d F, Y'), 'warning');
+ return false;
+ }
+
+ return true;
+ }
+}
\ No newline at end of file
diff --git a/deployed/tflearn/components/com_tflearn/src/Service/Router.php b/deployed/tflearn/components/com_tflearn/src/Service/Router.php
new file mode 100644
index 00000000..437d9564
--- /dev/null
+++ b/deployed/tflearn/components/com_tflearn/src/Service/Router.php
@@ -0,0 +1,87 @@
+categoryFactory = $categoryFactory;
+ $this->db = $db;
+
+ $courses = new RouterViewConfiguration('courses');
+ $this->registerView($courses);
+
+ $course = new RouterViewConfiguration('course');
+ $course->setKey('id')->setParent($courses);
+ $this->registerView($course);
+
+ $paths = new RouterViewConfiguration('paths');
+ $this->registerView($paths);
+
+ parent::__construct($app, $menu);
+
+ $this->attachRule(new MenuRules($this));
+ $this->attachRule(new StandardRules($this));
+ $this->attachRule(new NomenuRules($this));
+ }
+
+ public function getCourseSegment($id, $query)
+ {
+ $db = Factory::getDbo();
+ $dbquery = $db->getQuery(true);
+
+ $dbquery->select($dbquery->qn('alias'))
+ ->from($dbquery->qn('#__tfl_courses'))
+ ->where('id = ' . $dbquery->q($id));
+
+ $db->setQuery($dbquery);
+
+ $id .= ':' . $db->loadResult();
+
+ list($void, $segment) = explode(':', $id, 2);
+
+ return array($void => $segment);
+ }
+
+ public function getCourseId($segment, $query)
+ {
+ $db = Factory::getDbo();
+ $dbquery = $db->getQuery(true);
+
+ $dbquery->select($dbquery->qn('id'))
+ ->from($dbquery->qn('#__tfl_courses'))
+ ->where('alias = ' . $dbquery->q($segment));
+
+ $db->setQuery($dbquery);
+
+ return (int) $db->loadResult();
+ }
+}
\ No newline at end of file
diff --git a/deployed/tflearn/components/com_tflearn/src/View/Course/HtmlView.php b/deployed/tflearn/components/com_tflearn/src/View/Course/HtmlView.php
new file mode 100644
index 00000000..16e898d1
--- /dev/null
+++ b/deployed/tflearn/components/com_tflearn/src/View/Course/HtmlView.php
@@ -0,0 +1,24 @@
+initiate_item();
+
+ // Display the view
+ return parent::display($tpl);
+ }
+}
\ No newline at end of file
diff --git a/deployed/tflearn/components/com_tflearn/src/View/Courses/FeedView.php b/deployed/tflearn/components/com_tflearn/src/View/Courses/FeedView.php
new file mode 100644
index 00000000..b1f420ed
--- /dev/null
+++ b/deployed/tflearn/components/com_tflearn/src/View/Courses/FeedView.php
@@ -0,0 +1,24 @@
+base_item_link = 'index.php?option=com_tflearn&view=course';
+
+ $this->current_link = Route::_('index.php?option=com_tflearn&view=courses');
+
+ $this->initiate_feed();
+ }
+}
\ No newline at end of file
diff --git a/deployed/tflearn/components/com_tflearn/src/View/Courses/HtmlView.php b/deployed/tflearn/components/com_tflearn/src/View/Courses/HtmlView.php
new file mode 100644
index 00000000..8f641e62
--- /dev/null
+++ b/deployed/tflearn/components/com_tflearn/src/View/Courses/HtmlView.php
@@ -0,0 +1,31 @@
+initiate_list();
+
+ // Check for access
+ if (!in_array($this->getModel()->get_param('courses_access', 1), $this->user->getAuthorisedViewLevels()))
+ {
+ $this->handle_access();
+
+ return;
+ }
+
+ // Display the view
+ return parent::display($tpl);
+ }
+}
\ No newline at end of file
diff --git a/deployed/tflearn/components/com_tflearn/src/View/Page/HtmlView.php b/deployed/tflearn/components/com_tflearn/src/View/Page/HtmlView.php
new file mode 100644
index 00000000..f9f8d75e
--- /dev/null
+++ b/deployed/tflearn/components/com_tflearn/src/View/Page/HtmlView.php
@@ -0,0 +1,45 @@
+initiate_item();
+
+ $this->course_id = $this->app->input->get('course', '0');
+ $course = TfDb::get_item('tfl_courses', $this->course_id);
+
+ $this->section = $this->app->input->get('section', 'all');
+
+ $this->total_sections = count((array) $this->item->jids);
+
+ // Check for access (Course group id should be in user group ids)
+ if (!in_array($course->group_id, $this->user->getAuthorisedGroups()))
+ {
+ $this->handle_access();
+
+ return;
+ }
+
+ // Display the view
+ return parent::display($tpl);
+ }
+}
\ No newline at end of file
diff --git a/deployed/tflearn/components/com_tflearn/src/View/Path/HtmlView.php b/deployed/tflearn/components/com_tflearn/src/View/Path/HtmlView.php
new file mode 100644
index 00000000..de7411a8
--- /dev/null
+++ b/deployed/tflearn/components/com_tflearn/src/View/Path/HtmlView.php
@@ -0,0 +1,36 @@
+initiate_item();
+
+ // Check for access (Course group id should be in user group ids)
+ if (!in_array($this->item->group_id, $this->user->getAuthorisedGroups()))
+ {
+ $this->handle_access();
+
+ return;
+ }
+
+ // Display the view
+ return parent::display($tpl);
+ }
+}
\ No newline at end of file
diff --git a/deployed/tflearn/components/com_tflearn/src/View/Paths/HtmlView.php b/deployed/tflearn/components/com_tflearn/src/View/Paths/HtmlView.php
new file mode 100644
index 00000000..fd4c9d1b
--- /dev/null
+++ b/deployed/tflearn/components/com_tflearn/src/View/Paths/HtmlView.php
@@ -0,0 +1,22 @@
+initiate_list();
+
+ // Display the view
+ return parent::display($tpl);
+ }
+}
\ No newline at end of file
diff --git a/deployed/tflearn/components/com_tflearn/src/View/Score/HtmlView.php b/deployed/tflearn/components/com_tflearn/src/View/Score/HtmlView.php
new file mode 100644
index 00000000..8533c4c8
--- /dev/null
+++ b/deployed/tflearn/components/com_tflearn/src/View/Score/HtmlView.php
@@ -0,0 +1,28 @@
+initiate_list();
+
+ $lesson_id = $this->app->input->get('lesson_id', '0');
+ $this->lesson = TfDb::get_item('tfl_lessons', $lesson_id);
+
+ // Display the view
+ return parent::display($tpl);
+ }
+}
\ No newline at end of file
diff --git a/deployed/tflearn/components/com_tflearn/src/View/Scores/HtmlView.php b/deployed/tflearn/components/com_tflearn/src/View/Scores/HtmlView.php
new file mode 100644
index 00000000..dcbe4077
--- /dev/null
+++ b/deployed/tflearn/components/com_tflearn/src/View/Scores/HtmlView.php
@@ -0,0 +1,24 @@
+initiate_list();
+
+ // Display the view
+ return parent::display($tpl);
+ }
+}
\ No newline at end of file
diff --git a/deployed/tflearn/components/com_tflearn/src/View/Test/HtmlView.php b/deployed/tflearn/components/com_tflearn/src/View/Test/HtmlView.php
new file mode 100644
index 00000000..7b1b3a9d
--- /dev/null
+++ b/deployed/tflearn/components/com_tflearn/src/View/Test/HtmlView.php
@@ -0,0 +1,91 @@
+loadData = false;
+
+ $this->initiate_form();
+
+ $this->course_id = $this->app->input->get('course', '0');
+ $course = TfDb::get_item('tfl_courses', $this->course_id);
+
+ $this->questions = $this->get('Questions');
+
+ $this->lesson = $this->get('Lesson');
+
+ $this->_prepareDocument();
+
+ // Check for access (Course group id should be in user group ids)
+ if (!in_array($course->group_id, $this->user->getAuthorisedGroups()))
+ {
+ $this->handle_access();
+
+ return;
+ }
+
+ // Check access for the test
+ $access = $this->getModel()->check_access();
+ if (!$access)
+ {
+ $this->handle_access();
+
+ return;
+ }
+
+ // Display the view
+ return parent::display($tpl);
+ }
+
+ protected function _prepareDocument()
+ {
+ $app = Factory::getApplication();
+
+ // 01. Page heading of document
+ $menus = $app->getMenu();
+ $menu = $menus->getActive();
+ if ($menu)
+ {
+ $this->params->def('page_heading', $this->params->get('page_title', $menu->title));
+ }
+
+ // 02. Title of document
+ $title = $this->params->get('page_title', '');
+ if (empty($title))
+ {
+ if (is_object($this->lesson))
+ {
+ $title = $this->lesson->title;
+ }
+ }
+ if ($app->get('sitename_pagetitles', 0) == 1)
+ {
+ $title = Text::sprintf('JPAGETITLE', $app->get('sitename'), $title);
+ }
+ elseif ($app->get('sitename_pagetitles', 0) == 2)
+ {
+ $title = Text::sprintf('JPAGETITLE', $title, $app->get('sitename'));
+ }
+ $this->document->setTitle($title);
+ }
+}
\ No newline at end of file
diff --git a/deployed/tflearn/components/com_tflearn/tmpl/course/default.php b/deployed/tflearn/components/com_tflearn/tmpl/course/default.php
new file mode 100644
index 00000000..7620e37d
--- /dev/null
+++ b/deployed/tflearn/components/com_tflearn/tmpl/course/default.php
@@ -0,0 +1,92 @@
+get_param('course_layout', 'plain');
+
+$modules = json_decode($this->item->modules, true);
+
+$course_modtitle_class = $this->get_param('course_modtitle_class', '');
+$mod_title_class = empty($course_modtitle_class) ? '' : ' class="' . $course_modtitle_class . '"';
+
+$i = 1;
+if (is_array($modules))
+{
+ foreach ($modules as $module)
+ {
+ // Get lessons for each module
+ $mod = TfDb::get_item('tfl_modules', $module['module_id']);
+
+ if ($mod->published)
+ {
+ $mod->title = empty($module['module_name']) ? $mod->title : $module['module_name'];
+
+ $this->tabs[$i-1][0] = '' . $mod->title . '
';
+
+ $lesson_order = $this->get_param('lessons_order_col', 'ordering') . ' ' . $this->get_param('lessons_order_dirn', 'ASC');
+ $conditions = array(
+ array('module', '=', $module['module_id']),
+ array('published', '=', 1)
+ );
+ $lessons = TfDb::get_items('tfl_lessons', $conditions, $lesson_order);
+
+ foreach ($lessons as $lesson)
+ {
+ $this->lesson = $lesson;
+
+ $this->tabs[$i-1][1] .= $this->loadTemplate('lesson');
+ }
+ $i++;
+ }
+ }
+}
+?>
+
+item->title);
+
+ // 2. Image
+ if (!empty($this->item->image) && $this->get_param('course_show_image'))
+ {
+ TfHtml::image($this->item->image, $this->item->title, 'img-fluid img-thumbnail mb-3');
+ }
+
+ // 3. Description
+ TfHtml::simple($this->item->description);
+
+ // 4. Enrol button at top
+ if ($this->item->enrol != 'none')
+ {
+ $enrol_button_location = $this->get_param('enrol_button_location', 3);
+ if ($enrol_button_location == 1 || $enrol_button_location == 3)
+ {
+ echo $this->loadTemplate('button');
+ }
+ }
+
+ // 5. Modules and lessons
+ echo $this->loadTemplate('layout_' . $course_layout);
+
+ // 6. Enrol button at botttom
+ if ($this->item->enrol != 'none')
+ {
+ if ($enrol_button_location == 2 || $enrol_button_location == 3)
+ {
+ echo $this->loadTemplate('button');
+ }
+ }
+
+ // 7. Structured data
+ if ($this->get_param('enable_sd', 0))
+ {
+ echo $this->loadTemplate('tfsd');
+ }
+?>
\ No newline at end of file
diff --git a/deployed/tflearn/components/com_tflearn/tmpl/course/default_button.php b/deployed/tflearn/components/com_tflearn/tmpl/course/default_button.php
new file mode 100644
index 00000000..47bd5874
--- /dev/null
+++ b/deployed/tflearn/components/com_tflearn/tmpl/course/default_button.php
@@ -0,0 +1,21 @@
+get_param('course_button_class') ? 'class="' . $this->get_param('course_button_class') . '"' : '';
+
+if ($this->item->enrol == 'self')
+{
+ $this->action_button(Text::_('COM_TFLEARN_ENROL_NOW'), 'course.enrol', $this->get_param('course_button_class'));
+}
+elseif ($this->item->enrol == 'external')
+{
+ echo '' . Text::_('COM_TFLEARN_ENROL_NOW') . ' ';
+}
+?>
\ No newline at end of file
diff --git a/deployed/tflearn/components/com_tflearn/tmpl/course/default_layout_accordion.php b/deployed/tflearn/components/com_tflearn/tmpl/course/default_layout_accordion.php
new file mode 100644
index 00000000..61fdd074
--- /dev/null
+++ b/deployed/tflearn/components/com_tflearn/tmpl/course/default_layout_accordion.php
@@ -0,0 +1,11 @@
+tabs);
\ No newline at end of file
diff --git a/deployed/tflearn/components/com_tflearn/tmpl/course/default_layout_plain.php b/deployed/tflearn/components/com_tflearn/tmpl/course/default_layout_plain.php
new file mode 100644
index 00000000..e8751c0b
--- /dev/null
+++ b/deployed/tflearn/components/com_tflearn/tmpl/course/default_layout_plain.php
@@ -0,0 +1,11 @@
+tabs);
\ No newline at end of file
diff --git a/deployed/tflearn/components/com_tflearn/tmpl/course/default_layout_tabs.php b/deployed/tflearn/components/com_tflearn/tmpl/course/default_layout_tabs.php
new file mode 100644
index 00000000..e65ef6d7
--- /dev/null
+++ b/deployed/tflearn/components/com_tflearn/tmpl/course/default_layout_tabs.php
@@ -0,0 +1,11 @@
+tabs);
\ No newline at end of file
diff --git a/deployed/tflearn/components/com_tflearn/tmpl/course/default_lesson.php b/deployed/tflearn/components/com_tflearn/tmpl/course/default_lesson.php
new file mode 100644
index 00000000..c8e216ef
--- /dev/null
+++ b/deployed/tflearn/components/com_tflearn/tmpl/course/default_lesson.php
@@ -0,0 +1,41 @@
+
+
+
lesson->title; ?>
+ lesson->short_desc)) : ?>
+ lesson->short_desc; ?>
+
+
+ getModel()->get_param('auto_description');
+ if ($auto_description)
+ {
+ $jids = json_decode($this->lesson->jids);
+ $titles = array();
+ foreach ($jids as $jid)
+ {
+ $titles[] = $this->getModel()->get_lesson_title($jid->content_id, $this->lesson->content_source);
+ }
+ }
+
+ if ($auto_description == 1)
+ {
+ echo implode('; ', $titles);
+ }
+ elseif ($auto_description == 2)
+ {
+ echo '
';
+ foreach ($titles as $title)
+ {
+ echo '' . $title . ' ';
+ }
+ echo ' ';
+ }
+ ?>
+
\ No newline at end of file
diff --git a/deployed/tflearn/components/com_tflearn/tmpl/course/default_tfsd.php b/deployed/tflearn/components/com_tflearn/tmpl/course/default_tfsd.php
new file mode 100644
index 00000000..e1e97947
--- /dev/null
+++ b/deployed/tflearn/components/com_tflearn/tmpl/course/default_tfsd.php
@@ -0,0 +1,26 @@
+item->title);
+
+$json = TfSd::set_property($json, 'description', $this->item->short_desc);
+
+$provider = array(
+ '@type' => 'Organization',
+ 'name' => $this->get_param('provider', '')
+ );
+
+$json = TfSd::set_property($json, 'provider', $provider);
+
+TfSd::display_sd($json);
+?>
\ No newline at end of file
diff --git a/deployed/tflearn/components/com_tflearn/tmpl/courses/default.php b/deployed/tflearn/components/com_tflearn/tmpl/courses/default.php
new file mode 100644
index 00000000..965562cf
--- /dev/null
+++ b/deployed/tflearn/components/com_tflearn/tmpl/courses/default.php
@@ -0,0 +1,68 @@
+params->get('show_page_heading', 0))
+{
+ $title_class = $this->get_param('courses_title_class', '');
+ TfHtml::heading($this->escape($this->params->get('page_heading')), 'h1', $title_class);
+}
+
+// 2. Description
+TfHtml::simple($this->params->get('description', ''));
+
+// 3. No items messgae
+if (empty($this->items))
+{
+ Alert::display(Text::_('JGLOBAL_NO_MATCHING_RESULTS'), array('alert_class' => 'bg-warning'));
+}
+?>
+
+items)) : ?>
+
+ params->get('num_columns', 2);
+
+ $properties = array(
+ 'button_text' => $this->params->get('button_text'),
+ 'button_class' => $this->params->get('button_class'),
+ 'card_class' => $this->get_param('courses_item_class', '')
+ );
+
+ $options = array('show_title' => 1, 'show_date' => 0);
+
+ echo '';
+
+ foreach ($this->items as $course) :
+
+ $course->url = Route::_('index.php?option=com_tflearn&view=course&id=' . $course->id);
+
+ $course->description = $course->short_desc;
+
+ Card::display($course, $properties, $options);
+
+ endforeach;
+
+ echo '
';
+ ?>
+
+
+
+get_param('enable_sd', 0))
+{
+ echo $this->loadTemplate('tfsd');
+}
+?>
\ No newline at end of file
diff --git a/deployed/tflearn/components/com_tflearn/tmpl/courses/default.xml b/deployed/tflearn/components/com_tflearn/tmpl/courses/default.xml
new file mode 100644
index 00000000..0a9ff0e4
--- /dev/null
+++ b/deployed/tflearn/components/com_tflearn/tmpl/courses/default.xml
@@ -0,0 +1,62 @@
+
+
+
+ Displays courses
+
+
+
+
+
+
+ - Select Course Type -
+ All
+
+
+
+
+
+
+
+
+
+
+
+ 1
+ 2
+ 3
+ 4
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/deployed/tflearn/components/com_tflearn/tmpl/courses/default_tfsd.php b/deployed/tflearn/components/com_tflearn/tmpl/courses/default_tfsd.php
new file mode 100644
index 00000000..4a946e3d
--- /dev/null
+++ b/deployed/tflearn/components/com_tflearn/tmpl/courses/default_tfsd.php
@@ -0,0 +1,33 @@
+items as $course)
+{
+ $url = Route::_('index.php?option=com_tflearn&view=course&id=' . $course->id);
+
+ $item_list[] = array(
+ '@type' => 'ListItem',
+ 'position' => $i,
+ 'url' => $url
+ );
+
+ $i++;
+}
+
+$json = TfSd::set_property($json, 'itemListElement', $item_list);
+
+TfSd::display_sd($json);
+?>
\ No newline at end of file
diff --git a/deployed/tflearn/components/com_tflearn/tmpl/page/default.php b/deployed/tflearn/components/com_tflearn/tmpl/page/default.php
new file mode 100644
index 00000000..5291f89d
--- /dev/null
+++ b/deployed/tflearn/components/com_tflearn/tmpl/page/default.php
@@ -0,0 +1,47 @@
+get_param('show_all_pages', 1))
+{
+ echo '';
+ echo ' ' . Text::_('COM_TFLEARN_ALL_PAGES') . ' ';
+}
+
+// 2. Page Title
+$page_title_class = $this->get_param('page_title_class', '');
+TfHtml::heading($this->item->title, 'h1', $page_title_class);
+
+// 3. Description
+if ($this->get_param('prepare_content', 0))
+{
+ $this->item->description = HTMLHelper::_('content.prepare', $this->item->description);
+}
+TfHtml::simple($this->item->description);
+
+// 4. Sections - all or one at a time
+if ($this->section == 'all')
+{
+ echo $this->loadTemplate('sections');
+}
+elseif ($this->section <= $this->total_sections)
+{
+ echo $this->loadTemplate('section');
+}
+
+// 5. Lesson navigation
+if ($this->get_param('show_nav', 1))
+{
+ echo $this->loadTemplate('navigation');
+}
+?>
diff --git a/deployed/tflearn/components/com_tflearn/tmpl/page/default_navigation.php b/deployed/tflearn/components/com_tflearn/tmpl/page/default_navigation.php
new file mode 100644
index 00000000..1b7cdba8
--- /dev/null
+++ b/deployed/tflearn/components/com_tflearn/tmpl/page/default_navigation.php
@@ -0,0 +1,28 @@
+getModel()->getNav($this->item->id, $this->item->module);
+?>
+
+
+
\ No newline at end of file
diff --git a/deployed/tflearn/components/com_tflearn/tmpl/page/default_section.php b/deployed/tflearn/components/com_tflearn/tmpl/page/default_section.php
new file mode 100644
index 00000000..80672b74
--- /dev/null
+++ b/deployed/tflearn/components/com_tflearn/tmpl/page/default_section.php
@@ -0,0 +1,81 @@
+get_param('article_title_class', '');
+
+$jid = 'jids' . ($this->section - 1);
+
+$output = '';
+
+$content_source = $this->item->content_source;
+if ($content_source == 'joomla')
+{
+ $ja = $this->getModel()->getArticle($this->item->jids->$jid->content_id);
+ if ($this->item->jids->$jid->show_title)
+ {
+ $output .= TfHtml::heading($ja->title, 'h2', $article_title_class, false);
+ }
+ $output .= $ja->introtext . $ja->fulltext . ' ';
+
+}
+elseif ($content_source == 'pages')
+{
+ $ja = TfDb::get_item('tfl_pages', $this->item->jids->$jid->content_id);
+ if ($this->item->jids->$jid->show_title)
+ {
+ $output .= TfHtml::heading($ja->title, 'h2', $article_title_class, false);
+ }
+ $output .= $ja->description;
+}
+
+if ($this->getModel()->get_param('prepare_content', 0))
+{
+ $output = HTMLHelper::_('content.prepare', $output);
+}
+
+echo $output;
+?>
+
+
+
+
+
+section/$this->total_sections)*100);
+echo '';
+ Progress::display($progress, array('progress_class' => ' bg-success text-white'));
+echo '
';
+?>
+
+section == $this->total_sections && $this->item->completion_type == 'view')
+{
+ $this->getModel()->mark_complete($this->item->id, $this->user->id);
+}
+?>
\ No newline at end of file
diff --git a/deployed/tflearn/components/com_tflearn/tmpl/page/default_sections.php b/deployed/tflearn/components/com_tflearn/tmpl/page/default_sections.php
new file mode 100644
index 00000000..72a76a88
--- /dev/null
+++ b/deployed/tflearn/components/com_tflearn/tmpl/page/default_sections.php
@@ -0,0 +1,57 @@
+get_param('article_title_class', '');
+
+$output = '';
+
+if (is_object($this->item->jids))
+{
+ $content_source = $this->item->content_source;
+ if ($content_source == 'joomla')
+ {
+ foreach ($this->item->jids as $jid)
+ {
+ $ja = $this->getModel()->getArticle($jid->content_id);
+ if ($jid->show_title)
+ {
+ $output .= TfHtml::heading($ja->title, 'h2', $article_title_class, false);
+ }
+ $output .= $ja->introtext . $ja->fulltext;
+ }
+ }
+ elseif ($content_source == 'pages')
+ {
+ foreach ($this->item->jids as $jid)
+ {
+ $ja = TfDb::get_item('tfl_pages', $jid->content_id);
+ if ($jid->show_title)
+ {
+ $output .= TfHtml::heading($ja->title, 'h2', $article_title_class, false);
+ }
+ $output .= $ja->description;
+ }
+ }
+}
+
+if ($this->get_param('prepare_content', 0))
+{
+ $output = HTMLHelper::_('content.prepare', $output);
+}
+
+echo $output;
+
+// Mark lesson as complete for completion type: view
+if ($this->item->completion_type == 'view')
+{
+ $this->getModel()->mark_complete($this->item->id, $this->user->id);
+}
diff --git a/deployed/tflearn/components/com_tflearn/tmpl/path/default.php b/deployed/tflearn/components/com_tflearn/tmpl/path/default.php
new file mode 100644
index 00000000..74ca8fb4
--- /dev/null
+++ b/deployed/tflearn/components/com_tflearn/tmpl/path/default.php
@@ -0,0 +1,71 @@
+get_param('enable_completion', 1)) && !$this->user->guest;
+$path_layout = $this->getModel()->get_param('path_layout', 'plain');
+
+$modules = (array) $this->item->modules;
+
+$path_modtitle_class = $this->get_param('path_modtitle_class');
+$mod_title_class = empty($path_modtitle_class) ? '' : ' class="' . $path_modtitle_class . '"';
+
+if (!empty($modules))
+{
+ $this->total_lessons = $this->getModel()->total_lessons($modules);
+}
+
+$i = 1;
+foreach ($modules as $module)
+{
+ $module = (array) $module;
+
+ // Get lessons for each module
+ if (!empty($module))
+ {
+ $mod = TfDb::get_item('tfl_modules' , $module['module_id']);
+
+ if ($mod->published)
+ {
+ $mod->title = empty($module['module_name']) ? $mod->title : $module['module_name'];
+
+ $this->tabs[$i-1][0] = '' . $mod->title . '
';
+
+ $lesson_order = $this->get_param('lessons_order_col', 'ordering') . ' ' . $this->get_param('lessons_order_dirn', 'ASC');
+ $conditions = array(
+ array('module', '=', $module['module_id']),
+ array('published', '=', 1)
+ );
+ $lessons = TfDb::get_items('tfl_lessons', $conditions, $lesson_order);
+
+ foreach ($lessons as $lesson)
+ {
+ $this->lesson = $lesson;
+
+ $this->tabs[$i-1][1] .= $this->loadTemplate('lesson');
+ }
+ $i++;
+ }
+ }
+}
+?>
+item->title);
+
+ // 2. Modules and lessons
+ echo $this->loadTemplate('layout_' . $path_layout);
+
+ // 3. Progress bar
+ if ($enable_completion)
+ {
+ echo $this->loadTemplate('completion');
+ }
+?>
\ No newline at end of file
diff --git a/deployed/tflearn/components/com_tflearn/tmpl/path/default_completion.php b/deployed/tflearn/components/com_tflearn/tmpl/path/default_completion.php
new file mode 100644
index 00000000..5d485289
--- /dev/null
+++ b/deployed/tflearn/components/com_tflearn/tmpl/path/default_completion.php
@@ -0,0 +1,23 @@
+total_lessons) ? number_format(($this->complete/$this->total_lessons)*100) : 0;
+
+TfHtml::heading(Text::_('COM_TFLEARN_COMPLETION_STATUS'), 'h3', 'my-3');
+
+Progress::display($completed, array('progress_class' => 'bg-success text-white'));
+
+if ($completed == 100)
+{
+ $this->action_button(Text::_('COM_TFLEARN_COURSE_COMPLETE'), 'course.complete', 'my-3 btn bg-success text-white');
+}
+?>
\ No newline at end of file
diff --git a/deployed/tflearn/components/com_tflearn/tmpl/path/default_layout_accordion.php b/deployed/tflearn/components/com_tflearn/tmpl/path/default_layout_accordion.php
new file mode 100644
index 00000000..61fdd074
--- /dev/null
+++ b/deployed/tflearn/components/com_tflearn/tmpl/path/default_layout_accordion.php
@@ -0,0 +1,11 @@
+tabs);
\ No newline at end of file
diff --git a/deployed/tflearn/components/com_tflearn/tmpl/path/default_layout_plain.php b/deployed/tflearn/components/com_tflearn/tmpl/path/default_layout_plain.php
new file mode 100644
index 00000000..e8751c0b
--- /dev/null
+++ b/deployed/tflearn/components/com_tflearn/tmpl/path/default_layout_plain.php
@@ -0,0 +1,11 @@
+tabs);
\ No newline at end of file
diff --git a/deployed/tflearn/components/com_tflearn/tmpl/path/default_layout_tabs.php b/deployed/tflearn/components/com_tflearn/tmpl/path/default_layout_tabs.php
new file mode 100644
index 00000000..e65ef6d7
--- /dev/null
+++ b/deployed/tflearn/components/com_tflearn/tmpl/path/default_layout_tabs.php
@@ -0,0 +1,11 @@
+tabs);
\ No newline at end of file
diff --git a/deployed/tflearn/components/com_tflearn/tmpl/path/default_lesson.php b/deployed/tflearn/components/com_tflearn/tmpl/path/default_lesson.php
new file mode 100644
index 00000000..289f720b
--- /dev/null
+++ b/deployed/tflearn/components/com_tflearn/tmpl/path/default_lesson.php
@@ -0,0 +1,74 @@
+get_param('enable_completion')) && !$this->user->guest;
+
+$score = $this->getModel()->get_score($this->user->id, $this->lesson->id);
+$score = round($score, 1);
+
+$completion = $this->getModel()->get_completion($this->lesson->id, $this->user->id);
+$checked = ($completion) ? ' checked' : '';
+
+if ($completion && $enable_completion)
+{
+ $this->complete++;
+}
+
+$section = ($this->lesson->lesson_type == 'multi') ? '§ion=1' : '';
+$page_link = Route::_('index.php?option=com_tflearn&view=page&course=' . $this->item->id . '&id=' . $this->lesson->id . $section);
+$url = $page_link = Route::_('index.php?option=com_tflearn&view=page&course=' . $this->item->id . '&id=' . $this->lesson->id . $section);
+
+$link = '' . $this->lesson->title . ' ';
+?>
+
+
+
+
/>
+
+
+
+ lesson->resources, true);
+ foreach ($resources as $resource)
+ {
+ TfHtml::display_link_new($resource['title'], $resource['url'], 'mx-2 ' . $resource['class']);
+ }
+ ?>
+
+
+ lesson->questions)
+ {
+ if ($score)
+ {
+ $total_marks = $this->lesson->questions * $this->lesson->marks;
+ $score_text = Text::_('COM_TFLEARN_SCORE') . ': ' . $score . ' / ' . $total_marks;
+ $this->action_button($score_text, 'test.score', 'btn btn-sm ' . $this->get_param('score_btn_class'), '', array('lesson_id' => $this->lesson->id));
+ }
+
+ $this->action_button(Text::_('COM_TFLEARN_TEST'), 'test.start', 'btn btn-sm ' . $this->get_param('test_btn_class'), '', array('lesson_id' => $this->lesson->id));
+ }
+
+ if ($enable_completion)
+ {
+ if (!$completion && $this->lesson->completion_type == 'self')
+ {
+ $this->action_button(Text::_('COM_TFLEARN_MARK_COMPLETE'), 'completion.complete', 'btn btn-sm ' . $this->get_param('complete_btn_class'), '', array('lesson_id' => $this->lesson->id));
+ }
+ elseif ($completion)
+ {
+ $this->action_button(Text::_('COM_TFLEARN_MARK_INCOMPLETE'), 'completion.incomplete', 'btn btn-sm ' . $this->get_param('incomplete_btn_class'), '', array('lesson_id' => $this->lesson->id));
+ }
+ }
+ ?>
+
+
\ No newline at end of file
diff --git a/deployed/tflearn/components/com_tflearn/tmpl/paths/default.php b/deployed/tflearn/components/com_tflearn/tmpl/paths/default.php
new file mode 100644
index 00000000..cd24563b
--- /dev/null
+++ b/deployed/tflearn/components/com_tflearn/tmpl/paths/default.php
@@ -0,0 +1,76 @@
+get_param('enable_completion', 0) && !$this->user->guest;
+
+$path_class = $this->get_param('single_path_class');
+
+// 1. Page heading
+if ($this->params->get('show_page_heading', 0))
+{
+ $title_class = $this->get_param('paths_title_class', '');
+ TfHtml::heading($this->escape($this->params->get('page_heading')), 'h1', $title_class);
+}
+
+// 2. Description
+TfHtml::simple($this->params->get('description', ''));
+
+// 3. No items messgae
+if (empty($this->items))
+{
+ Alert::display($this->get_param('no_course_msg'), array('alert_class' => 'bg-warning'));
+}
+?>
+
+items)) : ?>
+
+ items as $path) :
+
+ $link = Route::_('index.php?option=com_tflearn&view=path&id=' . $path->id);
+
+ $modules = json_decode($path->modules, true);
+ $total_lessons = empty($modules) ? 0 : $this->getModel()->total_lessons($modules);
+
+ if ($enable_completion)
+ {
+ $complete = $complete = $this->getModel()->get_completion($this->user->id, $modules);
+ $completed = ($total_lessons) ? number_format(($complete/$total_lessons)*100) : 0;
+ }
+
+ echo '';
+
+ TfHtml::heading($path->title, 'h3');
+
+ if ($enable_completion)
+ {
+ Progress::display($completed, array('progress_class' => 'bg-success text-white'));
+ }
+
+ echo '
';
+ echo ' ' . Text::_('COM_TFLEARN_TEXT_TOTAL_LESSONS') . ' ' . $total_lessons . ' ';
+ if ($enable_completion)
+ {
+ echo ' ' . Text::_('COM_TFLEARN_TEXT_LESSONS_COMPLETED') . ' ' . $complete . ' ';
+ }
+ echo ' ';
+
+ Button::display($this->params->get('button_text'), array('button_class' => $this->params->get('button_class')), array('url' => $link));
+
+ echo '
';
+ endforeach;
+ ?>
+
+
\ No newline at end of file
diff --git a/deployed/tflearn/components/com_tflearn/tmpl/paths/default.xml b/deployed/tflearn/components/com_tflearn/tmpl/paths/default.xml
new file mode 100644
index 00000000..7ac0d2c0
--- /dev/null
+++ b/deployed/tflearn/components/com_tflearn/tmpl/paths/default.xml
@@ -0,0 +1,33 @@
+
+
+
+ All courses or learning paths user is enrolled in
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/deployed/tflearn/components/com_tflearn/tmpl/score/default.php b/deployed/tflearn/components/com_tflearn/tmpl/score/default.php
new file mode 100644
index 00000000..8fa5e1eb
--- /dev/null
+++ b/deployed/tflearn/components/com_tflearn/tmpl/score/default.php
@@ -0,0 +1,37 @@
+Review: ' . $this->lesson->title . '';
+
+foreach ($this->items as $item)
+{
+ echo '';
+ TfHtml::display_date($item->created);
+
+ echo '
Score: ' . $item->grade . '
';
+
+ $attempts = json_decode($item->attempts, true);
+ $questions = $this->getModel()->get_attempts($attempts);
+
+ $this->i = 1; // To store question number
+
+ foreach ($questions as $question)
+ {
+ $this->question = $question;
+ $qname = 'q' . $question->id;
+ $this->attempt = $attempts[$qname]; // Answer given or marked by student
+
+ echo $this->loadTemplate('question_type' . $question->q_type);
+
+ $this->i++;
+ }
+ echo '
';
+}
+?>
\ No newline at end of file
diff --git a/deployed/tflearn/components/com_tflearn/tmpl/score/default_question_type1.php b/deployed/tflearn/components/com_tflearn/tmpl/score/default_question_type1.php
new file mode 100644
index 00000000..0a1ed73d
--- /dev/null
+++ b/deployed/tflearn/components/com_tflearn/tmpl/score/default_question_type1.php
@@ -0,0 +1,33 @@
+
+i . '. '; ?>question->description; ?>
+
+question->options, true);
+$i = 0;
+
+echo '';
+foreach ($options_arr as $option)
+{
+ echo '';
+ echo $option['opt'];
+ if ($this->attempt == $i)
+ {
+ $icon = isset($option['is_correct']) ? 'check-circle text-success' : 'times-circle text-danger';
+ echo ' ';
+ }
+ if (isset($option['is_correct']) && $option['is_correct'])
+ {
+ echo ' Correct Answer ';
+ }
+ echo ' ';
+ $i++;
+}
+echo ' ';
+?>
\ No newline at end of file
diff --git a/deployed/tflearn/components/com_tflearn/tmpl/score/default_question_type2.php b/deployed/tflearn/components/com_tflearn/tmpl/score/default_question_type2.php
new file mode 100644
index 00000000..455324b9
--- /dev/null
+++ b/deployed/tflearn/components/com_tflearn/tmpl/score/default_question_type2.php
@@ -0,0 +1,35 @@
+attempt is an array
+?>
+i . '. '; ?>question->description; ?>
+
+question->options, true);
+$i = 0;
+
+echo '';
+foreach ($options_arr as $option)
+{
+ echo '';
+ echo $option['opt'];
+ if (in_array($i, $this->attempt))
+ {
+ $icon = isset($option['is_correct']) ? 'check-circle text-success' : 'times-circle text-danger';
+ echo ' ';
+ }
+ if (isset($option['is_correct']) && $option['is_correct'])
+ {
+ echo ' Correct Answer ';
+ }
+ echo ' ';
+ $i++;
+}
+echo ' ';
+?>
\ No newline at end of file
diff --git a/deployed/tflearn/components/com_tflearn/tmpl/score/default_question_type3.php b/deployed/tflearn/components/com_tflearn/tmpl/score/default_question_type3.php
new file mode 100644
index 00000000..5f7138cd
--- /dev/null
+++ b/deployed/tflearn/components/com_tflearn/tmpl/score/default_question_type3.php
@@ -0,0 +1,15 @@
+attempt == $this->question->answer) ? 'check-circle text-success' : 'times-circle text-danger';
+?>
+i . '. '; ?>question->description; ?>
+
+attempt; ?>
+
+Correct Answer question->answer; ?>
\ No newline at end of file
diff --git a/deployed/tflearn/components/com_tflearn/tmpl/score/default_question_type4.php b/deployed/tflearn/components/com_tflearn/tmpl/score/default_question_type4.php
new file mode 100644
index 00000000..108c9924
--- /dev/null
+++ b/deployed/tflearn/components/com_tflearn/tmpl/score/default_question_type4.php
@@ -0,0 +1,15 @@
+attempt) == strtolower($this->question->answer)) ? 'check-circle text-success' : 'times-circle text-danger';
+?>
+i . '. '; ?>question->description; ?>
+
+attempt; ?>
+
+Correct Answer question->answer; ?>
\ No newline at end of file
diff --git a/deployed/tflearn/components/com_tflearn/tmpl/score/default_question_type5.php b/deployed/tflearn/components/com_tflearn/tmpl/score/default_question_type5.php
new file mode 100644
index 00000000..41f59aa1
--- /dev/null
+++ b/deployed/tflearn/components/com_tflearn/tmpl/score/default_question_type5.php
@@ -0,0 +1,38 @@
+attempt is an array
+?>
+i . '. '; ?>question->description; ?>
+
+question->matching, true);
+$i = 0;
+
+echo '';
+foreach ($matchings as $matching)
+{
+ echo '';
+ echo $matching['col_a'] . ' - ' . $this->attempt[$i];
+ if ($matching['col_b'] == $this->attempt[$i])
+ {
+ $icon = 'check-circle text-success';
+ }
+ else
+ {
+ $icon = 'times-circle text-danger';
+ }
+ echo ' ';
+
+ echo ' Correct Answer ' . $matching['col_b'];
+
+ echo ' ';
+ $i++;
+}
+echo ' ';
+?>
\ No newline at end of file
diff --git a/deployed/tflearn/components/com_tflearn/tmpl/score/default_question_type6.php b/deployed/tflearn/components/com_tflearn/tmpl/score/default_question_type6.php
new file mode 100644
index 00000000..6357fec2
--- /dev/null
+++ b/deployed/tflearn/components/com_tflearn/tmpl/score/default_question_type6.php
@@ -0,0 +1,47 @@
+question->answer == 1 || strtoupper($this->question->answer) == 'T' || strtoupper($this->question->answer) == 'TRUE')
+{
+ $correct_answer = 1;
+}
+else
+{
+ $correct_answer = 0;
+}
+
+$icon = ($this->attempt == $correct_answer) ? 'check-circle text-success' : 'times-circle text-danger';
+?>
+i . '. '; ?>question->description; ?>
+
+';
+ echo '';
+ echo 'True';
+ if ($this->attempt == 1)
+ {
+ echo ' ';
+ }
+ if ($correct_answer == 1)
+ {
+ echo ' Correct Answer ';
+ }
+ echo ' ';
+ echo '';
+ echo 'False';
+ if ($this->attempt == 0)
+ {
+ echo ' ';
+ }
+ if ($correct_answer == 0)
+ {
+ echo ' Correct Answer ';
+ }
+ echo ' ';
+echo '';
+?>
\ No newline at end of file
diff --git a/deployed/tflearn/components/com_tflearn/tmpl/score/default_question_type7.php b/deployed/tflearn/components/com_tflearn/tmpl/score/default_question_type7.php
new file mode 100644
index 00000000..f6e2d8fd
--- /dev/null
+++ b/deployed/tflearn/components/com_tflearn/tmpl/score/default_question_type7.php
@@ -0,0 +1,9 @@
+
+i . '. '; ?>question->description; ?>
\ No newline at end of file
diff --git a/deployed/tflearn/components/com_tflearn/tmpl/scores/default.php b/deployed/tflearn/components/com_tflearn/tmpl/scores/default.php
new file mode 100644
index 00000000..2f9e2515
--- /dev/null
+++ b/deployed/tflearn/components/com_tflearn/tmpl/scores/default.php
@@ -0,0 +1,37 @@
+
+
+start_list_layout(); ?>
+
+items)) : ?>
+
+
+
+end_list_layout(); ?>
\ No newline at end of file
diff --git a/deployed/tflearn/components/com_tflearn/tmpl/scores/default.xml b/deployed/tflearn/components/com_tflearn/tmpl/scores/default.xml
new file mode 100644
index 00000000..c86db8cf
--- /dev/null
+++ b/deployed/tflearn/components/com_tflearn/tmpl/scores/default.xml
@@ -0,0 +1,21 @@
+
+
+
+ Displays scores of tests taken by the user.
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/deployed/tflearn/components/com_tflearn/tmpl/test/default.php b/deployed/tflearn/components/com_tflearn/tmpl/test/default.php
new file mode 100644
index 00000000..17ab99ca
--- /dev/null
+++ b/deployed/tflearn/components/com_tflearn/tmpl/test/default.php
@@ -0,0 +1,60 @@
+params->set('show_page_heading', 0);
+
+$total_marks = $this->lesson->questions * $this->lesson->marks;
+
+if (!$this->user->guest)
+{
+ $this->form->setValue('email', null, $this->user->email);
+ $this->form->setFieldAttribute('email', 'type', 'hidden');
+}
+
+$this->form->setValue('created_by', null, $this->user->id);
+$this->form->setValue('lesson_id', null, $this->lesson->id);
+$this->form->setValue('marks', null, $this->lesson->marks);
+
+$this->params->set('show_captcha', $this->get_param('show_captcha', 0));
+$this->params->set('custom_redirect', $this->get_param('custom_redirect'));
+$this->params->set('custom_message', $this->get_param('custom_message'));
+?>
+
+lesson->title; ?>
+
+
+ lesson->questions; ?>
+
+
+
+start_form_layout(); ?>
+
+ form->renderFieldset('general'); ?>
+
+ i = 1; // To store question number
+
+ foreach ($this->questions as $question)
+ {
+ $this->question = $question;
+
+ echo $this->loadTemplate('question_type' . $question['q_type']);
+
+ $this->i++;
+ }
+ ?>
+
+
+ button = $this->get_param('test_button');
+ ?>
+
+end_form_layout(); ?>
diff --git a/deployed/tflearn/components/com_tflearn/tmpl/test/default_question_title.php b/deployed/tflearn/components/com_tflearn/tmpl/test/default_question_title.php
new file mode 100644
index 00000000..5453097b
--- /dev/null
+++ b/deployed/tflearn/components/com_tflearn/tmpl/test/default_question_title.php
@@ -0,0 +1,13 @@
+
+
+ i . '. '; ?>question['description']; ?>
+
\ No newline at end of file
diff --git a/deployed/tflearn/components/com_tflearn/tmpl/test/default_question_type1.php b/deployed/tflearn/components/com_tflearn/tmpl/test/default_question_type1.php
new file mode 100644
index 00000000..80ea96a9
--- /dev/null
+++ b/deployed/tflearn/components/com_tflearn/tmpl/test/default_question_type1.php
@@ -0,0 +1,28 @@
+loadTemplate('question_title');
+
+$options_arr = json_decode($this->question['options'], true);
+
+$name = 'q' . $this->question['id']; // For example: q34
+$num = 0;
+foreach ($options_arr as $option)
+{
+ $label_id = $name . '.' . $num; // For example: q34.0
+
+ echo '';
+ echo ' ';
+ echo '' . $option['opt'] . ' ';
+ echo '
';
+
+ $num++;
+}
+?>
\ No newline at end of file
diff --git a/deployed/tflearn/components/com_tflearn/tmpl/test/default_question_type2.php b/deployed/tflearn/components/com_tflearn/tmpl/test/default_question_type2.php
new file mode 100644
index 00000000..cc7861b7
--- /dev/null
+++ b/deployed/tflearn/components/com_tflearn/tmpl/test/default_question_type2.php
@@ -0,0 +1,29 @@
+loadTemplate('question_title');
+
+$options_arr = json_decode($this->question['options'], true);
+
+$name = 'q' . $this->question['id']; // For example: q34
+$num = 0;
+foreach ($options_arr as $option)
+{
+ $label_id = $name . '.' . $num; // For example: q34.0
+
+ // In case of checkbox, name is different for each checkbox.
+ echo '';
+ echo ' ';
+ echo '' . $option['opt'] . ' ';
+ echo '
';
+
+ $num++;
+}
+?>
\ No newline at end of file
diff --git a/deployed/tflearn/components/com_tflearn/tmpl/test/default_question_type3.php b/deployed/tflearn/components/com_tflearn/tmpl/test/default_question_type3.php
new file mode 100644
index 00000000..350e3a08
--- /dev/null
+++ b/deployed/tflearn/components/com_tflearn/tmpl/test/default_question_type3.php
@@ -0,0 +1,18 @@
+loadTemplate('question_title');
+
+$name = 'q' . $this->question['id']; // For example: q34
+
+$label_id = $name;
+
+echo ' ';
+?>
\ No newline at end of file
diff --git a/deployed/tflearn/components/com_tflearn/tmpl/test/default_question_type4.php b/deployed/tflearn/components/com_tflearn/tmpl/test/default_question_type4.php
new file mode 100644
index 00000000..aa0881f7
--- /dev/null
+++ b/deployed/tflearn/components/com_tflearn/tmpl/test/default_question_type4.php
@@ -0,0 +1,18 @@
+loadTemplate('question_title');
+
+$name = 'q' . $this->question['id']; // For example: q34
+
+$label_id = $name;
+
+echo ' ';
+?>
\ No newline at end of file
diff --git a/deployed/tflearn/components/com_tflearn/tmpl/test/default_question_type5.php b/deployed/tflearn/components/com_tflearn/tmpl/test/default_question_type5.php
new file mode 100644
index 00000000..72bfa6b0
--- /dev/null
+++ b/deployed/tflearn/components/com_tflearn/tmpl/test/default_question_type5.php
@@ -0,0 +1,46 @@
+loadTemplate('question_title');
+
+$column_a = array();
+$column_b = array();
+
+$matchings = json_decode($this->question['matching'], true);
+
+foreach ($matchings as $matching)
+{
+ $column_a[] = $matching['col_a'];
+ $column_b[] = $matching['col_b'];
+}
+
+shuffle($column_b);
+
+$name = 'q' . $this->question['id']; // For example: q34
+$num = 0;
+foreach ($column_a as $col_a)
+{
+ $label_id = $name . '.' . $num; // For example: q34.0
+
+ // Name is different for each select
+ echo '';
+ echo '' . $col_a . ' ';
+ echo '';
+ echo '- Select - ';
+ foreach ($column_b as $col_b)
+ {
+ echo '' . $col_b . ' ';
+ }
+ echo ' ';
+ echo '
';
+
+ $num++;
+}
+?>
diff --git a/deployed/tflearn/components/com_tflearn/tmpl/test/default_question_type6.php b/deployed/tflearn/components/com_tflearn/tmpl/test/default_question_type6.php
new file mode 100644
index 00000000..3bb53ea6
--- /dev/null
+++ b/deployed/tflearn/components/com_tflearn/tmpl/test/default_question_type6.php
@@ -0,0 +1,24 @@
+loadTemplate('question_title');
+
+$name = 'q' . $this->question['id']; // For example: q34
+
+echo '';
+ echo ' ';
+ echo 'True ';
+echo '
';
+
+echo '';
+ echo ' ';
+ echo 'False ';
+echo '
';
+?>
\ No newline at end of file
diff --git a/deployed/tflearn/components/com_tflearn/tmpl/test/default_question_type7.php b/deployed/tflearn/components/com_tflearn/tmpl/test/default_question_type7.php
new file mode 100644
index 00000000..7a8e9c7b
--- /dev/null
+++ b/deployed/tflearn/components/com_tflearn/tmpl/test/default_question_type7.php
@@ -0,0 +1,12 @@
+loadTemplate('question_title');
+?>
\ No newline at end of file
diff --git a/deployed/tflearn/libraries/techfry/forms/blank.xml b/deployed/tflearn/libraries/techfry/forms/blank.xml
new file mode 100644
index 00000000..2b19b2f6
--- /dev/null
+++ b/deployed/tflearn/libraries/techfry/forms/blank.xml
@@ -0,0 +1,5 @@
+
+
\ No newline at end of file
diff --git a/deployed/tflearn/libraries/techfry/forms/bs/accordion.xml b/deployed/tflearn/libraries/techfry/forms/bs/accordion.xml
new file mode 100644
index 00000000..82f9e8d7
--- /dev/null
+++ b/deployed/tflearn/libraries/techfry/forms/bs/accordion.xml
@@ -0,0 +1,14 @@
+
+
\ No newline at end of file
diff --git a/deployed/tflearn/libraries/techfry/forms/bs/alert.xml b/deployed/tflearn/libraries/techfry/forms/bs/alert.xml
new file mode 100644
index 00000000..546337d2
--- /dev/null
+++ b/deployed/tflearn/libraries/techfry/forms/bs/alert.xml
@@ -0,0 +1,14 @@
+
+
\ No newline at end of file
diff --git a/deployed/tflearn/libraries/techfry/forms/bs/badge.xml b/deployed/tflearn/libraries/techfry/forms/bs/badge.xml
new file mode 100644
index 00000000..fd36fa56
--- /dev/null
+++ b/deployed/tflearn/libraries/techfry/forms/bs/badge.xml
@@ -0,0 +1,10 @@
+
+
\ No newline at end of file
diff --git a/deployed/tflearn/libraries/techfry/forms/bs/button_link.xml b/deployed/tflearn/libraries/techfry/forms/bs/button_link.xml
new file mode 100644
index 00000000..018bd05d
--- /dev/null
+++ b/deployed/tflearn/libraries/techfry/forms/bs/button_link.xml
@@ -0,0 +1,18 @@
+
+
\ No newline at end of file
diff --git a/deployed/tflearn/libraries/techfry/forms/bs/iconbox.xml b/deployed/tflearn/libraries/techfry/forms/bs/iconbox.xml
new file mode 100644
index 00000000..d00b1ce2
--- /dev/null
+++ b/deployed/tflearn/libraries/techfry/forms/bs/iconbox.xml
@@ -0,0 +1,36 @@
+
+
\ No newline at end of file
diff --git a/deployed/tflearn/libraries/techfry/forms/bs/progress.xml b/deployed/tflearn/libraries/techfry/forms/bs/progress.xml
new file mode 100644
index 00000000..216b7a43
--- /dev/null
+++ b/deployed/tflearn/libraries/techfry/forms/bs/progress.xml
@@ -0,0 +1,10 @@
+
+
\ No newline at end of file
diff --git a/deployed/tflearn/libraries/techfry/forms/bs/social.xml b/deployed/tflearn/libraries/techfry/forms/bs/social.xml
new file mode 100644
index 00000000..a451d876
--- /dev/null
+++ b/deployed/tflearn/libraries/techfry/forms/bs/social.xml
@@ -0,0 +1,15 @@
+
+
\ No newline at end of file
diff --git a/deployed/tflearn/libraries/techfry/forms/bs/u_background.xml b/deployed/tflearn/libraries/techfry/forms/bs/u_background.xml
new file mode 100644
index 00000000..3a1ad674
--- /dev/null
+++ b/deployed/tflearn/libraries/techfry/forms/bs/u_background.xml
@@ -0,0 +1,60 @@
+
+
\ No newline at end of file
diff --git a/deployed/tflearn/libraries/techfry/forms/bs/u_border.xml b/deployed/tflearn/libraries/techfry/forms/bs/u_border.xml
new file mode 100644
index 00000000..e27ca068
--- /dev/null
+++ b/deployed/tflearn/libraries/techfry/forms/bs/u_border.xml
@@ -0,0 +1,65 @@
+
+
\ No newline at end of file
diff --git a/deployed/tflearn/libraries/techfry/forms/bs/u_spacing.xml b/deployed/tflearn/libraries/techfry/forms/bs/u_spacing.xml
new file mode 100644
index 00000000..2117b8b5
--- /dev/null
+++ b/deployed/tflearn/libraries/techfry/forms/bs/u_spacing.xml
@@ -0,0 +1,68 @@
+
+
\ No newline at end of file
diff --git a/deployed/tflearn/libraries/techfry/forms/bs/u_text.xml b/deployed/tflearn/libraries/techfry/forms/bs/u_text.xml
new file mode 100644
index 00000000..cf9eac9f
--- /dev/null
+++ b/deployed/tflearn/libraries/techfry/forms/bs/u_text.xml
@@ -0,0 +1,65 @@
+
+
\ No newline at end of file
diff --git a/deployed/tflearn/libraries/techfry/forms/button.xml b/deployed/tflearn/libraries/techfry/forms/button.xml
new file mode 100644
index 00000000..4faabfc9
--- /dev/null
+++ b/deployed/tflearn/libraries/techfry/forms/button.xml
@@ -0,0 +1,14 @@
+
+
\ No newline at end of file
diff --git a/deployed/tflearn/libraries/techfry/forms/export.xml b/deployed/tflearn/libraries/techfry/forms/export.xml
new file mode 100644
index 00000000..98f82e4e
--- /dev/null
+++ b/deployed/tflearn/libraries/techfry/forms/export.xml
@@ -0,0 +1,48 @@
+
+
\ No newline at end of file
diff --git a/deployed/tflearn/libraries/techfry/forms/fields/calendar.xml b/deployed/tflearn/libraries/techfry/forms/fields/calendar.xml
new file mode 100644
index 00000000..4138b2cd
--- /dev/null
+++ b/deployed/tflearn/libraries/techfry/forms/fields/calendar.xml
@@ -0,0 +1,82 @@
+
+
\ No newline at end of file
diff --git a/deployed/tflearn/libraries/techfry/forms/fields/checkboxes.xml b/deployed/tflearn/libraries/techfry/forms/fields/checkboxes.xml
new file mode 100644
index 00000000..083e5049
--- /dev/null
+++ b/deployed/tflearn/libraries/techfry/forms/fields/checkboxes.xml
@@ -0,0 +1,10 @@
+
+
\ No newline at end of file
diff --git a/deployed/tflearn/libraries/techfry/forms/fields/color.xml b/deployed/tflearn/libraries/techfry/forms/fields/color.xml
new file mode 100644
index 00000000..fb041dc0
--- /dev/null
+++ b/deployed/tflearn/libraries/techfry/forms/fields/color.xml
@@ -0,0 +1,14 @@
+
+
\ No newline at end of file
diff --git a/deployed/tflearn/libraries/techfry/forms/fields/email.xml b/deployed/tflearn/libraries/techfry/forms/fields/email.xml
new file mode 100644
index 00000000..0797642d
--- /dev/null
+++ b/deployed/tflearn/libraries/techfry/forms/fields/email.xml
@@ -0,0 +1,10 @@
+
+
\ No newline at end of file
diff --git a/deployed/tflearn/libraries/techfry/forms/fields/file.xml b/deployed/tflearn/libraries/techfry/forms/fields/file.xml
new file mode 100644
index 00000000..9fb4e25a
--- /dev/null
+++ b/deployed/tflearn/libraries/techfry/forms/fields/file.xml
@@ -0,0 +1,14 @@
+
+
\ No newline at end of file
diff --git a/deployed/tflearn/libraries/techfry/forms/fields/filelist.xml b/deployed/tflearn/libraries/techfry/forms/fields/filelist.xml
new file mode 100644
index 00000000..64bb51dd
--- /dev/null
+++ b/deployed/tflearn/libraries/techfry/forms/fields/filelist.xml
@@ -0,0 +1,29 @@
+
+
\ No newline at end of file
diff --git a/deployed/tflearn/libraries/techfry/forms/fields/folderlist.xml b/deployed/tflearn/libraries/techfry/forms/fields/folderlist.xml
new file mode 100644
index 00000000..d869cbc2
--- /dev/null
+++ b/deployed/tflearn/libraries/techfry/forms/fields/folderlist.xml
@@ -0,0 +1,29 @@
+
+
\ No newline at end of file
diff --git a/deployed/tflearn/libraries/techfry/forms/fields/imagelist.xml b/deployed/tflearn/libraries/techfry/forms/fields/imagelist.xml
new file mode 100644
index 00000000..4cd3c6f9
--- /dev/null
+++ b/deployed/tflearn/libraries/techfry/forms/fields/imagelist.xml
@@ -0,0 +1,29 @@
+
+
\ No newline at end of file
diff --git a/deployed/tflearn/libraries/techfry/forms/fields/integer.xml b/deployed/tflearn/libraries/techfry/forms/fields/integer.xml
new file mode 100644
index 00000000..09234b40
--- /dev/null
+++ b/deployed/tflearn/libraries/techfry/forms/fields/integer.xml
@@ -0,0 +1,19 @@
+
+
\ No newline at end of file
diff --git a/deployed/tflearn/libraries/techfry/forms/fields/list.xml b/deployed/tflearn/libraries/techfry/forms/fields/list.xml
new file mode 100644
index 00000000..665b6406
--- /dev/null
+++ b/deployed/tflearn/libraries/techfry/forms/fields/list.xml
@@ -0,0 +1,22 @@
+
+
\ No newline at end of file
diff --git a/deployed/tflearn/libraries/techfry/forms/fields/note.xml b/deployed/tflearn/libraries/techfry/forms/fields/note.xml
new file mode 100644
index 00000000..c7feb255
--- /dev/null
+++ b/deployed/tflearn/libraries/techfry/forms/fields/note.xml
@@ -0,0 +1,19 @@
+
+
\ No newline at end of file
diff --git a/deployed/tflearn/libraries/techfry/forms/fields/number.xml b/deployed/tflearn/libraries/techfry/forms/fields/number.xml
new file mode 100644
index 00000000..e309bab8
--- /dev/null
+++ b/deployed/tflearn/libraries/techfry/forms/fields/number.xml
@@ -0,0 +1,19 @@
+
+
\ No newline at end of file
diff --git a/deployed/tflearn/libraries/techfry/forms/fields/password.xml b/deployed/tflearn/libraries/techfry/forms/fields/password.xml
new file mode 100644
index 00000000..5fdce1bd
--- /dev/null
+++ b/deployed/tflearn/libraries/techfry/forms/fields/password.xml
@@ -0,0 +1,10 @@
+
+
\ No newline at end of file
diff --git a/deployed/tflearn/libraries/techfry/forms/fields/radio.xml b/deployed/tflearn/libraries/techfry/forms/fields/radio.xml
new file mode 100644
index 00000000..a0fbf9e4
--- /dev/null
+++ b/deployed/tflearn/libraries/techfry/forms/fields/radio.xml
@@ -0,0 +1,12 @@
+
+
\ No newline at end of file
diff --git a/deployed/tflearn/libraries/techfry/forms/fields/range.xml b/deployed/tflearn/libraries/techfry/forms/fields/range.xml
new file mode 100644
index 00000000..e309bab8
--- /dev/null
+++ b/deployed/tflearn/libraries/techfry/forms/fields/range.xml
@@ -0,0 +1,19 @@
+
+
\ No newline at end of file
diff --git a/deployed/tflearn/libraries/techfry/forms/fields/subform.xml b/deployed/tflearn/libraries/techfry/forms/fields/subform.xml
new file mode 100644
index 00000000..e4a173e8
--- /dev/null
+++ b/deployed/tflearn/libraries/techfry/forms/fields/subform.xml
@@ -0,0 +1,23 @@
+
+
\ No newline at end of file
diff --git a/deployed/tflearn/libraries/techfry/forms/fields/tel.xml b/deployed/tflearn/libraries/techfry/forms/fields/tel.xml
new file mode 100644
index 00000000..2b19b2f6
--- /dev/null
+++ b/deployed/tflearn/libraries/techfry/forms/fields/tel.xml
@@ -0,0 +1,5 @@
+
+
\ No newline at end of file
diff --git a/deployed/tflearn/libraries/techfry/forms/fields/text.xml b/deployed/tflearn/libraries/techfry/forms/fields/text.xml
new file mode 100644
index 00000000..3018366b
--- /dev/null
+++ b/deployed/tflearn/libraries/techfry/forms/fields/text.xml
@@ -0,0 +1,9 @@
+
+
\ No newline at end of file
diff --git a/deployed/tflearn/libraries/techfry/forms/fields/textarea.xml b/deployed/tflearn/libraries/techfry/forms/fields/textarea.xml
new file mode 100644
index 00000000..44ae8415
--- /dev/null
+++ b/deployed/tflearn/libraries/techfry/forms/fields/textarea.xml
@@ -0,0 +1,14 @@
+
+
\ No newline at end of file
diff --git a/deployed/tflearn/libraries/techfry/forms/fields/url.xml b/deployed/tflearn/libraries/techfry/forms/fields/url.xml
new file mode 100644
index 00000000..a43dadf2
--- /dev/null
+++ b/deployed/tflearn/libraries/techfry/forms/fields/url.xml
@@ -0,0 +1,19 @@
+
+
\ No newline at end of file
diff --git a/deployed/tflearn/libraries/techfry/forms/import.xml b/deployed/tflearn/libraries/techfry/forms/import.xml
new file mode 100644
index 00000000..ada93f24
--- /dev/null
+++ b/deployed/tflearn/libraries/techfry/forms/import.xml
@@ -0,0 +1,26 @@
+
+
\ No newline at end of file
diff --git a/deployed/tflearn/libraries/techfry/forms/query.xml b/deployed/tflearn/libraries/techfry/forms/query.xml
new file mode 100644
index 00000000..00932a18
--- /dev/null
+++ b/deployed/tflearn/libraries/techfry/forms/query.xml
@@ -0,0 +1,172 @@
+
+
\ No newline at end of file
diff --git a/deployed/tflearn/libraries/techfry/forms/subform_filterarticles.xml b/deployed/tflearn/libraries/techfry/forms/subform_filterarticles.xml
new file mode 100644
index 00000000..0d86f065
--- /dev/null
+++ b/deployed/tflearn/libraries/techfry/forms/subform_filterarticles.xml
@@ -0,0 +1,34 @@
+
+
\ No newline at end of file
diff --git a/deployed/tflearn/libraries/techfry/forms/subform_filterusers.xml b/deployed/tflearn/libraries/techfry/forms/subform_filterusers.xml
new file mode 100644
index 00000000..e0032bcf
--- /dev/null
+++ b/deployed/tflearn/libraries/techfry/forms/subform_filterusers.xml
@@ -0,0 +1,35 @@
+
+
\ No newline at end of file
diff --git a/deployed/tflearn/libraries/techfry/forms/subform_where.xml b/deployed/tflearn/libraries/techfry/forms/subform_where.xml
new file mode 100644
index 00000000..ec6f520b
--- /dev/null
+++ b/deployed/tflearn/libraries/techfry/forms/subform_where.xml
@@ -0,0 +1,29 @@
+
+
\ No newline at end of file
diff --git a/deployed/tflearn/libraries/techfry/src/Controller/TfControllerAdmin.php b/deployed/tflearn/libraries/techfry/src/Controller/TfControllerAdmin.php
new file mode 100644
index 00000000..c9c43326
--- /dev/null
+++ b/deployed/tflearn/libraries/techfry/src/Controller/TfControllerAdmin.php
@@ -0,0 +1,46 @@
+checkToken();
+
+ $model = $this->getModel();
+
+ $model->deleteTable($model->table_name);
+
+ $this->setMessage('Table truncated successfully: ' . $model->table_name);
+
+ $this->setRedirect(Route::_('index.php?option=' . $this->option . '&view=' . $this->view_list, false));
+ }
+
+ // Empty table without checking existing records
+ public function truncateTable()
+ {
+ $this->checkToken();
+
+ $model = $this->getModel();
+
+ TfDb::truncate_table($model->table_name);
+
+ $this->setMessage('Table truncated successfully: ' . $model->table_name);
+
+ $this->setRedirect(Route::_('index.php?option=' . $this->option . '&view=' . $this->view_list, false));
+ }
+}
\ No newline at end of file
diff --git a/deployed/tflearn/libraries/techfry/src/Controller/TfControllerExport.php b/deployed/tflearn/libraries/techfry/src/Controller/TfControllerExport.php
new file mode 100644
index 00000000..47bf71ef
--- /dev/null
+++ b/deployed/tflearn/libraries/techfry/src/Controller/TfControllerExport.php
@@ -0,0 +1,212 @@
+option = $this->input->get('option');
+ }
+
+// *****************************************************************************
+
+ public function expo()
+ {
+ $model = $this->getModel();
+
+ if (!$model->pro())
+ {
+ $this->setMessage('Please upgrade to pro version to use this feature.', 'error');
+
+ $this->setRedirect(Route::_('index.php?option=' . $this->option . '&view=export', false));
+
+ return;
+ }
+
+ $info = $this->input->get('jform', array(), 'array');
+
+ $this->info = $this->input->get('jform', array(), 'array');
+
+ if (empty($info['export_select']))
+ {
+ $this->setMessage(Text::_('COM_TF_ERROR_SELECT_FIELDS'), 'error');
+
+ $this->setRedirect(Route::_('index.php?option=' . $this->option . '&view=export&type=' . $info['export_type'], false));
+
+ return;
+ }
+
+ if ($info['export_type'] == 'users')
+ {
+ $users = $this->filter_users();
+
+ if (!is_array($info['export_select']))
+ {
+ $info['export_select'] = explode(',', $info['export_select']);
+ }
+
+ $i = 0;
+ $j = 0;
+ $rows = array();
+
+ foreach ($users as $user_id)
+ {
+ $user = Factory::getUser($user_id);
+ $rows[$i] = array();
+ foreach ($info['export_select'] as $exportfield)
+ {
+ // Case 1: Field is group id
+ if ($exportfield == 'group_id')
+ {
+ $rows[$i][$j] = implode(',', $user->getAuthorisedGroups());
+ }
+
+ // Case 2: Field is Custom Field
+ elseif (is_numeric($exportfield))
+ {
+ $rows[$i][$j] = TfUser::get_custom_field($exportfield, $user_id);
+ }
+
+ // Case 3: Field is from users table
+ elseif ((is_numeric($exportfield) == false))
+ {
+ $rows[$i][$j] = $user->$exportfield;
+ }
+
+ $j++;
+ }
+ $i++;
+ }
+ }
+ else
+ {
+ // Conditions
+ $conditions = array();
+ foreach ($info['filter'] as $filter)
+ {
+ if ($filter['where_field'] != '' && $filter['where_value'] != '')
+ {
+ $conditions[] = array($filter['where_field'], $filter['where_operator'], $filter['where_value']);
+ }
+ elseif ($filter['where_field'] != '' && $filter['where_value'] == '')
+ {
+ $conditions[] = array($filter['where_field'], $filter['where_operator']);
+ }
+ }
+
+ $rows = TfDb::get_records($info['export_type'], $info['export_select'], $conditions, $info['order'], $info['limit']);
+
+ if ($info['export_type'] == 'joomla_content' && !empty($info['articles_cf']))
+ {
+ $rows = $this->add_article_fields($rows, $info['articles_cf']);
+ }
+ }
+
+ // Export data
+ $filename = $info['export_type'] . '.csv';
+
+ // Create a file pointer
+ $fp = fopen('php://output', 'w');
+
+ foreach ($rows as $row)
+ {
+ $row = (array) $row;
+
+ // Convert json to separate columns
+ if (!empty($info['jsons']))
+ {
+ $jsons = str_getcsv($info['jsons']);
+ foreach ($jsons as $json)
+ {
+ $arr = json_decode($row[$json], true);
+ foreach ($arr as $k => $v)
+ {
+ $row[$k] = $v;
+ }
+ unset($row[$json]);
+ }
+ }
+
+ fputcsv($fp, $row);
+ }
+
+ // Set headers to download file rather than display
+ header('Content-Type: text/csv');
+ header('Content-Disposition: attachment; filename="' . $filename . '";');
+
+ exit;
+ }
+
+ public function add_article_fields($rows, $fields)
+ {
+ BaseDatabaseModel::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_fields/models', 'FieldsModel');
+ $fieldModel = BaseDatabaseModel::getInstance('Field', 'FieldsModel', array('ignore_request' => true));
+
+ foreach ($rows as $i => $row)
+ {
+ foreach ($fields as $field)
+ {
+ // Case 1: Field is an image
+ if ($field == 'image_intro' || $field == 'image_fulltext')
+ {
+ $article = $this->getModel('export')->get_item('content', $row['id']);
+ $images = json_decode($article->images, true);
+ $rows[$i][$field] = $images[$field];
+ }
+ // Case 2: Combine intro text and fulltext
+ elseif ($field == 'full_article')
+ {
+ $article = $this->getModel('export')->get_item('content', $row['id']);
+ $rows[$i][$field] = $article->introtext . $article->fulltext;
+ }
+ // Case 3: Field is custom field
+ elseif (is_numeric($field))
+ {
+ $rows[$i][$field] = $fieldModel->getFieldValue($field, $row['id']);
+ }
+ }
+ }
+
+ return $rows;
+ }
+
+ public function filter_users()
+ {
+ $users = TfUser::filter_users($this->info['filter'], $this->info['filterusers']);
+
+ return $users;
+ }
+
+ public function cancel($key = null)
+ {
+ $this->checkToken();
+
+ $this->setRedirect(Route::_('index.php?option=' . $this->option . '&view=dashboard', false));
+
+ return true;
+ }
+}
\ No newline at end of file
diff --git a/deployed/tflearn/libraries/techfry/src/Controller/TfControllerForm.php b/deployed/tflearn/libraries/techfry/src/Controller/TfControllerForm.php
new file mode 100644
index 00000000..c4780627
--- /dev/null
+++ b/deployed/tflearn/libraries/techfry/src/Controller/TfControllerForm.php
@@ -0,0 +1,16 @@
+checkToken();
+
+ $model = $this->getModel();
+
+ // Get the data from the HTTP POST request
+ $data = $this->input->get('jform', array(), 'array');
+
+ $custom_message = (isset($data['custom_message']) && !empty($data['custom_message'])) ? $data['custom_message'] : Text::_('COM_TF_SUBMIT_SUCCESSFUL');
+
+ $custom_redirect = (isset($data['custom_redirect']) && !empty($data['custom_redirect'])) ? $data['custom_redirect'] : Uri::getInstance();
+
+ $context = $this->option . '.edit.' . $this->context;
+
+ // File Handling
+ if (!empty($this->file_fields))
+ {
+ $files = $this->input->files->get('jform');
+ foreach ($this->file_fields as $file_field)
+ {
+ if (!empty($files) && $files[$file_field]['size'] != 0)
+ {
+ $newfile = $this->save_file($files[$file_field]);
+ if ($newfile)
+ {
+ $data[$file_field] = $newfile;
+ }
+ else
+ {
+ // Save the data in the session
+ $this->app->setUserState($context . '.data', $data);
+
+ // Redirect back to the edit screen
+ $this->setRedirect(Uri::getInstance());
+
+ return false;
+ }
+ }
+ }
+ }
+
+ if (!$model->save($data))
+ {
+ // Save the data in the session
+ $this->app->setUserState($context . '.data', $data);
+
+ // Redirect back to the edit screen
+ $this->setRedirect($custom_redirect);
+
+ return false;
+ }
+
+ // Clear the data in the form
+ $this->app->setUserState($context . '.data', null);
+
+ // Post Save Method (Depreciated - Shift to Model)
+ $this->post_save($data);
+
+ $this->setRedirect($custom_redirect, $custom_message);
+
+ return true;
+ }
+
+ // Function called after saving data (Depreciated: Shift these to model save)
+ public function post_save($data)
+ {
+
+ }
+
+ // Save file to folder
+ protected function save_file($file)
+ {
+ $filename = File::makeSafe($file['name']);
+
+ $ext = File::getExt($filename);
+
+ // Check for file extension
+ if (!in_array(strtolower($ext), $this->allow_extensions))
+ {
+ $this->setMessage(Text::_('COM_TF_INVALID_FILE_EXTENSION'), 'warning');
+
+ return false;
+ }
+
+ // Check for file size
+ if ($file['size'] > $this->max_file_size)
+ {
+ $this->setMessage(Text::_('COM_TF_INVALID_FILE_SIZE'), 'warning');
+
+ return false;
+ }
+
+ $name = File::stripExt($filename);
+
+ $newfilename = $name . '_' . mt_rand(100,999) . '.' . $ext;
+
+ $src = $file['tmp_name'];
+ $folder = $this->save_folder . '/';
+ $dest = JPATH_SITE . '/images/' . $folder . $newfilename;
+
+ if (File::upload($src, $dest))
+ {
+ return $newfilename;
+ }
+ else
+ {
+ return false;
+ }
+ }
+}
\ No newline at end of file
diff --git a/deployed/tflearn/libraries/techfry/src/Controller/TfControllerImport.php b/deployed/tflearn/libraries/techfry/src/Controller/TfControllerImport.php
new file mode 100644
index 00000000..c0d175aa
--- /dev/null
+++ b/deployed/tflearn/libraries/techfry/src/Controller/TfControllerImport.php
@@ -0,0 +1,219 @@
+option = $this->input->get('option');
+ }
+
+ public function import()
+ {
+ $model = $this->getModel();
+
+ if (!$model->pro())
+ {
+ $this->setMessage('Please upgrade to pro version to use this feature.', 'error');
+
+ $this->setRedirect(Route::_('index.php?option=' . $this->option . '&view=import', false));
+
+ return;
+ }
+
+ $info = $this->input->get('jform', array(), 'array');
+
+ $files = $this->input->files->get('jform');
+ $file = $files['upload_file'];
+
+ $filename = File::makeSafe($file['name']);
+
+ $ext = strtolower(File::getExt($filename));
+ if ($ext !== 'csv')
+ {
+ $this->setMessage(Text::_('COM_TF_ERROR_INVALID_FILE'), 'error');
+
+ $this->setRedirect(Route::_('index.php?option=' . $this->option . '&view=import&type=' . $info['import_type'], false));
+
+ return;
+ }
+
+ if (empty($info['import_columns']))
+ {
+ $this->setMessage(Text::_('COM_TF_ERROR_SELECT_FIELDS'), 'error');
+
+ $this->setRedirect(Route::_('index.php?option=' . $this->option . '&view=import&type=' . $info['import_type'], false));
+
+ return;
+ }
+
+ $base = $this->base($info['import_type']);
+
+ $columns_arr = explode(',', $info['import_columns']);
+ if ($info['import_type'] == 'users' && !empty($info['users_cf']))
+ {
+ $columns_arr = array_merge($columns_arr, $info['users_cf']);
+ }
+
+ $model = $this->getModel('import');
+
+ $fileopen = fopen($file['tmp_name'], "r");
+ $counter = 0;
+ $c_exists = 0;
+
+ // Ignore first row of csv file
+ if ($info['ignore_first'])
+ {
+ fgetcsv($fileopen, 10000, ",");
+ }
+
+ while (($data = fgetcsv($fileopen, 10000, ",")) !== FALSE)
+ {
+ $record = $this->set_data($data, $columns_arr);
+
+ if ($info['import_type'] == 'users')
+ {
+ $user_exists = TfUser::find_user($record['email']);
+ if ($user_exists)
+ {
+ $c_exists++;
+ }
+ else
+ {
+ $user = TfUser::create_user($record);
+
+ if (!empty($info['users_cf']))
+ {
+ $fields = $info['users_cf'];
+ foreach ($fields as $field_id)
+ {
+ TfUser::save_custom_field($field_id, $user->id, $record[$field_id]);
+ }
+ }
+
+ $counter++;
+ }
+ }
+ elseif ($info['import_type'] == 'joomla_content')
+ {
+ $article = TfArticle::create_article($record);
+
+ if (!empty($info['articles_cf']))
+ {
+ $fields = $info['articles_cf'];
+ foreach ($fields as $field_id)
+ {
+ // TO DO: Get $alias from title
+ $article_id = TfArticle::find_article($alias, $record['catid']);
+
+ TfArticle::save_custom_field($field_id, $article_id, $record[$field_id]);
+ }
+ }
+
+ $counter++;
+ }
+ else
+ {
+ $record = $this->set_columns($record, $base['table']);
+
+ $result = $model->direct_save($record, $base['table'], true);
+
+ $result ? $counter++ : $c_exists++;
+ }
+ }
+
+ fclose($fileopen);
+
+ $this->setMessage($counter . ' ' . Text::_('COM_TF_RECORDS_IMPORTED') . ' ' . $c_exists . ' ' . Text::_('COM_TF_RECORDS_EXISTS'));
+
+ $this->setRedirect(Route::_('index.php?option=' . $this->option . '&view=import&type=' . $info['import_type'], false));
+ }
+
+ // 02. Returns record array to save in database
+ public function set_data($data, $columns)
+ {
+ $record = array();
+
+ $c = 0; // Column number
+ foreach ($columns as $column)
+ {
+ $record[$column] = $data[$c];
+ $c++;
+ }
+
+ return $record;
+ }
+
+ // 03. Function to determine which table is used
+ public function base($import_type)
+ {
+ $arr = array();
+
+ $model = $this->getModel('import');
+
+ $import_tables = $model->import_tables;
+
+ foreach ($import_tables as $type => $table)
+ {
+ if ($import_type == $type)
+ {
+ $arr['table'] = $table;
+ }
+ }
+
+ return $arr;
+ }
+
+ // 04. Add fields that should be handled automatically
+ public function set_columns($record, $table)
+ {
+ $record['id'] = 0;
+
+ $auto_fields = array('alias', 'created', 'modified', 'created_by');
+
+ $db = Factory::getDbo();
+ $cols = $db->getTableColumns('#__' . $table);
+
+ foreach ($auto_fields as $field)
+ {
+ if (array_key_exists($field, $cols) && !isset($record[$field]))
+ {
+ $record[$field] = '';
+ }
+ }
+
+ return $record;
+ }
+
+ public function cancel($key = null)
+ {
+ $this->checkToken();
+
+ $this->setRedirect(Route::_('index.php?option=' . $this->option . '&view=dashboard', false));
+
+ return true;
+ }
+}
\ No newline at end of file
diff --git a/deployed/tflearn/libraries/techfry/src/Controller/TfControllerQuery.php b/deployed/tflearn/libraries/techfry/src/Controller/TfControllerQuery.php
new file mode 100644
index 00000000..8d0e6865
--- /dev/null
+++ b/deployed/tflearn/libraries/techfry/src/Controller/TfControllerQuery.php
@@ -0,0 +1,430 @@
+option = $this->input->get('option');
+ }
+
+// *****************************************************************************
+
+ public function get_form_info()
+ {
+ $this->info = $this->input->get('jform', array(), 'array');
+ }
+
+ public function process()
+ {
+ $model = $this->getModel();
+
+ if (!$model->pro())
+ {
+ $this->setMessage('Please upgrade to pro version to use this feature.', 'error');
+
+ $this->setRedirect(Route::_('index.php?option=' . $this->option . '&view=query', false));
+
+ return;
+ }
+
+ $info = $this->input->get('jform', array(), 'array');
+ $this->get_form_info();
+
+ $this->query_type = $info['query_type'];
+ if ($this->query_type == 'users')
+ {
+ $this->filter_users();
+ }
+ elseif ($this->query_type == 'content')
+ {
+ $this->articles = TfArticle::filter_articles($info['filter'], $info['filterarticles']);
+ }
+
+ $this->db_table = '#__' . $info['query_type'];
+ $this->db_table_wo_prefix = $info['query_type'];
+ $this->column = $info['column_field'];
+ $this->column_save = ($info['column_save'] != '') ? $info['column_save'] : $info['column_field'];
+ $this->text = $info['text'];
+ $this->value = $info['value'];
+
+ if ($info['tool'] == 'string')
+ {
+ $this->function_name = $info['str_function'];
+ }
+ elseif ($info['tool'] == 'date')
+ {
+ $this->function_name = $info['date_function'];
+ }
+ elseif ($info['tool'] == 'numeric')
+ {
+ $this->function_name = $info['num_function'];
+ }
+
+ // Conditions
+ if (!empty($info['filter']))
+ {
+ foreach ($info['filter'] as $filter)
+ {
+ if ($filter['where_field'] != '' && $filter['where_value'] != '')
+ {
+ // $this->conditions[] = $filter['where_field'] . ' ' . $filter['where_operator'] . ' ' . $filter['where_value'];
+ $this->conditions[] = array($filter['where_field'], $filter['where_operator'], $filter['where_value']);
+ }
+ elseif ($filter['where_field'] != '' && $filter['where_value'] == '')
+ {
+ $this->conditions[] = $filter['where_field'] . ' ' . $filter['where_operator'];
+ }
+ }
+ }
+
+ $function_name = $info['tool'] . '_tool';
+
+ $message = $this->$function_name();
+ if (is_array($message))
+ {
+ $message = '' . print_r($message, true) . ' ';
+ }
+
+ if ($this->num_rows != '')
+ {
+ $this->app->enqueueMessage('Affected Rows: ' . $this->num_rows . ' ');
+ }
+
+ $this->setMessage($message);
+
+ $query_type = !empty($info['query_type']) ? '&type=' . $info['query_type'] : '';
+ $this->setRedirect(Route::_('index.php?option=' . $this->option . '&view=query' . $query_type, false));
+ }
+
+ // 01. Find text in table column; Return ids
+ public function find_tool()
+ {
+ $like = '%' . $this->text . '%';
+ $order = $this->info['order_col'] . ' ' . $this->info['order_dirn'];
+
+ $conditions = array(
+ array($this->column, 'LIKE', $like)
+ );
+
+ $result = TfDb::get_items($this->db_table_wo_prefix, $conditions, $order, $this->info['limit'], 'id');
+
+ return $result;
+ }
+
+ // 02. Find duplicates by column
+ public function find_duplicates_tool()
+ {
+ $db = Factory::getDbo();
+ $query = $db->getQuery(true);
+
+ $query
+ ->select(array($this->column, 'COUNT(*) AS c'))
+ ->from($db->quoteName($this->db_table))
+ ->group($db->quoteName($this->column))
+ ->having('c > 1');
+
+ $db->setQuery($query);
+
+ $db->execute();
+
+ $this->num_rows = $db->getNumRows();
+
+ $result = $db->loadAssocList();
+
+ return $result;
+ }
+
+ // 03. Update text with value in table column
+ public function update_tool()
+ {
+ if ($this->query_type == 'users')
+ {
+ foreach ($this->users as $user_id)
+ {
+ // Case 1: Update Users Custom Fields
+ if (is_numeric($this->column))
+ {
+ TfUser::save_custom_field($this->column, $user_id, $this->value);
+ }
+ // Case 2: Update Joomla Users Table
+ else
+ {
+ $action_field = $this->column;
+ $userdata = array('id' => $user_id, $action_field => $this->value);
+ $updates = array($action_field);
+ TfUser::update_user($userdata, $updates);
+ }
+ }
+
+ $this->num_rows = count($this->users);
+ }
+ elseif ($this->query_type == 'content')
+ {
+ foreach ($this->articles as $article_id)
+ {
+ // Case 1: Update Content Custom Fields
+ if (is_numeric($this->column))
+ {
+ TfArticle::save_custom_field($this->column, $article_id, $this->value);
+ }
+ // Case 2: Update Joomla Content Table
+ else
+ {
+ $action_field = $this->column;
+ $articledata = array('id' => $article_id, $action_field => $this->value);
+ TfArticle::update_article($articledata);
+ }
+ }
+ }
+ else
+ {
+ $sets = array($this->column => $this->value);
+
+ $this->num_rows = TfDb::update_records($this->db_table_wo_prefix, $this->conditions, $sets);
+ }
+ }
+
+ // 04. Replace text with value
+ public function replace_tool()
+ {
+ // Use TfDb class
+
+ $db = Factory::getDbo();
+ $query = $db->getQuery(true);
+
+ $query->update($db->quoteName($this->db_table));
+
+ $fields = array($db->quoteName($this->column) . ' = REPLACE(' . $db->quoteName($this->column) . ',' . $db->quote($this->text) . ',' . $db->quote($this->value) . ')');
+
+ $query->set($fields);
+
+ if (!empty($this->conditions))
+ {
+ $query->where($this->conditions);
+ }
+
+ $db->setQuery($query);
+
+ $db->execute();
+
+ $this->num_rows = $db->getAffectedRows();
+ }
+
+ // 05. Delete rows
+ public function delete_tool()
+ {
+ if (!empty($this->conditions))
+ {
+ $this->num_rows = TfDb::delete_items($this->db_table_wo_prefix, $this->conditions);
+ }
+ }
+
+ // 06. Truncate table
+ public function truncate_tool()
+ {
+ TfDb::truncate_table($this->db_table_wo_prefix);
+
+ return 'Database table ' . $this->db_table_wo_prefix . ' truncated.';
+ }
+
+ // 07. Get columns in a table
+ public function table_columns_tool()
+ {
+ $cols = TfDb::get_table_columns($this->db_table_wo_prefix);
+
+ return $cols;
+ }
+
+ // 08. Get create statement for a table
+ public function table_create_tool()
+ {
+ $db = Factory::getDbo();
+
+ $cols = $db->getTableCreate($this->db_table);
+
+ return $cols;
+ }
+
+ // 09. Get list of all database tables
+ public function table_list_tool()
+ {
+ $db = Factory::getDbo();
+
+ $tables = $db->getTableList();
+
+ return $tables;
+ }
+
+ // 10. String function
+ public function string_tool()
+ {
+ $this->get_rows();
+
+ $column_name = $this->info['column_field'];
+ $column_save = $this->column_save;
+
+ if ($this->function_name == 'preg_replace')
+ {
+ $this->info['p1'] = '/' . $this->info['p1'] . '/i';
+ }
+
+ $params = array($this->info['p1'], $this->info['p2']);
+
+ foreach ($this->rows as $row)
+ {
+ $row->$column_save = TfString::process($this->function_name, $row->$column_name, $params);
+
+ TfDb::insert_update($this->db_table_wo_prefix, $row);
+ }
+ }
+
+ // 11. Date function
+ public function date_tool()
+ {
+ $this->get_rows();
+
+ $column_name = $this->info['column_field'];
+ $column_save = $this->column_save;
+
+ foreach ($this->rows as $row)
+ {
+ $row->$column_save = TfDate::process($this->function_name, $row->$column_name, $this->info['p1']);
+
+ TfDb::insert_update($this->db_table_wo_prefix, $row);
+ }
+ }
+
+ // 12. Numeric function
+ public function numeric_tool()
+ {
+ // $this->function_tool();
+
+ return 'Coming Soon!';
+ }
+
+ // Function tool
+ public function function_tool()
+ {
+ $model = $this->getModel();
+
+ $this->get_rows();
+
+ $function_name = $this->function_name;
+ $column_name = $this->info['column_field'];
+ $column_save = $this->column_save;
+
+ foreach ($this->rows as $row)
+ {
+ if ($this->info['p1'] == '' && $this->info['p2'] == '' && $this->info['p3'] == '')
+ {
+ $row->$column_save = $function_name($row->$column_name);
+ }
+ elseif ($this->info['p1'] != '' && $this->info['p2'] == '' && $this->info['p3'] == '')
+ {
+ $row->$column_save = $function_name($row->$column_name, $this->info['p1']);
+ }
+ elseif ($this->info['p1'] != '' && $this->info['p2'] != '' && $this->info['p3'] == '')
+ {
+ $row->$column_save = $function_name($row->$column_name, $this->info['p1'], $this->info['p2']);
+ }
+ elseif ($this->info['p1'] != '' && $this->info['p2'] != '' && $this->info['p3'] != '')
+ {
+ $row->$column_save = $function_name($row->$column_name, $this->info['p1'], $this->info['p2'], $this->info['p3']);
+ }
+
+ $model->direct_save($row, $this->db_table_wo_prefix);
+ }
+ }
+
+ public function get_rows()
+ {
+ $db = Factory::getDbo();
+ $query = $db->getQuery(true);
+
+ $query
+ ->select($db->quoteName(array('id', $this->column)))
+ ->from($db->quoteName($this->db_table))
+ ->order($this->info['order_col'] . ' ' . $this->info['order_dirn'])
+ ->setLimit($this->info['limit']);
+
+ if (!empty($this->conditions))
+ {
+ $query->where($this->conditions);
+ }
+
+ $db->setQuery($query);
+
+ $db->execute();
+
+ $this->num_rows = $db->getNumRows();
+
+ $this->rows = $db->loadObjectList();
+ }
+
+ public function filter_users()
+ {
+ $this->users = TfUser::filter_users($this->info['filter'], $this->info['filterusers']);
+ }
+
+ public function cancel($key = null)
+ {
+ $this->checkToken();
+
+ $this->setRedirect(Route::_('index.php?option=' . $this->option . '&view=dashboard', false));
+
+ return true;
+ }
+}
\ No newline at end of file
diff --git a/deployed/tflearn/libraries/techfry/src/Model/Back/TfModelDashboard.php b/deployed/tflearn/libraries/techfry/src/Model/Back/TfModelDashboard.php
new file mode 100644
index 00000000..89a7b1bc
--- /dev/null
+++ b/deployed/tflearn/libraries/techfry/src/Model/Back/TfModelDashboard.php
@@ -0,0 +1,98 @@
+getQuery(true);
+
+ $query->select('update_site_id')
+ ->from($db->qn('#__update_sites_extensions'))
+ ->where($db->qn('extension_id') . ' = '. $db->q($extension_id));
+
+ $db->setQuery($query);
+
+ $update_site = $db->loadResult();
+
+ return $update_site;
+ }
+
+ // Get current version of component installed
+ public function get_current_version($element = '')
+ {
+ if ($element == '')
+ {
+ $element = $this->option;
+ }
+
+ $ext = TfDb::get_item('extensions', $element, 'element');
+
+ $version = json_decode($ext->manifest_cache)->version;
+
+ return $version;
+ }
+
+ // Get new bersion of component
+ public function get_new_version()
+ {
+ $component = ComponentHelper::getComponent($this->option);
+
+ $update_site = $this->get_update_site_id($component->id);
+
+ $update = TfDb::get_item('update_sites', $update_site, 'update_site_id');
+
+ $dom = new \DOMDocument();
+ $dom->load($update->location);
+ $contents = $dom->getElementsByTagName('version');
+ foreach ($contents as $content)
+ {
+ $new_version = $content->nodeValue;
+ }
+
+ return $new_version;
+ }
+
+ public function get_new_library_version()
+ {
+ $library = LibraryHelper::getLibrary('techfry');
+
+ $update_site = $this->get_update_site_id($library->id);
+
+ $update = TfDb::get_item('update_sites', $update_site, 'update_site_id');
+
+ $dom = new \DOMDocument();
+ $dom->load($update->location);
+ $contents = $dom->getElementsByTagName('version');
+ foreach ($contents as $content)
+ {
+ $new_version = $content->nodeValue;
+ }
+
+ return $new_version;
+ }
+
+ // Placeholder function to be defined in component dashboard model class
+ public function getAlerts()
+ {
+ $alerts = array();
+
+ return $alerts;
+ }
+}
\ No newline at end of file
diff --git a/deployed/tflearn/libraries/techfry/src/Model/Back/TfModelForm.php b/deployed/tflearn/libraries/techfry/src/Model/Back/TfModelForm.php
new file mode 100644
index 00000000..3ac6ed43
--- /dev/null
+++ b/deployed/tflearn/libraries/techfry/src/Model/Back/TfModelForm.php
@@ -0,0 +1,402 @@
+table_name)
+ {
+ $this->table_columns = TfDb::get_table_columns($this->table_name);
+ }
+
+ $this->set_basic_fields();
+
+ $this->app = Factory::getApplication();
+
+ $this->input = $this->app->input;
+ }
+
+ public function getTable($name = '', $prefix = 'Table', $options = array())
+ {
+ if (empty($name))
+ {
+ if (empty($this->table))
+ {
+ $name = ucwords($this->getName());
+ }
+ else
+ {
+ $name = $this->table;
+ }
+ }
+
+ if ($table = $this->_createTable($name, $prefix, $options))
+ {
+ return $table;
+ }
+
+ throw new \Exception(Text::sprintf('JLIB_APPLICATION_ERROR_TABLE_NAME_NOT_SUPPORTED', $name), 0);
+ }
+
+ public function getForm($data = array(), $loadData = true)
+ {
+ // Get the form
+ $this->form = $this->loadForm($this->option . '.' . $this->getName(), $this->getName(), array('control' => 'jform', 'load_data' => $this->loadData));
+
+ if (empty($this->form))
+ {
+ return false;
+ }
+
+ $this->complete_form();
+
+ $this->bind_form();
+
+ return $this->form;
+ }
+
+ protected function loadFormData()
+ {
+ // Check the session for previously entered form data.
+ $app = Factory::getApplication();
+ $data = $app->getUserState($this->option . '.edit.' . $this->getName() . '.data', array());
+
+ if (empty($data))
+ {
+ $data = $this->getItem();
+ }
+
+ return $data;
+ }
+
+ public function complete_form()
+ {
+ foreach ($this->basic_fields as $field)
+ {
+ switch ($field)
+ {
+ case 'title' :
+ $fieldset = '';
+ $element = ' ';
+ break;
+
+ case 'alias' :
+ $fieldset = '';
+ $element = ' ';
+ break;
+
+ case 'description' :
+ $fieldset = 'description';
+ $element = ' ';
+ break;
+
+ case 'note' :
+ $fieldset = 'options';
+ $element = ' ';
+ break;
+
+ case 'published' :
+ $fieldset = 'options';
+ $element = ' ';
+ break;
+
+ case 'language' :
+ $fieldset = 'options';
+ $element = 'JALL ';
+ break;
+
+ case 'ordering' :
+ $fieldset = 'options';
+ $element = ' ';
+ break;
+
+ case 'id' :
+ $fieldset = 'details';
+ $element = ' ';
+ break;
+
+ case 'modified' :
+ $fieldset = 'details';
+ $element = ' ';
+ break;
+
+ case 'created_by' :
+ $fieldset = 'details';
+ $element = ' ';
+ break;
+
+ case 'hits' :
+ $fieldset = 'details';
+ $element = ' ';
+ break;
+ }
+
+ $this->set_field($element, $fieldset);
+ }
+ }
+
+ public function save($data)
+ {
+ if (!$this->pro() && isset($this->db_limit))
+ {
+ $total_rows = $this->total_rows($this->table_name);
+
+ if ($total_rows > $this->db_limit)
+ {
+ $msg = 'You have reached maximum limit of ' . $this->db_limit . ' items. Please upgrade to pro version.';
+
+ $this->setError($msg);
+
+ return;
+ }
+ }
+
+ $data = $this->prepare_data($data, $this->table_name, $this->date_fields, $this->subform_fields, $this->multiple_fields);
+
+ return parent::save($data);
+ }
+
+ public function validate($form, $data, $group = null)
+ {
+ return $data;
+ }
+
+ public function getItem($pk = null)
+ {
+ $item = parent::getItem($pk);
+
+ // Convert JSON string to array
+ foreach ($this->multiple_fields as $k => $v)
+ {
+ if ($item && property_exists($item, $v))
+ {
+ $registry = new Registry($item->$v);
+
+ $item->$v = $registry->toArray();
+ }
+ }
+
+ // Load associated content items
+ $assoc = Associations::isEnabled();
+ if ($assoc && $this->is_ml)
+ {
+ $item->associations = array();
+ if ($item->id != null)
+ {
+ $associations = Associations::getAssociations($this->option, '#__' . $this->table_name, $this->associationsContext, $item->id, 'id', 'alias', '');
+
+ foreach ($associations as $tag => $association)
+ {
+ $item->associations[$tag] = $association->id;
+ }
+ }
+ }
+
+ return $item;
+ }
+
+ protected function preprocessForm(Form $form, $data, $group = 'content')
+ {
+ $str = ucwords(substr($this->option, 6));
+
+ // Association content items
+ if (Associations::isEnabled() && $this->is_ml)
+ {
+ $languages = LanguageHelper::getContentLanguages(false, false, null, 'ordering', 'asc');
+
+ if (count($languages) > 1)
+ {
+ $addform = new \SimpleXMLElement('');
+ $fields = $addform->addChild('fields');
+ $fields->addAttribute('name', 'associations');
+ $fieldset = $fields->addChild('fieldset');
+ $fieldset->addAttribute('name', 'item_associations');
+ $fieldset->addAttribute('addfieldprefix', 'TechFry\Component\Tf' . $str . '\Administrator\Field');
+
+ foreach ($languages as $language)
+ {
+ $field = $fieldset->addChild('field');
+ $field->addAttribute('name', $language->lang_code);
+ $field->addAttribute('type', 'modal_' . $this->name);
+ $field->addAttribute('language', $language->lang_code);
+ $field->addAttribute('label', $language->title);
+ $field->addAttribute('translate_label', 'false');
+
+ $field->addAttribute('select', 'true');
+ // $field->addAttribute('new', 'true');
+ // $field->addAttribute('edit', 'true');
+ $field->addAttribute('clear', 'true');
+ // $field->addAttribute('propagate', 'true');
+ }
+
+ $form->load($addform, false);
+ }
+ }
+
+ parent::preprocessForm($form, $data);
+ }
+
+ // Add field to fieldset
+ public function set_field($element, $fieldset)
+ {
+ $xml = new \SimpleXMLElement($element);
+ $this->form->setField($xml, null, false, $fieldset);
+ }
+
+ // Add fields to fieldset
+ public function set_fields($elements, $fieldset)
+ {
+ foreach ($elements as $element)
+ {
+ $this->set_field($element, $fieldset);
+ }
+ }
+
+ // Add fieldset to the form
+ public function add_fieldset($name, $label = '', $description = '')
+ {
+ $element = '