_binary From 4266f60bb05d42142b517063da8d0cb34ff7b963 Mon Sep 17 00:00:00 2001
From: Harika Nukala <harika.nukala@sap.com>
Date: Thu, 27 Apr 2017 15:50:32 -0700
Subject: [PATCH] chatbot framework related files

---
 src/configs/Config.php                          |   2 +-
 src/controllers/AdminController.php             |   6 +-
 src/controllers/components/ChatbotComponent.php | 368 +++++++++++++++++++++
 src/controllers/components/SocialComponent.php  |  96 +++++-
 src/library/VersionFunctions.php                |  48 +++
 src/models/BotModel.php                         | 414 ++++++++++++++++++++++++
 src/views/elements/BotstoryElement.php          | 384 ++++++++++++++++++++++
 7 files changed, 1311 insertions(+), 7 deletions(-)
 create mode 100644 src/controllers/components/ChatbotComponent.php
 create mode 100644 src/models/BotModel.php
 create mode 100644 src/views/elements/BotstoryElement.php

diff --git a/src/configs/Config.php b/src/configs/Config.php
index d9feae8..858664c 100755
--- a/src/configs/Config.php
+++ b/src/configs/Config.php
@@ -112,7 +112,7 @@ function nsconddefine($constant, $value)
  * Version number for upgrade function
  * @var int
  */
-nsdefine('YIOOP_VERSION', 50);
+nsdefine('YIOOP_VERSION', 51);
 /**
  * Minimum Version fo Yioop for which keyword ad script
  * still works with this version
diff --git a/src/controllers/AdminController.php b/src/controllers/AdminController.php
index d1896df..644b2a0 100755
--- a/src/controllers/AdminController.php
+++ b/src/controllers/AdminController.php
@@ -76,7 +76,8 @@ class AdminController extends Controller implements CrawlConstants
         "social" => ["manageGroups", "groupFeeds", "mixCrawls", "wiki"],
         "advertisement" => ["manageCredits", "manageAdvertisements"],
         "system" => ["manageMachines", "manageLocales", "serverSettings",
-            "security", "appearance", "configure"]
+            "security", "appearance", "configure"],
+        "chatbot" => ["botStory"]
     ];
     /**
      * This is the main entry point for handling requests to administer the
@@ -386,7 +387,8 @@ class AdminController extends Controller implements CrawlConstants
             "social" => tl('admin_controller_social'),
             "crawl" => tl('admin_controller_crawl_settings'),
             "system" => tl('admin_controller_system_settings'),
-            "advertisement" => tl('admin_controller_advertisement')
+            "advertisement" => tl('admin_controller_advertisement'),
+            "chatbot" => tl('admin_controller_chatbot')
         ];
         if (isset($data["ACTIVITIES"])) {
             foreach (self::$component_activities as $component => $activities){
diff --git a/src/controllers/components/ChatbotComponent.php b/src/controllers/components/ChatbotComponent.php
new file mode 100644
index 0000000..29f6b5c
--- /dev/null
+++ b/src/controllers/components/ChatbotComponent.php
@@ -0,0 +1,368 @@
+<?php
+/**
+ * SeekQuarry/Yioop --
+ * Open Source Pure PHP Search Engine, Crawler, and Indexer
+ *
+ * Copyright (C) 2009 - 2017  Chris Pollett chris@pollett.org
+ *
+ * LICENSE:
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * END LICENSE
+ *
+ * @author Chris Pollett chris@pollett.org
+ * @license http://www.gnu.org/licenses/ GPL3
+ * @link http://www.seekquarry.com/
+ * @copyright 2009 - 2017
+ * @filesource
+ */
+namespace seekquarry\yioop\controllers\components;
+
+use seekquarry\yioop as B;
+use seekquarry\yioop\configs as C;
+use seekquarry\yioop\library as L;
+use seekquarry\yioop\library\PhraseParser;
+
+
+/**
+ * Provides activities to AdminController related to creating
+ * bot stories.
+ *
+ * @author Harika Nukala
+ */
+class ChatbotComponent extends Component
+{
+    public function botStory()
+    {
+        $parent = $this->parent;
+        $bot_model = $parent->model("bot");
+        $user_model = $parent->model("user");
+        $data["ELEMENT"] = "botstory";
+        $allowed_options = ['create_intent', 'create_entity',
+            'create_expressions'];
+        print_r($_REQUEST['option_type']);
+        if (isset($_REQUEST['option_type']) &&
+            in_array($_REQUEST['option_type'], $allowed_options)) {
+            $data['option_type'] = $_REQUEST['option_type'];
+        } else {
+            $data['option_type'] = 'create_intent';
+        }
+        if ($data['option_type'] == 'create_intent') {
+            $data['create_intent_active'] = "active";
+            $data['create_entity_active'] = "";
+            $data['create_expressions_active'] = "";
+            $data['SCRIPT'] .= "\nswitchTab('createintenttab',".
+                "'createentitytab','createexpressionstab')\n";
+        } else if ($data['option_type'] == 'create_entity') {
+            $data['create_entity_active'] = "active";
+            $data['create_intent_active'] = "";
+            $data['create_expressions_active'] = "";
+            $data['SCRIPT'] .= "\nswitchTab('createentitytab',".
+                "'createintenttab', 'createexpressionstab')\n";
+        } else {
+            $data['create_entity_active'] = "";
+            $data['create_intent_active'] = "";
+            $data['create_expressions_active'] = "active";
+            $data['SCRIPT'] .= "\nswitchTab('createexpressionstab',".
+                "'createintenttab', 'createentitytab');\n";
+        }
+
+        $data['MESSAGE'] = "";
+        $data['INTENT_LISTS']="";
+        $data["CURRENT_STORY"] = [
+            "INTENT_ID" => "","EXPRESSION"=>""];
+        $intent="";
+        $entity_name="";
+        $entity_value="";
+        $user_id = $_SESSION['USER_ID'];
+        $intents=$bot_model->getIntents($user_id);
+        foreach ($intents as $intent) {
+            $data['INTENT_LISTS'][$intent['INTENT_ID']]=$intent['INTENT'];
+        }
+        if (isset($_REQUEST['BOT_INTENT'])) {
+            $intent = $_REQUEST['BOT_INTENT'];
+        }
+        if (isset($_REQUEST['BOT_ENTITY_NAME'])) {
+            $entity_name = $_REQUEST['BOT_ENTITY_NAME'];
+        }
+        if (isset($_REQUEST['BOT_ENTITY_VALUE'])) {
+            $entity_value = $_REQUEST['BOT_ENTITY_VALUE'];
+        }
+        $data['INTENT_FORM_TYPE'] = "addintent";
+        $data["ENTITY_FORM_TYPE"] = "addentity";
+        $data["EXPRESSION_FORM_TYPE"] = "addnewexpression";
+        if (isset($_REQUEST['arg']))
+        {
+            switch ($_REQUEST['arg'])
+            {
+                case "addintent":
+                    if ($intent != "") {
+                           $bot_model->addIntent($intent);
+                    } else {
+                        $data['SCRIPT'] .= "doMessage('<h1 class=\"red\" >".
+                            tl('chatbot_component_intent_blank').
+                            "</h1>')";
+                    }
+                    break;
+                case "addentity":
+                    $data['option_type'] ="create_entity";
+                    if ($entity_name != "") {
+                        $bot_model->addEntity($entity_name);
+                    } else {
+                        $data['SCRIPT'] .= "doMessage('<h1 class=\"red\" >".
+                            tl('chatbot_component_entity_blank').
+                            "</h1>')";
+                    }
+                    break;
+                case "addnewexpression":
+                    $data['option_type'] ="create_expression";
+                    $to_clean = ["INTENT_ID", 'EXPRESSION'];
+                    $entities = $bot_model->getEntities($user_id);
+                    foreach ($entities as $entity) {
+                        $to_clean[] = $entity['ENTITY_ID'];
+                    }
+                    $must_have = $to_clean;
+                    foreach ($to_clean as $clean_me) {
+                        $r[$clean_me] = (isset($_REQUEST[$clean_me])) ?
+                            trim($parent->clean($_REQUEST[$clean_me],
+                                "string")) : "";
+                    }
+                    $change_exp=$r['EXPRESSION'];
+                    $phrase_string=$r['EXPRESSION'];
+                    foreach ($entities as $entity) {
+                        if($r[$entity['ENTITY_ID']]!="") {
+                            $change_exp = str_replace($r[$entity['ENTITY_ID']],
+                                '&'.$entity['ENTITY_NAME'], $change_exp);
+                            $phrase_string = str_replace(
+                                $r[$entity['ENTITY_ID']],'',$phrase_string);
+                        }
+                    }
+                    $bot_model->addExpression($change_exp, $r['INTENT_ID']);
+                    $expression_id = $bot_model->getExpressionId(
+                        $change_exp,$r['INTENT_ID']);
+                    foreach ($entities as $entity) {
+                        if($r[$entity['ENTITY_ID']]!="") {
+                            $bot_model->addEntityValue($expression_id,
+                                $r['INTENT_ID'], $entity['ENTITY_ID'],
+                                $r[$entity['ENTITY_ID']]);
+                        }
+                    }
+                    $stop_obj = PhraseParser::getTokenizer(C\DEFAULT_LOCALE);
+                    if ($stop_obj && method_exists($stop_obj,
+                            "stopwordsRemover")) {
+                        $phrase_string = $stop_obj->stopwordsRemover(
+                            $phrase_string);
+                    }
+                    $terms = PhraseParser::stemTerms($phrase_string,
+                        C\DEFAULT_LOCALE);
+                    foreach ($terms as $term) {
+                        $bot_model->addTermFrequency($term, $r['INTENT_ID']);
+                    }
+                    break;
+                case "editintent":
+                    $data['INTENT_FORM_TYPE'] = "editintent";
+                    $update=false;
+                    if(isset($_REQUEST['id'])){
+                        $data['id']=$_REQUEST['id'];
+                        $obj = $bot_model->getIntent($data['id']);
+                        $data['BOT_INTENT']=$obj['INTENT'];
+                        if(isset($_REQUEST['BOT_INTENT']))
+                            $update=true;
+                    }
+                    if($update){
+                        $obj['INTENT_ID']=$_REQUEST['id'];
+                        $obj['INTENT']=$intent;
+                        $bot_model->updateIntent($obj);
+                        return $parent->redirectWithMessage(
+                            tl('chatbot_component_intent_modified'));
+                    }
+                    break;
+                case "deleteintent":
+                    if (!isset($_REQUEST['id'])) {
+                        return $parent->redirectWithMessage(
+                            tl('chatbot_component_no_delete_intent'));
+                    }
+                    $intent_id = $_REQUEST['id'];
+                    $bot_model->deleteIntent($intent_id);
+                    return $parent->redirectWithMessage(
+                        tl('chatbot_component_intent_deleted'));
+                    break;
+                case "editentity":
+                    $data['ENTITY_FORM_TYPE'] = "editentity";
+                    $update=false;
+                    if(isset($_REQUEST['id'])){
+                        $data['id']=$_REQUEST['id'];
+                        $obj = $bot_model->getEntity($data['id']);
+                        $data['BOT_ENTITY_NAME']=$obj['ENTITY_NAME'];
+                        $search_array3[]=["ID, ENTITY_VALUE","","","ASC"];
+                        $parent->pagingLogic($data, $bot_model, "ENTITY_VALUES",
+                            C\DEFAULT_ADMIN_PAGING_NUM, $search_array3, "",
+                            ["ENTITY_VALUES",[$_REQUEST['id']]]);
+                        if(isset($_REQUEST['BOT_ENTITY_NAME']))
+                            $update=true;
+                    }
+                    if($update){
+                        $obj['ENTITY_ID']=$_REQUEST['id'];
+                        $obj['ENTITY_NAME']=$entity_name;
+                        $obj['ENTITY_VALUE']=$entity_value;
+                        $bot_model->updateEntity($obj);
+                        return $parent->redirectWithMessage(
+                            tl('chatbot_component_entity_modified'));
+                    }
+                    break;
+                case "deleteentity":
+                    if (!isset($_REQUEST['id'])) {
+                        return $parent->redirectWithMessage(
+                            tl('chabot_component_no_delete_entity'));
+                    }
+                    $entity_id = $_REQUEST['id'];
+                    $bot_model->deleteEntity($entity_id);
+                    return $parent->redirectWithMessage(
+                        tl('chatbot_component_entity_deleted'));
+                    break;
+                case "editexpression":
+                    $data['EXPRESSION_FORM_TYPE'] = "editexpression";
+                    $update=false;
+                    $obj="";
+                    $entity_matches=[];
+                    if(isset($_REQUEST['id'])){
+                        $data['id']=$_REQUEST['id'];
+                        $obj = $bot_model->getExpression($data['id']);
+                        foreach ($data['CURRENT_STORY'] as $field => $value) {
+                            $upper_field = strtoupper($field);
+                            if (isset($_REQUEST[$field])) {
+                                $obj[$upper_field] = $_REQUEST[$field];
+                                $data['CURRENT_STORY'][$field] =
+                                    $obj[$upper_field];
+                                $update = true;
+                            } else if (isset($obj[$upper_field])){
+                                $data['CURRENT_STORY'][$field] =
+                                    $obj[$upper_field];
+                            }
+                        }
+                        $intent_id=$obj['INTENT_ID'];
+                        $expressions = $bot_model->getExpressions($intent_id);
+                        $phrase_string = $obj['EXPRESSION'];
+                        $stop_obj = PhraseParser::getTokenizer(
+                            C\DEFAULT_LOCALE);
+                        if ($stop_obj && method_exists($stop_obj,
+                                "stopwordsRemover")) {
+                            $phrase_string = $stop_obj->stopwordsRemover(
+                                $phrase_string);
+                        }
+                        foreach ($expressions as $expression){
+                            $entity_names=[];
+                            $expression = $stop_obj->stopwordsRemover(
+                                $expression);
+                            if($phrase_string!== $expression) {
+                                if (preg_match_all('/\&\w+/', $expression,
+                                    $matches)) {
+                                    foreach ($matches[0] as $match){
+                                        $expression = str_replace($match,'(.*)'
+                                            ,$expression);
+                                        $match =str_replace('&', '',$match);
+                                        $entity_names[] =$match;
+//                                        var_dump($entity_names);
+                                    }
+                                }
+                                if (preg_match_all('/' . trim($expression) .
+                                    '/', $phrase_string, $matches,
+                                    PREG_SET_ORDER, 0)) {
+                                    $i=0;
+                                    foreach (array_slice($matches[0], 1)
+                                             as $match) {
+                                        $entity_id = $bot_model->getEntityId(
+                                            $entity_names[$i],$user_id);
+                                        $data[$entity_names[$i]]=$match;
+                                        $i++;
+                                    }
+                                }
+                            }
+                            if(sizeof($entity_matches)>0) break;
+                        }
+                    }
+                    if($update){
+                        $entities = $bot_model->getEntities($user_id);
+                        foreach ($entities as $entity) {
+                            $to_clean[] = $entity['ENTITY_ID'];
+                        }
+                        $must_have = $to_clean;
+                        foreach ($to_clean as $clean_me) {
+                            $r[$clean_me] = (isset($_REQUEST[$clean_me])) ?
+                                trim($parent->clean($_REQUEST[$clean_me],
+                                    "string")) : "";
+                        }
+                        $change_exp=$obj['EXPRESSION'];
+                        $phrase_string=$obj['EXPRESSION'];
+                        foreach ($entities as $entity) {
+                            if($r[$entity['ENTITY_ID']]!="") {
+                                $change_exp = str_replace(
+                                    $r[$entity['ENTITY_ID']],
+                                    '&'.$entity['ENTITY_NAME'], $change_exp);
+                                $phrase_string = str_replace(
+                                    $r[$entity['ENTITY_ID']],'',$phrase_string);
+                            }
+                        }
+                        $obj['EXPRESSION']=$change_exp;
+                        $bot_model->updateExpression($obj);
+                        $expression_id = $bot_model->getExpressionId(
+                            $change_exp,$r['INTENT_ID']);
+                        foreach ($entities as $entity) {
+                            if($r[$entity['ENTITY_ID']]!="") {
+                                $bot_model->addEntityValue(
+                                    $expression_id, $r['INTENT_ID'],
+                                    $entity['ENTITY_ID'],
+                                    $r[$entity['ENTITY_ID']]);
+                            }
+                        }
+                        return $parent->redirectWithMessage(
+                            tl('chatbot_component_expression_modified'));
+                    }
+                    break;
+                case "deleteexpression":
+                    if (!isset($_REQUEST['id'])) {
+                        return $parent->redirectWithMessage(
+                            tl('chatbot_component_no_delete_expression'));
+                    }
+                    $expression_id = $_REQUEST['id'];
+                    $bot_model->deleteExpression($expression_id);
+                    return $parent->redirectWithMessage(
+                        tl('chatbot_component_expression_deleted'));
+                    break;
+                case "deleteentityvalue":
+                    if (!isset($_REQUEST['id'])) {
+                        return $parent->redirectWithMessage(
+                            tl('chatbot_component_no_delete_entityvalue'));
+                    }
+                    $id = $_REQUEST['id'];
+                    $bot_model->deleteEntityValue($id);
+                    return $parent->redirectWithMessage(
+                        tl('chatbot_component_entityvalue_deleted'));
+                    break;
+            }
+        }
+                $search_array[]=["INTENT","","","ASC"];
+        $parent->pagingLogic($data, $bot_model, "INTENTS",
+            C\DEFAULT_ADMIN_PAGING_NUM, $search_array, "",["INTENTS",null]);
+        $search_array1[]=["ENTITY_ID,ENTITY_NAME","","","ASC"];
+        $parent->pagingLogic($data, $bot_model, "ENTITIES",
+            C\DEFAULT_ADMIN_PAGING_NUM, $search_array1, "",["ENTITIES",null]);
+        $search_array2[]=["EXPRESSION,INTENT","","","ASC"];
+        $parent->pagingLogic($data, $bot_model, "EXPRESSIONS",
+            C\DEFAULT_ADMIN_PAGING_NUM, $search_array2, "",
+            ["EXPRESSIONS",null]);
+        return $data;
+    }
+}
\ No newline at end of file
diff --git a/src/controllers/components/SocialComponent.php b/src/controllers/components/SocialComponent.php
index 40e14ed..26c96a7 100644
--- a/src/controllers/components/SocialComponent.php
+++ b/src/controllers/components/SocialComponent.php
@@ -38,7 +38,7 @@ use seekquarry\yioop\library\MailServer;
 use seekquarry\yioop\library\UrlParser;
 use seekquarry\yioop\library\WikiParser;
 use seekquarry\yioop\library\FetchUrl;
-
+use seekquarry\yioop\library\PhraseParser;
 /**
  * Provides activities to AdminController related to creating, updating
  * blogs (and blog entries), static web pages, and crawl mixes.
@@ -1258,12 +1258,16 @@ class SocialComponent extends Component implements CrawlConstants
                     $post_data = [];
                     $time = time();
                     for ($i = 0; $i < $num_bots; $i++) {
+                        $intent = $this->classifyIntent($post_followed,$bots_called[$i]['USER_ID']);
+                        $intent_name=$intent['INTENT'];
+                        $entities = $this->extractEntities($post_followed,$intent_name,$bots_called[$i]['USER_ID']);
                         $sites[$i][CrawlConstants::URL] =
                             $bots_called[$i]['CALLBACK_URL'];
-                        $post_data[$i] = "post=$post_followed&bot_token=" .
+                        $post_data[$i] = "a=$intent_name&post=$post_followed&bot_token=" .
                             hash("sha256", $bots_called[$i]['BOT_TOKEN'] .
-                            $time . $post_followed) . "*" . $time .
-                            "&bot_name=". $bots_called[$i]['USER_NAME'];
+                                $time . $post_followed) . "*" . $time .
+                            "&bot_name=". $bots_called[$i]['USER_NAME'].
+                            "&entities=".serialize($entities);
                     }
                     $outputs = [];
                     if (count($sites) > 0) {
@@ -4089,4 +4093,88 @@ EOD;
         }
         $data['SCRIPT'] .= ']; drawFragments();';
     }
+    /**
+     * Intent Classifier for a user's message
+     *
+     * @param $post , the message posted in the group thread
+     * @param $user_id, the bot user to whom the message is posted
+     */
+    public function classifyIntent($post,$user_id)
+    {
+        $phrase_string = $post;
+        $stop_obj = PhraseParser::getTokenizer(C\DEFAULT_LOCALE);
+        if ($stop_obj && method_exists($stop_obj, "stopwordsRemover")) {
+            $phrase_string = $stop_obj->stopwordsRemover($phrase_string);
+        }
+        $terms = PhraseParser::stemTerms($phrase_string,C\DEFAULT_LOCALE);
+        $parent = $this->parent;
+        $bot_model = $parent->model("bot");
+        $intents = $bot_model->getIntents($user_id);
+        $values = [];
+        foreach ($intents as $intent){
+            $values[$intent['INTENT_ID']] = $this->tfidf($terms,
+                $intent,$intents);
+        }
+        arsort($values);
+        foreach ($values as $key => $val){
+            return $bot_model->getIntent($key);
+        }
+    }
+
+    public function tfidf($terms,$intent,$intents){
+        $value=0.0;
+        foreach($terms as $term){
+            $idf = $this->idf($term,$intents);
+            $value=$value+($this->tf($term,$intent['INTENT_ID'])*$idf);
+        }
+        return $value;
+    }
+
+    public function idf($term,$intents){
+        $parent = $this->parent;
+        $bot_model = $parent->model("bot");
+        $total=count($intents);
+        $intent_ids=[];
+        foreach($intents as $intent){
+            $intent_ids[]=$intent['INTENT_ID'];
+        }
+        $intentsWithTerm = $bot_model->getIntentsWithTerm($term,$intent_ids);
+        $idf = 1 + log(($total) / ( 1 + $intentsWithTerm ));
+        return $idf;
+    }
+
+    public function tf($term,$intent){
+        $parent = $this->parent;
+        $bot_model = $parent->model("bot");
+        $termFrequency = $bot_model->getTermFrequency($term,$intent);
+        return $termFrequency ? $termFrequency : 0;
+    }
+
+    public function extractEntities($post_followed,$intent_name,$user_id){
+        $entities=[];
+        $parent = $this->parent;
+        $bot_model = $parent->model("bot");
+        $intent_id = $bot_model->getIntentId($intent_name,$user_id);
+        $expressions = $bot_model->getExpressions($intent_id);
+        $phrase_string = $post_followed;
+        $stop_obj = PhraseParser::getTokenizer(C\DEFAULT_LOCALE);
+        if ($stop_obj && method_exists($stop_obj, "stopwordsRemover")) {
+            $phrase_string = $stop_obj->stopwordsRemover($phrase_string);
+        }
+        foreach ($expressions as $expression){
+            if (preg_match_all('/\&\w+/', $expression, $matches)) {
+                foreach ($matches[0] as $match){
+                    $expression = str_replace($match,'(.*)',$expression);
+                }
+            }
+            $expression = $stop_obj->stopwordsRemover($expression);
+            if (preg_match_all('/' . trim($expression) . '/', $phrase_string,
+                $matches, PREG_SET_ORDER, 0)) {
+                foreach (array_slice($matches[0], 1) as $match) {
+                    $entities[] = $match;
+                }
+            }
+        }
+        return $entities;
+    }
 }
diff --git a/src/library/VersionFunctions.php b/src/library/VersionFunctions.php
index dce2a3f..8c1bb7f 100644
--- a/src/library/VersionFunctions.php
+++ b/src/library/VersionFunctions.php
@@ -1392,3 +1392,51 @@ function upgradeDatabaseVersion50(&$db)
         SELECT GROUP_ID, GROUP_NAME, CREATED_TIME, OWNER_ID, REGISTER_TYPE,
         MEMBER_ACCESS, VOTE_ACCESS, POST_LIFETIME FROM GROUPS_OLD");
 }
+/**
+ * Upgrades a Version 50 version of the Yioop! database to a Version 51 version
+ * @param object $db datasource to use to upgrade.
+ */
+function upgradeDatabaseVersion51(&$db){
+    $role_model = new M\RoleModel(C\DB_NAME, false);
+    $role_model->db = $db;
+    $dbinfo = ["DBMS" => C\DBMS, "DB_HOST" => C\DB_HOST,
+        "DB_NAME" => C\DB_NAME, "DB_PASSWORD" => C\DB_PASSWORD];
+    $auto_increment = $db->autoIncrement($dbinfo);
+    $serial = $db->serialType($dbinfo);
+    $sql = "SELECT ACTIVITY_ID FROM ACTIVITY ".
+        "WHERE METHOD_NAME = 'botStory'";
+    $result = $db->execute($sql, []);
+    if ($result) {
+        $row = $db->fetchArray($result);
+        if  ($row) { //activity already exists
+            return;
+        }
+    }
+    addActivityAtId($db, 'db_activity_botstory',
+        "botStory", 21);
+    updateTranslationForStringId($db, 'db_activity_botstory',
+        'en-US', 'Bot Story');
+    $role_id = $role_model->getRoleId('Bot User');
+    $role_model->addActivityRole($role_id, 21);
+    $sql="CREATE TABLE INTENT(INTENT_ID INTEGER PRIMARY KEY $auto_increment,
+        INTENT VARCHAR(" . C\MAX_DESCRIPTION_LEN . "),USER_ID INTEGER)";
+    $db->execute($sql);
+    $db->execute("CREATE TABLE EXPRESSION(EXPRESSION_ID INTEGER
+          PRIMARY KEY $auto_increment,
+          EXPRESSION VARCHAR(" . C\MAX_DESCRIPTION_LEN ."),
+          INTENT_ID INTEGER)");
+    $db->execute("CREATE TABLE ENTITY(ENTITY_ID INTEGER
+        PRIMARY KEY $auto_increment,
+        ENTITY_NAME VARCHAR(" . C\MAX_DESCRIPTION_LEN ."),
+        USER_ID INTEGER)");
+    $db->execute("CREATE TABLE INTENT_EXPRESSION_ENTITY(ID INTEGER
+        PRIMARY KEY $auto_increment,
+        INTENT_ID INTEGER, EXPRESSION_ID INTEGER, ENTITY_ID INTEGER,
+        ENTITY_VALUE VARCHAR(" . C\MAX_DESCRIPTION_LEN ."),
+        PRIMARY KEY(INTENT_ID,EXPRESSION_ID,ENTITY_ID))");
+//    $db->execute("CREATE TABLE BOTUSER_STORY(USER_ID INTEGER,
+//         STORY_ID INTEGER, PRIMARY KEY(USER_ID, STORY_ID))");
+    $db->execute("CREATE TABLE BOT_TERM_FREQUENCY(TERM VARCHAR
+        (" . C\MAX_DESCRIPTION_LEN . "), FREQUENCY INTEGER,
+         INTENT_ID INTEGER, PRIMARY KEY(TERM, INTENT_ID))");
+}
\ No newline at end of file
diff --git a/src/models/BotModel.php b/src/models/BotModel.php
new file mode 100644
index 0000000..f74e10b
--- /dev/null
+++ b/src/models/BotModel.php
@@ -0,0 +1,414 @@
+<?php
+/**
+ * SeekQuarry/Yioop --
+ * Open Source Pure PHP Search Engine, Crawler, and Indexer
+ *
+ * Copyright (C) 2009 - 2017  Chris Pollett chris@pollett.org
+ *
+ * LICENSE:
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * END LICENSE
+ *
+ * @author Chris Pollett chris@pollett.org
+ * @license http://www.gnu.org/licenses/ GPL3
+ * @link http://www.seekquarry.com/
+ * @copyright 2009 - 2017
+ * @filesource
+ */
+namespace seekquarry\yioop\models;
+
+use seekquarry\yioop\configs as C;
+use seekquarry\yioop\library as L;
+use seekquarry\yioop\library\Processors\ImageProcessor;
+
+/** For getLocaleTag*/
+require_once __DIR__.'/../library/LocaleFunctions.php';
+/**
+ * This class is used to handle
+ * database statements related to Bot User stories
+ *
+ * @author Harika Nukala
+ */
+class BotModel extends Model
+{
+    public function addIntent($intent)
+    {
+        $user_id=$_SESSION['USER_ID'];
+        $db = $this->db;
+        $intent_id=$this->getIntentId($intent,$user_id);
+        if(!$intent_id) {
+            $sql = "INSERT INTO INTENT(INTENT,USER_ID) VALUES (?,?)";
+            $result = $db->execute($sql, [$intent,$user_id]);
+        }
+    }
+
+    public function addExpression($expression,$intent_id)
+    {
+        $db = $this->db;
+        $sql = "INSERT INTO EXPRESSION(EXPRESSION,INTENT_ID) VALUES (?,?)";
+        $result = $db->execute($sql, [$expression,$intent_id]);
+    }
+
+    public function addEntityValue($expression_id,$intent_id,
+                                   $entity_id,$entity_value){
+        $db = $this->db;
+        $sql = "INSERT INTO INTENT_EXPRESSION_ENTITY(INTENT_ID,EXPRESSION_ID,
+                ENTITY_ID,ENTITY_VALUE) VALUES (?,?,?,?)";
+        $result = $db->execute($sql, [$intent_id,$expression_id,
+            $entity_id,$entity_value]);
+    }
+
+    public function addEntity($entity_name)
+    {
+        $user_id=$_SESSION['USER_ID'];
+        $db = $this->db;
+        $entity_id=$this->getEntityId($entity_name,$user_id);
+        if(!$entity_id)
+        {
+            $sql = "INSERT INTO ENTITY(ENTITY_NAME,USER_ID) VALUES (?,?)";
+            $result = $db->execute($sql, [$entity_name,$user_id]);
+        }
+    }
+
+    public function getIntent($intent_id)
+    {
+        $db = $this->db;
+        $sql = "SELECT * FROM INTENT WHERE INTENT_ID = (?)".
+            $db->limitOffset(1);
+        $result = $db->execute($sql, [$intent_id]);
+        if (!$result) {
+            return false;
+        }
+        $row = $db->fetchArray($result);
+        return $row;
+    }
+
+    public function getIntentId($intent,$user_id)
+    {
+        $db = $this->db;
+        $sql = "SELECT INTENT_ID FROM INTENT WHERE
+            LOWER(INTENT) = LOWER(?) AND USER_ID = (?)". $db->limitOffset(1);
+        $result = $db->execute($sql, [$intent,$user_id]);
+        if (!$result) {
+            return false;
+        }
+        $row = $db->fetchArray($result);
+        $intent_id = $row['INTENT_ID'];
+        return $intent_id;
+    }
+
+    public function getEntityId($entity_name,$user_id)
+    {
+        $db = $this->db;
+        $sql = "SELECT ENTITY_ID FROM ENTITY WHERE
+            LOWER(ENTITY_NAME) = LOWER (?) AND USER_ID = (?)".
+            $db->limitOffset(1);
+        $result = $db->execute($sql, [$entity_name,$user_id]);
+        if (!$result) {
+            return false;
+        }
+        $row = $db->fetchArray($result);
+        $entity_id = $row['ENTITY_ID'];
+        return $entity_id;
+    }
+
+    public function getExpressionId($expression,$intent_id)
+    {
+        $db = $this->db;
+        $sql = "SELECT EXPRESSION_ID FROM EXPRESSION WHERE EXPRESSION = (?)
+                AND INTENT_ID=(?)". $db->limitOffset(1);
+        $result = $db->execute($sql, [$expression,$intent_id]);
+        if (!$result) {
+            return false;
+        }
+        $row = $db->fetchArray($result);
+        return $row['EXPRESSION_ID'];
+    }
+
+    public function getEntity($entity_id)
+    {
+        $db = $this->db;
+        $sql = "SELECT * FROM ENTITY WHERE ENTITY_ID = (?)".
+            $db->limitOffset(1);
+        $result = $db->execute($sql, [$entity_id]);
+        if (!$result) {
+            return false;
+        }
+        $row = $db->fetchArray($result);
+        return $row;
+    }
+
+    public function getEntities($user_id)
+    {
+        $entities=[];
+        $db = $this->db;
+        $sql = "SELECT ENTITY_ID, ENTITY_NAME FROM ENTITY WHERE USER_ID = (?)";
+        $result = $db->execute($sql, [$user_id]);
+        if (!$result) {
+            return false;
+        }
+        while ($row = $db->fetchArray($result)) {
+            $entities[] = $row;
+        }
+        return $entities;
+    }
+
+    public function getExpression($expression_id)
+    {
+        $db = $this->db;
+        $sql = "SELECT * FROM EXPRESSION WHERE EXPRESSION_ID = (?)".
+            $db->limitOffset(1);
+        $result = $db->execute($sql, [$expression_id]);
+        if (!$result) {
+            return false;
+        }
+        $row = $db->fetchArray($result);
+        return $row;
+    }
+
+    public function getExpressions($intent_id)
+    {
+        $expressions=[];
+        $db = $this->db;
+        $sql = "SELECT EXPRESSION FROM EXPRESSION WHERE INTENT_ID = (?)";
+        $result = $db->execute($sql, [$intent_id]);
+        if (!$result) {
+            return false;
+        }
+        while ($row = $db->fetchArray($result)) {
+            $expressions[] = $row['EXPRESSION'];
+        }
+        return $expressions;
+    }
+
+    public function deleteIntent($intent_id)
+    {
+        $sql = "SELECT * FROM INTENT WHERE INTENT_ID='$intent_id'";
+        $result = $this->db->execute($sql);
+        if ($result) {
+            $sql = "DELETE FROM EXPRESSION WHERE INTENT_ID=?";
+            $this->db->execute($sql, [$intent_id]);
+        }
+        $sql = "DELETE FROM INTENT WHERE INTENT_ID=?";
+        $this->db->execute($sql, [$intent_id]);
+    }
+
+    public function updateIntent($obj)
+    {
+        $intent_id = $obj['INTENT_ID'];
+        $sql = "UPDATE INTENT SET ";
+        $comma ="";
+        $params = [];
+        foreach ($obj as $field => $value) {
+            $sql .= "$comma $field=? ";
+            $comma = ",";
+            $params[] = $value;
+        }
+        $sql .= " WHERE INTENT_ID=?";
+        $params[] = $intent_id;
+        $this->db->execute($sql, $params);
+    }
+
+    public function updateEntity($obj)
+    {
+        $db = $this->db;
+        $entity_id = $obj['ENTITY_ID'];
+        $sql = "UPDATE ENTITY SET ";
+        $comma ="";
+        $params = [];
+        foreach ($obj as $field => $value) {
+            $sql .= "$comma $field=? ";
+            $comma = ",";
+            $params[] = $value;
+        }
+        $sql .= " WHERE ENTITY_ID=?";
+        $params[] = $entity_id;
+        $db->execute($sql, $params);
+        if($obj['ENTITY_VALUE'] != ""){
+            $sql = "SELECT * FROM INTENT_EXPRESSION_ENTITY
+                    WHERE ENTITY_ID = (?)". $db->limitOffset(1);
+            $result = $db->execute($sql, [$entity_id]);
+            $row = $db->fetchArray($result);
+            $this->addEntityValue($row['EXPRESSION_ID'], $row['INTENT_ID']
+                                    , $entity_id , $obj['ENTITY_VALUE']);
+        }
+    }
+
+    public function deleteEntity($entity_id)
+    {
+        $sql = "DELETE FROM ENTITY WHERE ENTITY_ID=?";
+        $this->db->execute($sql, [$entity_id]);
+    }
+
+    public function updateExpression($obj)
+    {
+        $expression_id = $obj['EXPRESSION_ID'];
+        $sql = "UPDATE EXPRESSION SET ";
+        $comma ="";
+        $params = [];
+        foreach ($obj as $field => $value) {
+            $sql .= "$comma $field=? ";
+            $comma = ",";
+            $params[] = $value;
+        }
+        $sql .= " WHERE EXPRESSION_ID=?";
+        $params[] = $expression_id;
+        $this->db->execute($sql, $params);
+    }
+
+    public function deleteExpression($expression_id){
+        $sql = "DELETE FROM EXPRESSION WHERE EXPRESSION_ID=?";
+        $this->db->execute($sql, [$expression_id]);
+    }
+
+    public function selectCallback($args = null)
+    {
+        $select = "";
+        list($query, $conditions, ) = $args;
+        if ($query=="INTENTS") {
+            $select = "INTENT_ID,INTENT";
+        }
+        else if ($query=="ENTITIES") {
+            $select = "ENTITY_ID,ENTITY_NAME";
+        }
+        else if($query=="EXPRESSIONS"){
+            $select = "I.INTENT AS INTENT, E.EXPRESSION AS EXPRESSION,
+            E.EXPRESSION_ID AS EXPRESSION_ID";
+        }
+        else if ($query=="ENTITY_VALUES") {
+            $select = "ID, ENTITY_VALUE";
+        }
+        return $select;
+    }
+    /**
+     * {@inheritDoc}
+     *
+     * @param mixed $args any additional arguments which should be used to
+     *     determine these tables (in this case none)
+     */
+    public function fromCallback($args = null)
+    {
+        $from="";
+        list($query, $conditions, ) = $args;
+        if ($query=="INTENTS") {
+            $from = "INTENT";
+        }
+        else if ($query=="ENTITIES") {
+            $from = "ENTITY";
+        }
+        else if($query=="EXPRESSIONS") {
+            $from = "INTENT I, EXPRESSION E";
+        }
+        else if ($query=="ENTITY_VALUES") {
+            $from = "INTENT_EXPRESSION_ENTITY";
+        }
+            return $from;
+    }
+    /**
+     * Used to restrict getRows in which rows it returns. Rows in this
+     * case corresponding to Yioop groups. The restrictions added are to
+     * restrict to those group available to a given user_id and whether or
+     * not the user wants groups subscribed to, or groups that could be
+     * subscribed to
+     *
+     * @param array $args first two elements are the $user_id of the user
+     *     and the $browse flag which says whether or not user is browing
+     *     through all groups to which he could subscribe and read or
+     *     just those groups to which he is already subscribed.
+     * @return string a SQL WHERE clause suitable to perform the above
+     *     restrictions
+     */
+    public function whereCallback($args = null)
+    {
+        $where="";
+        list($query, $conditions, ) = $args;
+        if ($query=="INTENTS" || $query=="ENTITIES") {
+            $where = "USER_ID=". $_SESSION['USER_ID'];
+        }
+        else if($query=="EXPRESSIONS") {
+            $where = "I.INTENT_ID = E.INTENT_ID AND USER_ID="
+                .$_SESSION['USER_ID'];
+        }
+        else if ($query=="ENTITY_VALUES"&&$conditions[0]) {
+            $where = "ENTITY_ID =".$conditions[0];
+        }
+            return $where;
+    }
+
+    public function addTermFrequency($term,$intent)
+    {
+        $db = $this->db;
+        $sql = "SELECT FREQUENCY AS NUM FROM " .
+            "BOT_TERM_FREQUENCY BT WHERE BT.TERM = ? " .
+            "AND BT.INTENT_ID = ?";
+        $result = $db->execute($sql, [$term, $intent]);
+        $present = false;
+        $count = 0;
+        if ($result) {
+            while ($row = $db->fetchArray($result)) {
+                if ($row["NUM"] > 0) {
+                    $count = $row["NUM"];
+                    $present = true;
+                } else {
+                    $present = false;
+                }
+            }
+        }
+        if (!$present) {
+            $sql = "INSERT INTO BOT_TERM_FREQUENCY(TERM, FREQUENCY,
+                INTENT_ID) VALUES (?, ?, ?)";
+            $result = $db->execute($sql, [$term, $count + 1, $intent]);
+        } else {
+            $sql = "UPDATE BOT_TERM_FREQUENCY SET FREQUENCY = ?";
+            $sql .= " WHERE TERM = ? AND INTENT_ID = ?";
+            $this->db->execute($sql, [$count + 1, $term, $intent]);
+        }
+    }
+
+    public function getIntents($user_id){
+        $db = $this->db;
+        $intents = [];
+        $sql = "SELECT INTENT_ID,INTENT FROM INTENT WHERE USER_ID = (?) ";
+        $result = $db->execute($sql, [$user_id]);
+        while ($row = $db->fetchArray($result)){
+            $intents[] = $row;
+        }
+        return $intents;
+    }
+
+    public function getIntentsWithTerm($term,$intents){
+        $db = $this->db;
+        $sql = "SELECT COUNT(*) AS INTENT_COUNT FROM BOT_TERM_FREQUENCY
+                WHERE TERM = (?) AND INTENT_ID IN (?)";
+        $result = $db->execute($sql, [$term,$intents]);
+        $row = $db->fetchArray($result);
+        return $row['INTENT_COUNT'];
+    }
+
+    public function getTermFrequency($term,$intent){
+        $db = $this->db;
+        $sql = "SELECT FREQUENCY FROM BOT_TERM_FREQUENCY
+                WHERE TERM = ? AND INTENT_ID = (?) ";
+        $result = $db->execute($sql, [$term,$intent]);
+        $row = $db->fetchArray($result);
+        return $row['FREQUENCY'];
+    }
+
+    public function deleteEntityValue($id){
+        $sql = "DELETE FROM INTENT_EXPRESSION_ENTITY WHERE ID=?";
+        $this->db->execute($sql, [$id]);
+    }
+}
\ No newline at end of file
diff --git a/src/views/elements/BotstoryElement.php b/src/views/elements/BotstoryElement.php
new file mode 100644
index 0000000..b6866b6
--- /dev/null
+++ b/src/views/elements/BotstoryElement.php
@@ -0,0 +1,384 @@
+<?php
+/**
+ * SeekQuarry/Yioop --
+ * Open Source Pure PHP Search Engine, Crawler, and Indexer
+ *
+ * Copyright (C) 2009 - 2017  Chris Pollett chris@pollett.org
+ *
+ * LICENSE:
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * END LICENSE
+ *
+ * @author Chris Pollett chris@pollett.org
+ * @license http://www.gnu.org/licenses/ GPL3
+ * @link http://www.seekquarry.com/
+ * @copyright 2009 - 2017
+ * @filesource
+ */
+namespace seekquarry\yioop\views\elements;
+
+use seekquarry\yioop as B;
+use seekquarry\yioop\configs as C;
+
+/**
+ * Element responsible for displaying the bot story features
+ * that someone can create for their own bot.
+ *
+ * @author Harika Nukala
+ */
+class BotstoryElement extends Element
+{
+    public function render($data)
+    {
+        ?>
+        <div class="current-activity">
+                <ul class='tab-menu-list'>
+                    <li><a href="javascript:
+                switchTab('createintenttab', 'createentitytab', 'createexpressionstab');"
+                           id='createintenttabitem'
+                           class="<?= $data['create_intent_active'] ?>"><?=
+                            tl('botstory_element_create_intent')?></a></li>
+                    <li><a href="javascript:
+                switchTab('createentitytab', 'createintenttab','createexpressionstab');"
+                           id='createentitytabitem'
+                           class="<?= $data['create_entity_active'] ?>"><?=
+                            tl('botstory_element_create_entity')?></a></li>
+                    <li><a href="javascript:
+                switchTab('createexpressionstab', 'createintenttab','createentitytab');"
+                           id='createexpressionstabitem'
+                           class="<?= $data['create_expressions_active'] ?>"><?=
+                            tl('botstory_element_create_expressions')?></a></li>
+                </ul>
+                <div class='tab-menu-content'>
+                    <div id='createintenttab'>
+                        <?php
+                        $admin_url = htmlentities(B\controllerUrl('admin', true));
+                        $token_string = C\CSRF_TOKEN."=".$data[C\CSRF_TOKEN];
+                        $pre_base_url = $admin_url . $token_string;
+                        $base_url = $pre_base_url ."&amp;a=botStory&amp;option_type=".$data['option_type'];
+                        ?>
+                        <div>
+                            <?php if ($data["INTENT_FORM_TYPE"] == "editintent") {
+                                ?>
+                                <div class='float-opposite'><a href='<?= $base_url ?>'><?=
+                                        tl('botstory_element_addintent_form') ?></a></div>
+                                <h2><?= tl('botstory_element_edit_intent')?></h2>
+                                <?php
+                            }
+                            ?>
+                            </div>
+                        <form id="botIntentForm" method="post">
+                            <input type="hidden" name="c" value="admin" />
+                            <input type="hidden" id='option-type' name="option_type" value="<?=
+                            $data['option_type'] ?>" />
+                            <input type="hidden" name="<?= C\CSRF_TOKEN ?>" value="<?=
+                            $data[C\CSRF_TOKEN] ?>" />
+                            <input type="hidden" name="a" value="botStory" />
+                            <input type="hidden" name="arg" value="<?=
+                            $data['INTENT_FORM_TYPE']?>" />
+                            <?php
+                            if ($data['INTENT_FORM_TYPE'] == "editintent") {
+                            ?>
+                            <input type="hidden" name="id" value="<?= $data['id']?>" />
+                            <?php
+                            }
+                            ?>
+                            <div class="top-margin"><b><label for="intent"><?=
+                                        tl('botstory_element_intent')?></label></b>
+                                <input type="text" id="intent" class="wide-field"
+                                       name="BOT_INTENT" value="<?= $data['BOT_INTENT']  ?>" />
+                                <button id="bot-intent-save" class="button-box"
+                                        type="submit"
+                                ><?= tl('bot_intent_save') ?></button>
+                            </div>
+                            </form>
+                        <?php
+//                        $data['FORM_TYPE'] = "";
+//                        $data['TABLE_TITLE'] = tl('searchsources_element_media_sources');
+//                        $data['NO_FLOAT_TABLE'] = true;
+//                        $data['ACTIVITY'] = 'botStory';
+//                        $data['VIEW'] = $this->view;
+//                        $data['NO_SEARCH'] = true;
+//                        $paging_items = ['SUBstart_row', 'SUBend_row', 'SUBnum_show'];
+//                        $paging1 = "";
+//                        foreach ($paging_items as $item) {
+//                            if (isset($data[strtoupper($item)])) {
+//                                $paging1 .= "&amp;".$item."=".$data[strtoupper($item)];
+//                            }
+//                        }
+//                        $paging2 = "";
+//                        $paging_items = ['start_row', 'end_row', 'num_show'];
+//                        foreach ($paging_items as $item) {
+//                            if (isset($data[strtoupper($item)])) {
+//                                $paging2 .= "&amp;".$item."=".$data[strtoupper($item)];
+//                            }
+//                        }
+//                        $data['PAGING'] = $paging1;
+//                        $this->view->helper("pagingtable")->render($data);
+                        ?>
+                        <table class="search-sources-table">
+                            <tr><th><?= tl('botstory_element_intentname') ?></th>
+                                <th colspan="3"><?= tl('botstory_element_actions')?></th>
+                            </tr><?php
+                            foreach ($data['INTENTS'] as $intent) {
+                                ?>
+                                <tr>
+                                    <td><?= $intent['INTENT'] ?></td>
+                                    <td><a href="<?=$pre_base_url ."&amp;a=botStory&amp;option_type=".
+                                        $data['option_type'] ."&amp;arg=editintent&amp;id=".
+                                         $intent['INTENT_ID']?>"><?=
+                                            tl('botstory_element_editintent')
+                                            ?></a></td>
+                                    <td><a onclick='javascript:return confirm("<?=
+                                        tl('botstory_element_delete_operation') ?>");' href="<?=
+                                        $pre_base_url ."&amp;a=botStory&amp;option_type=" .$data['option_type']
+                                        ."&amp;arg=deleteintent&amp;id=".$intent['INTENT_ID']
+                                        ?>"><?= tl('botstory_element_deleteintent')
+                                            ?></a></td>
+                                </tr>
+                                <?php
+                            } ?>
+                        </table>
+                    </div>
+                    <div id='createentitytab'>
+                        <div>
+                            <?php if ($data["ENTITY_FORM_TYPE"] == "editentity") {
+                                ?>
+                                <div class='float-opposite'><a href='<?= $base_url ?>'><?=
+                                        tl('botstory_element_addentity_form') ?></a></div>
+                                <h2><?= tl('botstory_element_edit_entity')?></h2>
+                                <?php
+                            }
+                            ?>
+                        </div>
+                        <form id="createEntityForm" method="post">
+                            <input type="hidden" name="c" value="admin" />
+                            <input type="hidden" id='option-type' name="option_type" value="<?=
+                            $data['option_type'] ?>" />
+                            <input type="hidden" name="<?= C\CSRF_TOKEN ?>" value="<?=
+                            $data[C\CSRF_TOKEN] ?>" />
+                            <input type="hidden" name="a" value="botStory" />
+                            <input type="hidden" name="arg" value="<?=
+                            $data['ENTITY_FORM_TYPE']?>" />
+                            <?php
+                            if ($data['ENTITY_FORM_TYPE'] == "editentity") {
+                                ?>
+                                <input type="hidden" name="id" value="<?= $data['id']?>" />
+                                <?php
+                            }
+                            ?>
+                            <div class="top-margin">
+                                <table class="name-table">
+                                    <tr><th class="table-label"><label for="new_entity"><?=
+                                            tl('botstory_element_new_entity')?></label>:</th>
+                                        <th> <input type="text" id="entity-name" class="wide-field"
+                                                    name="BOT_ENTITY_NAME" value="<?= $data['BOT_ENTITY_NAME']  ?>" />
+                                            </th>
+                                        </tr>
+                                <?php
+                                if ($data['ENTITY_FORM_TYPE'] == "editentity") {
+                                    ?>
+                                   <tr><th class="table-label"><label for="new_entity_value"><?=
+                                           tl('botstory_element_new_entity_value')?></label>:</th>
+                                       <td><div class='light-gray-box'><table><?php
+                                        foreach ($data['ENTITY_VALUES'] as $entity) {
+                                            ?>
+                                            <tr>
+                                                <td><?= $entity['ENTITY_VALUE'] ?></td>
+                                                <td><a onclick='javascript:return confirm("<?=
+                                                    tl('botstory_element_delete_operation') ?>");' href="<?=
+                                                    $pre_base_url ."&amp;a=botStory&amp;option_type=create_entity"
+                                                    ."&amp;arg=deleteentityvalue&amp;id=".$entity['ID']
+                                                    ?>"><?= tl('botstory_element_deleteentityvalue')
+                                                        ?></a></td>
+                                            </tr>
+                                            <?php
+                                        } ?>
+                                        <tr><td><input type="text" id="entity-value"
+                                                       name="BOT_ENTITY_VALUE"
+                                                       value="<?= $data['BOT_ENTITY_VALUE']  ?>" /></td></tr>
+                                    </table>
+                                           </div>
+                                <?php
+                                }
+                                ?>
+                                <tr><td></td></td><td class="center"><button class="button-box" id="bot-entity-save" type="submit"><?php
+                                    e(tl('bot_entity_save'));
+                                    ?></button></td></tr>
+                                    </table>
+                            </div>
+                        </form>
+                        <?php
+//                        $data['SUBFORM_TYPE'] = "";
+//                        $data['TABLE_TITLE'] = tl('searchsources_element_subsearches');
+//                        $data['TARGET_FRAGMENT'] = "subsearch-head";
+//                        $data['NO_FLOAT_TABLE'] = true;
+//                        $data['ACTIVITY'] = 'botStory';
+//                        $data['VIEW'] = $this->view;
+//                        $data['VAR_PREFIX'] = "SUB";
+//                        $data['PAGING'] = $paging2;
+//                        $this->view->helper("pagingtable")->render($data);
+                        ?>
+                        <table class="search-sources-table">
+                            <tr><th><?= tl('botstory_element_entityname') ?></th>
+                                <th colspan="3"><?= tl('botstory_element_actions')?></th>
+                            </tr><?php
+                            foreach ($data['ENTITIES'] as $entity) {
+                                ?>
+                                <tr>
+                                    <td><?= $entity['ENTITY_NAME'] ?></td>
+                                    <td><a href="<?=$pre_base_url ."&amp;a=botStory&amp;option_type=create_entity"
+                                        ."&amp;arg=editentity&amp;id=".
+                                        $entity['ENTITY_ID']?>"><?=
+                                            tl('botstory_element_editentity')
+                                            ?></a></td>
+                                    <td><a onclick='javascript:return confirm("<?=
+                                        tl('botstory_element_delete_operation') ?>");' href="<?=
+                                        $pre_base_url ."&amp;a=botStory&amp;option_type=create_entity"
+                                        ."&amp;arg=deleteentity&amp;id=".$entity['ENTITY_ID']
+                                        ?>"><?= tl('botstory_element_deleteentity')
+                                            ?></a></td>
+                                </tr>
+                                <?php
+                            } ?>
+                        </table>
+
+                    </div>
+                    <div id='createexpressionstab'>
+                        <div>
+                            <?php if ($data["EXPRESSION_FORM_TYPE"] == "editexpression") {
+                                ?>
+                                <div class='float-opposite'><a href='<?= $base_url ?>'><?=
+                                        tl('botstory_element_addexpression_form') ?></a></div>
+                                <h2><?= tl('botstory_element_edit_expression')?></h2>
+                                <?php
+                            }
+                            ?>
+                        </div>
+                        <form id="expressionForm" method="post">
+                            <input type="hidden" name="c" value="admin" />
+                            <input type="hidden" id="option-type" name="option_type" value="<?=
+                            $data['option_type'] ?>" />
+                            <input type="hidden" name="<?= C\CSRF_TOKEN ?>" value="<?=
+                            $data[C\CSRF_TOKEN] ?>" />
+                            <input type="hidden" name="a" value="botStory" />
+                            <input type="hidden" name="arg" value="<?=
+                            $data['EXPRESSION_FORM_TYPE']?>" />
+                            <?php
+                            if ($data['EXPRESSION_FORM_TYPE'] == "editexpression") {
+                                ?>
+                                <input type="hidden" name="id" value="<?= $data['id']?>" />
+                                <?php
+                            }
+                            ?>
+                            <table class="name-table">
+                                <tr><td><label for="intent-select"><b><?=
+                                                tl('botstory_element_intentselect')?></b></label></td><td>
+                                        <?php
+                                        $this->view->helper("options")->render("intent-select",
+                                            "INTENT_ID", $data['INTENT_LISTS'],
+                                            $data['CURRENT_STORY']['INTENT_ID']); ?></td></tr>
+                                <tr><td><b><label for="create_expressions"><?=
+                                            tl('botstory_element_new_expressions')?></label></b></label></td><td>
+                                        <input type="text" id="expression" class="extra-wide-field"
+                                               name="EXPRESSION" value="<?= $data['CURRENT_STORY']['EXPRESSION']  ?>" />
+                                               </td></tr>
+                                <tr><td colspan="3"><b><label for="view_entities"><?=
+                                                "Bot User has following Entities:"?></label></b></label></td></tr>
+                                <?php
+                                foreach ($data['ENTITIES'] as $entity) {
+                                ?>
+                                <tr>
+                                    <td><input type="text" id="exp-entity-name" class="wide-field"
+                                                value="<?= $entity['ENTITY_NAME'] ?>"
+                                               style="background: none;border:none" disabled="disabled"/>
+                                        </td>
+                                    <td><input type="text" id="exp-entity-value" class="wide-field"
+                                               name="<?=$entity['ENTITY_ID']?>" value="<?= $data[$entity['ENTITY_NAME']] ?>"/>
+                                    </td>
+                                </tr>
+                                <?php
+                                } ?>
+                                <tr><td></td><td class="center"><button class="button-box" id="bot-expression-save"
+                                                                        type="submit"><?= tl('bot_expression_save')
+                                            ?></button></td></tr>
+                            </table>
+                        </form>
+                        <table class="search-sources-table">
+                            <tr><th><?= tl('botstory_element_expressionname') ?></th>
+                                <th><?= tl('botstory_element_intentname') ?></th>
+                                <th colspan="3"><?= tl('botstory_element_actions')?></th>
+                            </tr><?php
+                            foreach ($data['EXPRESSIONS'] as $expression) {
+                                ?>
+                                <tr>
+                                    <td><?= $expression['EXPRESSION'] ?></td>
+                                    <td><?= $expression['INTENT'] ?></td>
+                                    <td><a href="<?=$pre_base_url ."&amp;a=botStory&amp;option_type=create_expressions"
+                                        ."&amp;arg=editexpression&amp;id=".
+                                        $expression['EXPRESSION_ID']?>"><?=
+                                            tl('botstory_element_editexpression')
+                                            ?></a></td>
+                                    <td><a onclick='javascript:return confirm("<?=
+                                        tl('botstory_element_delete_operation') ?>");' href="<?=
+                                        $pre_base_url ."&amp;a=botStory&amp;option_type=create_expressions"
+                                        ."&amp;arg=deleteexpression&amp;id=".$expression['EXPRESSION_ID']
+                                        ?>"><?= tl('botstory_element_deleteexpression')
+                                            ?></a></td>
+                                </tr>
+                                <?php
+                            } ?>
+                        </table>
+                    </div>
+                </div>
+        </div>
+        <script type="text/javascript">
+            function switchTab(newtab, oldtab, oldtab2)
+            {
+                setDisplay(newtab, true);
+                setDisplay(oldtab, false);
+                setDisplay(oldtab2, false);
+                ntab = elt(newtab + "item");
+                if (ntab) {
+                    ntab.className = 'active';
+                }
+                otab = elt(oldtab + "item");
+                if (otab) {
+                    otab.className = '';
+                }
+                otab2 = elt(oldtab2 + "item");
+                if (otab2) {
+                    otab2.className = '';
+                }
+                ctype = elt('option-type');
+                if (ctype) {
+                    ctype.value = (newtab == 'createintenttab')
+                        ? 'create_intent' : ((newtab == 'createentitytab') ?
+                        'create_entity' : 'create_expressions' );
+                }
+                console.log(ctype)
+            }
+        </script>
+        <?php
+    }
+
+    public function renderStoryForms()
+    {
+        ?>
+
+        <?php
+    }
+}
\ No newline at end of file
-- 
2.10.1 (Apple Git-78)

