From b84a6b18556774b213a121047326e2af486dc182 Mon Sep 17 00:00:00 2001 From: Dmitriy Simushev Date: Tue, 8 Jul 2014 14:30:53 +0000 Subject: [PATCH] Make the first approach to a new installer --- src/mibew/.htaccess | 6 +- src/mibew/app.php | 5 +- src/mibew/install.php | 45 + src/mibew/install/dbinfo.php | 455 ----------- src/mibew/install/dbperform.php | 333 -------- src/mibew/install/index.php | 505 ------------ src/mibew/install/migrate.php | 68 -- .../DummyAuthenticationManager.php | 73 ++ .../Mibew/Controller/InstallController.php | 168 ++++ src/mibew/libs/classes/Mibew/Installer.php | 771 ++++++++++++++++++ .../Mibew/Routing/RouteCollectionLoader.php | 23 +- src/mibew/libs/common/constants.php | 2 +- src/mibew/libs/common/string.php | 25 + src/mibew/libs/database_schema.yml | 284 +++++++ src/mibew/libs/routing_install.yml | 9 + 15 files changed, 1407 insertions(+), 1365 deletions(-) create mode 100644 src/mibew/install.php delete mode 100644 src/mibew/install/dbinfo.php delete mode 100644 src/mibew/install/dbperform.php delete mode 100644 src/mibew/install/index.php delete mode 100644 src/mibew/install/migrate.php create mode 100644 src/mibew/libs/classes/Mibew/Authentication/DummyAuthenticationManager.php create mode 100644 src/mibew/libs/classes/Mibew/Controller/InstallController.php create mode 100644 src/mibew/libs/classes/Mibew/Installer.php create mode 100644 src/mibew/libs/database_schema.yml create mode 100644 src/mibew/libs/routing_install.yml diff --git a/src/mibew/.htaccess b/src/mibew/.htaccess index a37136a0..b773f43b 100644 --- a/src/mibew/.htaccess +++ b/src/mibew/.htaccess @@ -34,9 +34,13 @@ Options +FollowSymLinks RewriteEngine On + # Use separate front controller for the system installator + RewriteCond %{REQUEST_FILENAME} !-f + RewriteRule ^install(|/(.*))$ install.php [QSA,L] + # Alter only requests for files that do not exist RewriteCond %{REQUEST_FILENAME} !-f - # Rewrite all requests to front controller + # Rewrite all other requests to front controller RewriteRule ^(.*)$ app.php [QSA,L] diff --git a/src/mibew/app.php b/src/mibew/app.php index ce6f51ff..78927baa 100644 --- a/src/mibew/app.php +++ b/src/mibew/app.php @@ -27,7 +27,10 @@ use Symfony\Component\Config\FileLocator; $file_locator = new FileLocator(array(MIBEW_FS_ROOT)); $router = new Router(new RouteCollectionLoader($file_locator)); -$router->setOption('route_collection', RouteCollectionLoader::ROUTES_ALL); +$router->setOption( + 'route_collection', + RouteCollectionLoader::ROUTES_CORE | RouteCollectionLoader::ROUTES_PLUGINS +); $application = new Application($router, new AuthenticationManager()); diff --git a/src/mibew/install.php b/src/mibew/install.php new file mode 100644 index 00000000..99c1b0f9 --- /dev/null +++ b/src/mibew/install.php @@ -0,0 +1,45 @@ +setOption( + 'route_collection', + RouteCollectionLoader::ROUTES_CORE | RouteCollectionLoader::ROUTES_INSTALLATION +); + +$application = new Application($router, new DummyAuthenticationManager()); + +// Process request +$request = Request::createFromGlobals(); +$response = $application->handleRequest($request); + +// Send response to the user +$response->prepare($request); +$response->send(); diff --git a/src/mibew/install/dbinfo.php b/src/mibew/install/dbinfo.php deleted file mode 100644 index 1d8d7c2f..00000000 --- a/src/mibew/install/dbinfo.php +++ /dev/null @@ -1,455 +0,0 @@ - array( - "groupid" => "int NOT NULL auto_increment PRIMARY KEY", - "parent" => "int DEFAULT NULL", - "vcemail" => "varchar(64)", - "vclocalname" => "varchar(64) NOT NULL", - "vccommonname" => "varchar(64) NOT NULL", - "vclocaldescription" => "varchar(1024) NOT NULL", - "vccommondescription" => "varchar(1024) NOT NULL", - "iweight" => "int NOT NULL DEFAULT 0", - "vctitle" => "varchar(255) DEFAULT ''", - "vcchattitle" => "varchar(255) DEFAULT ''", - "vclogo" => "varchar(255) DEFAULT ''", - "vchosturl" => "varchar(255) DEFAULT ''", - ), - - // Chat threads - "${mysqlprefix}chatthread" => array( - // ID of the thread. - "threadid" => "int NOT NULL auto_increment PRIMARY KEY", - // Name of the user in chat. - "userName" => "varchar(64) NOT NULL", - // ID of the user. This field is foreign key for - // {chatsitevisitor}.userid - "userid" => "varchar(255)", - // Name of the operator who took place in the chat. - "agentName" => "varchar(64)", - // ID of the operator who took place in the chat. - "agentId" => "int NOT NULL DEFAULT 0", - // Unix timestamp of the moment when the thread was created. - "dtmcreated" => "int NOT NULL DEFAULT 0", - // Unix timestamp of the moment when chat actually started. - "dtmchatstarted" => "int NOT NULL DEFAULT 0", - // Unix timestamp of the last thread modification. - "dtmmodified" => "int NOT NULL DEFAULT 0", - // Unix timestamp of the moment when the thread was closed. - "dtmclosed" => "int NOT NULL DEFAULT 0", - // ID of the last thread revision. - "lrevision" => "int NOT NULL DEFAULT 0", - // State of the thread. It is one of Thread::STATE_* constants. - "istate" => "int NOT NULL DEFAULT 0", - // State of invitation related with the thread. It is one of - // Thread::INVITATION_* constants. - "invitationstate" => "int NOT NULL DEFAULT 0", - // Last token of the thread. - "ltoken" => "int NOT NULL", - // IP address of the user. - "remote" => "varchar(255)", - // Page from which chat thread was started. - "referer" => "text", - // ID of the operator who will next in the chat. - "nextagent" => "int NOT NULL DEFAULT 0", - // Code of chat locale. - "locale" => "varchar(8)", - // Unix timestamp of the last request from user's window to server. - "lastpinguser" => "int NOT NULL DEFAULT 0", - // Unix timestamp of the last request from operator's window to server. - "lastpingagent" => "int NOT NULL DEFAULT 0", - // Indicates if user typing or not. It can take two values 0 and 1. - "userTyping" => "int DEFAULT 0", - // Indicates if operator typing or not. It can take two values 0 and 1. - "agentTyping" => "int DEFAULT 0", - // ID of shown message in the chat. - "shownmessageid" => "int NOT NULL DEFAULT 0", - // User agent description that took from 'User-Agent' HTTP header. - "userAgent" => "varchar(255)", - // Total count of user's messages related with the thread. - "messageCount" => "varchar(16)", - // ID of the group at Mibew side related with the thread. - "groupid" => "int references ${mysqlprefix}chatgroup(groupid)", - ), - - "${mysqlprefix}chatthreadstatistics" => array( - "statid" => "int NOT NULL auto_increment PRIMARY KEY", - "date" => "int NOT NULL DEFAULT 0", - "threads" => "int NOT NULL DEFAULT 0", - "missedthreads" => "int NOT NULL DEFAULT 0", - "sentinvitations" => "int NOT NULL DEFAULT 0", - "acceptedinvitations" => "int NOT NULL DEFAULT 0", - "rejectedinvitations" => "int NOT NULL DEFAULT 0", - "ignoredinvitations" => "int NOT NULL DEFAULT 0", - "operatormessages" => "int NOT NULL DEFAULT 0", - "usermessages" => "int NOT NULL DEFAULT 0", - "averagewaitingtime" => "FLOAT(10, 1) NOT NULL DEFAULT 0", - "averagechattime" => "FLOAT(10, 1) NOT NULL DEFAULT 0" - ), - - "${mysqlprefix}requestbuffer" => array( - "requestid" => "int NOT NULL auto_increment PRIMARY KEY", - // Use MD5 hashes as keys - "requestkey" => "char(32) NOT NULL", - "request" => "text NOT NULL" - ), - - "${mysqlprefix}requestcallback" => array( - "callbackid" => "int NOT NULL auto_increment PRIMARY KEY", - "token" => "varchar(64) NOT NULL DEFAULT ''", - "function" => "varchar(64) NOT NULL", - "arguments" => "varchar(1024)" - ), - - // Contains updated translations - "${mysqlprefix}translation" => array( - "stringid" => "int NOT NULL auto_increment PRIMARY KEY", - "locale" => "varchar(5) NOT NULL", - "context" => "varchar(256) NOT NULL DEFAULT ''", - "source" => "text COLLATE utf8_bin", - "translation" => "text", - ), - - // Contains locales info - "${mysqlprefix}locale" => array( - // Artificial primary key - "localeid" => "int NOT NULL auto_increment PRIMARY KEY", - // Locale code - "code" => "varchar(5) NOT NULL", - // Indicates if a locale is enabled or not. - "enabled" => "tinyint NOT NULL DEFAULT 0", - ), - - // Contains localized mail templates - "${mysqlprefix}mailtemplate" => array( - // Artificial primary key - "templateid" => "int NOT NULL auto_increment PRIMARY KEY", - // Locale code a template belongs to - "locale" => "varchar(5) NOT NULL", - // Machine name of a template - "name" => "varchar(256) NOT NULL", - // Mail subject - "subject" => "varchar(1024) NOT NULL", - // Mail body - "body" => "text", - ), - - // Store chat thread messages - "${mysqlprefix}chatmessage" => array( - // Message ID. - "messageid" => "int NOT NULL auto_increment PRIMARY KEY", - // ID of the thread related with the message. - "threadid" => "int NOT NULL references ${mysqlprefix}chatthread(threadid)", - // Message kind. It is one of Thread::KIND_* constants. - "ikind" => "int NOT NULL", - // ID of operator who sent the message. This value will be ignored for - // system messages and messages which sent by users. - "agentId" => "int NOT NULL DEFAULT 0", - // Message text body. - "tmessage" => "text NOT NULL", - // Name of the plugin which sent the message. If message was not sent by - // a plugin this field equals to an empty string. - "plugin" => "varchar(256) NOT NULL DEFAULT ''", - // Arbitrary serialized data related with message. - "data" => "text", - // Unix timestamp when message was created. - "dtmcreated" => "int NOT NULL DEFAULT 0", - // Name of the message sender. - "tname" => "varchar(64)" - ), - - "${mysqlprefix}chatoperator" => array( - "operatorid" => "int NOT NULL auto_increment PRIMARY KEY", - "vclogin" => "varchar(64) NOT NULL", - "vcpassword" => "varchar(64) NOT NULL", - "vclocalename" => "varchar(64) NOT NULL", - "vccommonname" => "varchar(64) NOT NULL", - "vcemail" => "varchar(64)", - "dtmlastvisited" => "int NOT NULL DEFAULT 0", - "istatus" => "int DEFAULT 0", /* 0 - online, 1 - away */ - "idisabled" => "int DEFAULT 0", - "vcavatar" => "varchar(255)", - "vcjabbername" => "varchar(255)", - "iperm" => "int DEFAULT 0", /* Do not grant all privileges by default */ - "dtmrestore" => "int NOT NULL DEFAULT 0", - "vcrestoretoken" => "varchar(64)", - // Use to start chat with specified operator - "code" => "varchar(64) DEFAULT ''" - ), - - "${mysqlprefix}chatoperatorstatistics" => array( - "statid" => "int NOT NULL auto_increment PRIMARY KEY", - "date" => "int NOT NULL DEFAULT 0", - "operatorid" => "int NOT NULL", - "threads" => "int NOT NULL DEFAULT 0", - "messages" => "int NOT NULL DEFAULT 0", - "averagelength" => "FLOAT(10, 1) NOT NULL DEFAULT 0", - "sentinvitations" => "int NOT NULL DEFAULT 0", - "acceptedinvitations" => "int NOT NULL DEFAULT 0", - "rejectedinvitations" => "int NOT NULL DEFAULT 0", - "ignoredinvitations" => "int NOT NULL DEFAULT 0" - ), - - "${mysqlprefix}chatrevision" => array( - "id" => "INT NOT NULL" - ), - - "${mysqlprefix}chatgroupoperator" => array( - "groupid" => "int NOT NULL references ${mysqlprefix}chatgroup(groupid)", - "operatorid" => "int NOT NULL references ${mysqlprefix}chatoperator(operatorid)", - ), - - "${mysqlprefix}chatban" => array( - "banid" => "INT NOT NULL auto_increment PRIMARY KEY", - "dtmcreated" => "int NOT NULL DEFAULT 0", - "dtmtill" => "int NOT NULL DEFAULT 0", - "address" => "varchar(255)", - "comment" => "varchar(255)", - "blockedCount" => "int DEFAULT 0" - ), - - "${mysqlprefix}chatconfig" => array( - "id" => "INT NOT NULL auto_increment PRIMARY KEY", - "vckey" => "varchar(255)", - "vcvalue" => "varchar(255)", - ), - - "${mysqlprefix}chatresponses" => array( - "id" => "INT NOT NULL auto_increment PRIMARY KEY", - "locale" => "varchar(8)", - "groupid" => "int references ${mysqlprefix}chatgroup(groupid)", - "vctitle" => "varchar(100) NOT NULL DEFAULT ''", - "vcvalue" => "varchar(1024) NOT NULL", - ), - - "${mysqlprefix}chatsitevisitor" => array( - "visitorid" => "INT NOT NULL auto_increment PRIMARY KEY", - "userid" => "varchar(255) NOT NULL", - "username" => "varchar(64)", - "firsttime" => "int NOT NULL DEFAULT 0", - "lasttime" => "int NOT NULL DEFAULT 0", - "entry" => "text NOT NULL", - "details" => "text NOT NULL", - "invitations" => "INT NOT NULL DEFAULT 0", - "chats" => "INT NOT NULL DEFAULT 0", - "threadid" => "INT references ${mysqlprefix}chatthread(threadid) on delete set null" - ), - - "${mysqlprefix}visitedpage" => array( - "pageid" => "INT NOT NULL auto_increment PRIMARY KEY", - "address" => "varchar(1024)", - "visittime" => "int NOT NULL DEFAULT 0", - "visitorid" => "INT", - // Indicates if path included in 'by page' statistics - "calculated" => "tinyint NOT NULL DEFAULT 0" - ), - - "${mysqlprefix}visitedpagestatistics" => array( - "pageid" => "INT NOT NULL auto_increment PRIMARY KEY", - "date" => "int NOT NULL DEFAULT 0", - "address" => "varchar(1024)", - "visits" => "int NOT NULL DEFAULT 0", - "chats" => "int NOT NULL DEFAULT 0", - "sentinvitations" => "int NOT NULL DEFAULT 0", - "acceptedinvitations" => "int NOT NULL DEFAULT 0", - "rejectedinvitations" => "int NOT NULL DEFAULT 0", - "ignoredinvitations" => "int NOT NULL DEFAULT 0" - ), -); - -$dbtables_indexes = array( - "${mysqlprefix}chatgroup" => array( - "parent" => "parent" - ), - "${mysqlprefix}chatoperatorstatistics" => array( - "operatorid" => "operatorid" - ), - "${mysqlprefix}chatgroupoperator" => array( - "groupid" => "groupid", - "operatorid" => "operatorid" - ), - "${mysqlprefix}requestbuffer" => array( - "requestkey" => "requestkey" - ), - "${mysqlprefix}chatmessage" => array( - "idx_agentid" => "agentid" - ), - "${mysqlprefix}chatsitevisitor" => array( - "threadid" => "threadid" - ), - "${mysqlprefix}requestcallback" => array( - "token" => "token" - ), - "${mysqlprefix}visitedpage" => array( - "visitorid" => "visitorid" - ) -); - -$memtables = array(); - -$dbtables_can_update = array( - "${mysqlprefix}chatthread" => array("agentId", "userTyping", "agentTyping", "messageCount", "nextagent", "shownmessageid", "userid", "userAgent", "groupid", "dtmchatstarted", "dtmclosed", "invitationstate"), - "${mysqlprefix}chatthreadstatistics" => array("missedthreads", "sentinvitations", "acceptedinvitations", "rejectedinvitations", "ignoredinvitations"), - "${mysqlprefix}requestbuffer" => array("requestid", "requestkey", "request"), - "${mysqlprefix}chatmessage" => array("agentId", "plugin", "data"), - "${mysqlprefix}chatoperator" => array("vcavatar", "vcjabbername", "iperm", "istatus", "idisabled", "vcemail", "dtmrestore", "vcrestoretoken", "code"), - "${mysqlprefix}chatoperatorstatistics" => array("sentinvitations", "acceptedinvitations", "rejectedinvitations", "ignoredinvitations"), - "${mysqlprefix}chatban" => array(), - "${mysqlprefix}chatgroup" => array("vcemail", "iweight", "parent", "vctitle", "vcchattitle", "vclogo", "vchosturl"), - "${mysqlprefix}chatgroupoperator" => array(), - "${mysqlprefix}chatresponses" => array("vctitle"), - "${mysqlprefix}chatsitevisitor" => array(), - "${mysqlprefix}requestcallback" => array("callbackid", "token", "function", "arguments"), - "${mysqlprefix}visitedpage" => array(), - "${mysqlprefix}visitedpagestatistics" => array("sentinvitations", "acceptedinvitations", "rejectedinvitations", "ignoredinvitations"), -); - -function show_install_err($text) -{ - global $page; - $page = array( - 'version' => MIBEW_VERSION, - 'localeLinks' => get_locale_links(), - 'title' => getlocal("Problem"), - 'no_right_menu' => true, - 'fixedwrap' => true, - 'errors' => array($text), - ); - $page_style = new \Mibew\Style\PageStyle('default'); - start_html_output(); - echo($page_style->render('install_err', $page)); - exit; -} - -function create_table($id, $link) -{ - global $dbtables, $dbtables_indexes, $memtables, $mysqlprefix; - - if (!isset($dbtables[$id])) { - show_install_err("Unknown table: $id, " . mysql_error($link)); - } - - $query = - "CREATE TABLE $id\n" . - "(\n"; - foreach ($dbtables[$id] as $k => $v) { - $query .= " $k $v,\n"; - } - - if (isset($dbtables_indexes[$id])) { - foreach ($dbtables_indexes[$id] as $k => $v) { - $query .= " INDEX $k ($v),\n"; - } - } - - $query = preg_replace("/,\n$/", "", $query); - $query .= ") charset utf8"; - if (in_array($id, $memtables)) { - $query .= " ENGINE=MEMORY"; - } else { - $query .= " ENGINE=InnoDb"; - } - - mysql_query($query, $link) or show_install_err(' Query failed: ' . mysql_error($link)); - - if ($id == "${mysqlprefix}chatoperator") { - // Create First Administrator - // Grant all privileges by default only for First Administrator - mysql_query( - "INSERT INTO ${mysqlprefix}chatoperator ( " . - "vclogin, " . - "vcpassword, " . - "vclocalename, " . - "vccommonname, " . - "vcavatar, " . - "vcemail, " . - "iperm " . - ") values ( " . - "'admin', " . - "MD5(''), " . - "'', " . - "'Administrator', " . - "'Administrator', " . - "'', " . - "65535" . - ")", - $link - ); - } else if ($id == "${mysqlprefix}chatrevision") { - $result = mysql_query("INSERT INTO ${mysqlprefix}chatrevision VALUES (1)", $link); - if (! $result) { - die(' Query failed: ' . mysql_error($link)); - } - } -} - -function get_tables($link) -{ - global $mysqldb, $errors; - $result = mysql_query("SHOW TABLES FROM `$mysqldb`", $link); - if ($result) { - $arr = array(); - while ($row = mysql_fetch_array($result, MYSQL_NUM)) { - $arr[] = $row[0]; - } - mysql_free_result($result); - return $arr; - - } else { - $errors[] = "Cannot get tables from database. Error: " . mysql_error($link); - return false; - } -} - -function get_columns($tablename, $link) -{ - global $errors; - $result = mysql_query("SHOW COLUMNS FROM $tablename", $link); - if ($result) { - $arr = array(); - while ($row = mysql_fetch_array($result, MYSQL_NUM)) { - $arr[] = $row[0]; - } - mysql_free_result($result); - return $arr; - - } else { - $errors[] = "Cannot get columns from table \"$tablename\". Error: " . mysql_error($link); - return false; - } -} - -function get_indexes($tablename, $link) -{ - global $mysqldb, $errors; - $result = mysql_query("SELECT index_name FROM information_schema.statistics where table_schema = '$mysqldb' and table_name = '$tablename' and index_name != 'PRIMARY'", $link); - if ($result) { - $arr = array(); - while ($row = mysql_fetch_array($result, MYSQL_NUM)) { - $arr[] = $row[0]; - } - mysql_free_result($result); - return $arr; - - } else { - $errors[] = "Cannot get indexes for table \"$tablename\". Error: " . mysql_error($link); - return false; - } -} - -?> \ No newline at end of file diff --git a/src/mibew/install/dbperform.php b/src/mibew/install/dbperform.php deleted file mode 100644 index 026ae192..00000000 --- a/src/mibew/install/dbperform.php +++ /dev/null @@ -1,333 +0,0 @@ - $columns) { - $curr_columns = get_columns($id, $link); - if ($curr_columns === false) { - show_install_err($errors[0]); - } - $tocreate = array_diff(array_keys($columns), $curr_columns); - foreach ($tocreate as $v) { - $absent_columns[] = "$id.$v"; - } - } - - if (in_array("${mysqlprefix}chatmessage.agentId", $absent_columns)) { - runsql("ALTER TABLE ${mysqlprefix}chatmessage ADD agentId int NOT NULL DEFAULT 0 AFTER ikind", $link); - runsql("update ${mysqlprefix}chatmessage, ${mysqlprefix}chatoperator set agentId = operatorid where agentId = 0 AND ikind = 2 AND (vclocalename = tname OR vccommonname = tname)", $link); - } - - if (in_array("${mysqlprefix}chatmessage.plugin", $absent_columns)) { - runsql("ALTER TABLE ${mysqlprefix}chatmessage ADD plugin varchar(256) NOT NULL DEFAULT '' AFTER tmessage", $link); - } - - if (in_array("${mysqlprefix}chatmessage.data", $absent_columns)) { - runsql("ALTER TABLE ${mysqlprefix}chatmessage ADD data text AFTER plugin", $link); - } - - if (in_array("${mysqlprefix}chatthread.agentId", $absent_columns)) { - runsql("ALTER TABLE ${mysqlprefix}chatthread ADD agentId int NOT NULL DEFAULT 0 AFTER agentName", $link); - runsql("update ${mysqlprefix}chatthread, ${mysqlprefix}chatoperator set agentId = operatorid where agentId = 0 AND (vclocalename = agentName OR vccommonname = agentName)", $link); - } - - if (in_array("${mysqlprefix}chatthread.dtmchatstarted", $absent_columns)) { - runsql("ALTER TABLE ${mysqlprefix}chatthread ADD dtmchatstarted int NOT NULL DEFAULT 0 AFTER dtmcreated", $link); - runsql("update ${mysqlprefix}chatthread set dtmchatstarted = dtmcreated", $link); - } - - if (in_array("${mysqlprefix}chatthread.dtmclosed", $absent_columns)) { - runsql("ALTER TABLE ${mysqlprefix}chatthread ADD dtmclosed int NOT NULL DEFAULT 0 AFTER dtmmodified", $link); - runsql("update ${mysqlprefix}chatthread set dtmclosed = dtmmodified", $link); - } - - if (in_array("${mysqlprefix}chatthread.agentTyping", $absent_columns)) { - runsql("ALTER TABLE ${mysqlprefix}chatthread ADD agentTyping int DEFAULT 0", $link); - } - - if (in_array("${mysqlprefix}chatthread.userTyping", $absent_columns)) { - runsql("ALTER TABLE ${mysqlprefix}chatthread ADD userTyping int DEFAULT 0", $link); - } - - if (in_array("${mysqlprefix}chatthread.messageCount", $absent_columns)) { - runsql("ALTER TABLE ${mysqlprefix}chatthread ADD messageCount varchar(16)", $link); - runsql("ALTER TABLE ${mysqlprefix}chatmessage ADD INDEX idx_threadid_ikind (threadid, ikind)", $link); - runsql("UPDATE ${mysqlprefix}chatthread t SET t.messageCount = (SELECT COUNT(*) FROM ${mysqlprefix}chatmessage WHERE ${mysqlprefix}chatmessage.threadid = t.threadid AND ikind = 1)", $link); - runsql("ALTER TABLE ${mysqlprefix}chatmessage DROP INDEX idx_threadid_ikind", $link); - } - - if (in_array("${mysqlprefix}chatthread.nextagent", $absent_columns)) { - runsql("ALTER TABLE ${mysqlprefix}chatthread ADD nextagent int NOT NULL DEFAULT 0", $link); - } - - if (in_array("${mysqlprefix}chatthread.shownmessageid", $absent_columns)) { - runsql("ALTER TABLE ${mysqlprefix}chatthread ADD shownmessageid int NOT NULL DEFAULT 0", $link); - } - - if (in_array("${mysqlprefix}chatthread.userid", $absent_columns)) { - runsql("ALTER TABLE ${mysqlprefix}chatthread ADD userid varchar(255) DEFAULT \"\"", $link); - } - - if (in_array("${mysqlprefix}chatthread.invitationstate", $absent_columns)) { - runsql("ALTER TABLE ${mysqlprefix}chatthread ADD invitationstate int NOT NULL DEFAULT 0 AFTER istate", $link); - } - - if (in_array("${mysqlprefix}chatthreadstatistics.missedthreads", $absent_columns)) { - runsql("ALTER TABLE ${mysqlprefix}chatthreadstatistics ADD missedthreads int NOT NULL DEFAULT 0 AFTER threads", $link); - } - - if (in_array("${mysqlprefix}chatthreadstatistics.sentinvitations", $absent_columns)) { - runsql("ALTER TABLE ${mysqlprefix}chatthreadstatistics ADD sentinvitations int NOT NULL DEFAULT 0 AFTER missedthreads", $link); - } - - if (in_array("${mysqlprefix}chatthreadstatistics.acceptedinvitations", $absent_columns)) { - runsql("ALTER TABLE ${mysqlprefix}chatthreadstatistics ADD acceptedinvitations int NOT NULL DEFAULT 0 AFTER sentinvitations", $link); - } - - if (in_array("${mysqlprefix}chatthreadstatistics.rejectedinvitations", $absent_columns)) { - runsql("ALTER TABLE ${mysqlprefix}chatthreadstatistics ADD rejectedinvitations int NOT NULL DEFAULT 0 AFTER acceptedinvitations", $link); - } - - if (in_array("${mysqlprefix}chatthreadstatistics.ignoredinvitations", $absent_columns)) { - runsql("ALTER TABLE ${mysqlprefix}chatthreadstatistics ADD ignoredinvitations int NOT NULL DEFAULT 0 AFTER rejectedinvitations", $link); - } - - if (in_array("${mysqlprefix}chatoperator.iperm", $absent_columns)) { - runsql("ALTER TABLE ${mysqlprefix}chatoperator ADD iperm int DEFAULT 65535", $link); - } - - if (in_array("${mysqlprefix}chatoperator.istatus", $absent_columns)) { - runsql("ALTER TABLE ${mysqlprefix}chatoperator ADD istatus int DEFAULT 0", $link); - } - - if (in_array("${mysqlprefix}chatoperator.idisabled", $absent_columns)) { - runsql("ALTER TABLE ${mysqlprefix}chatoperator ADD idisabled int DEFAULT 0 AFTER istatus", $link); - } - - if (in_array("${mysqlprefix}chatoperator.vcavatar", $absent_columns)) { - runsql("ALTER TABLE ${mysqlprefix}chatoperator ADD vcavatar varchar(255)", $link); - } - - if (in_array("${mysqlprefix}chatoperator.vcjabbername", $absent_columns)) { - runsql("ALTER TABLE ${mysqlprefix}chatoperator ADD vcjabbername varchar(255)", $link); - } - - if (in_array("${mysqlprefix}chatoperator.vcemail", $absent_columns)) { - runsql("ALTER TABLE ${mysqlprefix}chatoperator ADD vcemail varchar(64)", $link); - } - - if (in_array("${mysqlprefix}chatoperator.dtmrestore", $absent_columns)) { - runsql("ALTER TABLE ${mysqlprefix}chatoperator ADD dtmrestore int NOT NULL DEFAULT 0", $link); - } - - if (in_array("${mysqlprefix}chatoperator.vcrestoretoken", $absent_columns)) { - runsql("ALTER TABLE ${mysqlprefix}chatoperator ADD vcrestoretoken varchar(64)", $link); - } - - if (in_array("${mysqlprefix}chatoperator.code", $absent_columns)) { - runsql("ALTER TABLE ${mysqlprefix}chatoperator ADD code varchar(64) DEFAULT ''", $link); - } - - if (in_array("${mysqlprefix}chatoperatorstatistics.sentinvitations", $absent_columns)) { - runsql("ALTER TABLE ${mysqlprefix}chatoperatorstatistics ADD sentinvitations int NOT NULL DEFAULT 0", $link); - } - - if (in_array("${mysqlprefix}chatoperatorstatistics.acceptedinvitations", $absent_columns)) { - runsql("ALTER TABLE ${mysqlprefix}chatoperatorstatistics ADD acceptedinvitations int NOT NULL DEFAULT 0", $link); - } - - if (in_array("${mysqlprefix}chatoperatorstatistics.rejectedinvitations", $absent_columns)) { - runsql("ALTER TABLE ${mysqlprefix}chatoperatorstatistics ADD rejectedinvitations int NOT NULL DEFAULT 0", $link); - } - - if (in_array("${mysqlprefix}chatoperatorstatistics.ignoredinvitations", $absent_columns)) { - runsql("ALTER TABLE ${mysqlprefix}chatoperatorstatistics ADD ignoredinvitations int NOT NULL DEFAULT 0", $link); - } - - if (in_array("${mysqlprefix}chatresponses.vctitle", $absent_columns)) { - runsql("ALTER TABLE ${mysqlprefix}chatresponses ADD vctitle varchar(100) NOT NULL DEFAULT '' AFTER groupid", $link); - } - - if (in_array("${mysqlprefix}chatthread.groupid", $absent_columns)) { - runsql("ALTER TABLE ${mysqlprefix}chatthread ADD groupid int references ${mysqlprefix}chatgroup(groupid)", $link); - } - - if (in_array("${mysqlprefix}chatthread.userAgent", $absent_columns)) { - runsql("ALTER TABLE ${mysqlprefix}chatthread ADD userAgent varchar(255)", $link); - } - - if (in_array("${mysqlprefix}chatgroup.vcemail", $absent_columns)) { - runsql("ALTER TABLE ${mysqlprefix}chatgroup ADD vcemail varchar(64)", $link); - } - - if (in_array("${mysqlprefix}chatgroup.iweight", $absent_columns)) { - runsql("ALTER TABLE ${mysqlprefix}chatgroup ADD iweight int DEFAULT 0", $link); - } - - if (in_array("${mysqlprefix}chatgroup.parent", $absent_columns)) { - runsql("ALTER TABLE ${mysqlprefix}chatgroup ADD parent int DEFAULT NULL AFTER groupid", $link); - } - - if (in_array("${mysqlprefix}chatgroup.vctitle", $absent_columns)) { - runsql("ALTER TABLE ${mysqlprefix}chatgroup ADD vctitle varchar(255) DEFAULT ''", $link); - } - - if (in_array("${mysqlprefix}chatgroup.vcchattitle", $absent_columns)) { - runsql("ALTER TABLE ${mysqlprefix}chatgroup ADD vcchattitle varchar(255) DEFAULT ''", $link); - } - - if (in_array("${mysqlprefix}chatgroup.vclogo", $absent_columns)) { - runsql("ALTER TABLE ${mysqlprefix}chatgroup ADD vclogo varchar(255) DEFAULT ''", $link); - } - - if (in_array("${mysqlprefix}chatgroup.vchosturl", $absent_columns)) { - runsql("ALTER TABLE ${mysqlprefix}chatgroup ADD vchosturl varchar(255) DEFAULT ''", $link); - } - - if (in_array("${mysqlprefix}visitedpagestatistics.sentinvitations", $absent_columns)) { - runsql("ALTER TABLE ${mysqlprefix}visitedpagestatistics ADD sentinvitations int NOT NULL DEFAULT 0", $link); - } - - if (in_array("${mysqlprefix}visitedpagestatistics.acceptedinvitations", $absent_columns)) { - runsql("ALTER TABLE ${mysqlprefix}visitedpagestatistics ADD acceptedinvitations int NOT NULL DEFAULT 0", $link); - } - - if (in_array("${mysqlprefix}visitedpagestatistics.rejectedinvitations", $absent_columns)) { - runsql("ALTER TABLE ${mysqlprefix}visitedpagestatistics ADD rejectedinvitations int NOT NULL DEFAULT 0", $link); - } - - if (in_array("${mysqlprefix}visitedpagestatistics.ignoredinvitations", $absent_columns)) { - runsql("ALTER TABLE ${mysqlprefix}visitedpagestatistics ADD ignoredinvitations int NOT NULL DEFAULT 0", $link); - } - -// Add absent indexes - $absent_indexes = array(); - foreach ($dbtables_indexes as $id => $indexes) { - $curr_indexes = get_indexes($id, $link); - if ($curr_indexes === false) { - show_install_err($errors[0]); - } - $tocreate = array_diff(array_keys($indexes), $curr_indexes); - foreach ($tocreate as $i) { - $absent_indexes[] = "$id.$i"; - } - } - - if (in_array("${mysqlprefix}chatgroup.parent", $absent_indexes)) { - runsql("ALTER TABLE ${mysqlprefix}chatgroup ADD INDEX (parent)", $link); - } - - if (in_array("${mysqlprefix}chatgroupoperator.groupid", $absent_indexes)) { - runsql("ALTER TABLE ${mysqlprefix}chatgroupoperator ADD INDEX (groupid)", $link); - } - - if (in_array("${mysqlprefix}chatgroupoperator.operatorid", $absent_indexes)) { - runsql("ALTER TABLE ${mysqlprefix}chatgroupoperator ADD INDEX (operatorid)", $link); - } - - if (in_array("${mysqlprefix}chatmessage.idx_agentid", $absent_indexes)) { - runsql("ALTER TABLE ${mysqlprefix}chatmessage ADD INDEX idx_agentid (agentid)", $link); - } - - if (in_array("${mysqlprefix}chatsitevisitor.threadid", $absent_indexes)) { - runsql("ALTER TABLE ${mysqlprefix}chatsitevisitor ADD INDEX (threadid)", $link); - } - - if (in_array("${mysqlprefix}visitedpage.visitorid", $absent_indexes)) { - runsql("ALTER TABLE ${mysqlprefix}visitedpage ADD INDEX (visitorid)", $link); - } - - if (in_array("${mysqlprefix}chatoperatorstatistics.operatorid", $absent_indexes)) { - runsql("ALTER TABLE ${mysqlprefix}chatoperatorstatistics ADD INDEX (operatorid)", $link); - } - } -} - -mysql_close($link); -header("Location: " . MIBEW_WEB_ROOT . "/install/index.php"); -exit; -?> \ No newline at end of file diff --git a/src/mibew/install/index.php b/src/mibew/install/index.php deleted file mode 100644 index 5c821ef2..00000000 --- a/src/mibew/install/index.php +++ /dev/null @@ -1,505 +0,0 @@ - MIBEW_VERSION, - 'localeLinks' => get_locale_links() -); - -$page['done'] = array(); -$page['nextstep'] = false; -$page['nextnotice'] = false; -$page['soundcheck'] = false; -$errors = array(); - -function check_mibewroot() -{ - global $page, $errors; - - if (MIBEW_CONFIG_WEB_ROOT != MIBEW_WEB_ROOT) { - $errors[] = "Please, check file " . MIBEW_WEB_ROOT . "/libs/config.php
Wrong value of \$mibewroot variable, should be \"" . MIBEW_WEB_ROOT . "\""; - return false; - } - - $page['done'][] = getlocal("Application path is {0}", array(MIBEW_WEB_ROOT)); - return true; -} - -function fpermissions($file) -{ - $perms = fileperms($file); - if (($perms & 0x8000) == 0x8000) { - $info = '-'; - } elseif (($perms & 0x4000) == 0x4000) { - $info = 'd'; - } else { - $info = '?'; - } - - // Owner - $info .= (($perms & 0x0100) ? 'r' : '-'); - $info .= (($perms & 0x0080) ? 'w' : '-'); - $info .= (($perms & 0x0040) ? - (($perms & 0x0800) ? 's' : 'x') : - (($perms & 0x0800) ? 'S' : '-')); - - // Group - $info .= (($perms & 0x0020) ? 'r' : '-'); - $info .= (($perms & 0x0010) ? 'w' : '-'); - $info .= (($perms & 0x0008) ? - (($perms & 0x0400) ? 's' : 'x') : - (($perms & 0x0400) ? 'S' : '-')); - - // World - $info .= (($perms & 0x0004) ? 'r' : '-'); - $info .= (($perms & 0x0002) ? 'w' : '-'); - $info .= (($perms & 0x0001) ? - (($perms & 0x0200) ? 't' : 'x') : - (($perms & 0x0200) ? 'T' : '-')); - - return $info; -} - -function check_files() -{ - global $page, $errors; - - $packageFile = MIBEW_FS_ROOT . "/install/package"; - $fp = @fopen($packageFile, "r"); - if ($fp === FALSE) { - $errors[] = getlocal("Cannot read file {0}", array(MIBEW_WEB_ROOT . "/install/package")); - if (file_exists($packageFile)) { - $errors[] = getlocal("Insufficient file permissions {0}", array(fpermissions($packageFile))); - } - return false; - } - - $knownFiles = array(); - while (!feof($fp)) { - $line = fgets($fp, 4096); - $keyval = preg_split("/ /", $line, 2); - if (isset($keyval[1])) { - $knownFiles[$keyval[0]] = trim($keyval[1]); - } - } - fclose($fp); - - foreach ($knownFiles as $file => $sum) { - $relativeName = MIBEW_FS_ROOT . "/$file"; - if (!is_readable($relativeName)) { - if (file_exists($relativeName)) { - $errors[] = getlocal("Cannot read file {0}", array(MIBEW_WEB_ROOT . "/$file")); - $errors[] = getlocal("Insufficient file permissions {0}", array(fpermissions($relativeName))); - } else { - $errors[] = getlocal("File is absent: {0}", array(MIBEW_WEB_ROOT . "/$file")); - } - return false; - } - if ($sum != "-") { - $result = md5_file($relativeName); - if ($result != $sum) { - // try without \r - $result = md5(str_replace("\r", "", file_get_contents($relativeName))); - } - if ($result != $sum) { - $errors[] = getlocal("Checksum differs for {0}", array(MIBEW_WEB_ROOT . "/$file")); - $errors[] = getlocal("Please, re-upload files to the server."); - return false; - } - } - } - - $page['done'][] = getlocal("Mibew package is valid."); - return true; -} - -function check_connection() -{ - global $mysqlhost, $mysqllogin, $mysqlpass, $page, $errors; - $link = @mysql_connect($mysqlhost, $mysqllogin, $mysqlpass); - if ($link) { - $result = mysql_query("SELECT VERSION() as c", $link); - if ($result && $ver = mysql_fetch_array($result, MYSQL_ASSOC)) { - $page['done'][] = getlocal("You are connected to MySQL server version {0}", array($ver['c'])); - mysql_free_result($result); - } else { - $errors[] = "Version of your SQL server is unknown. Please check. Error: " . mysql_error($link); - mysql_close($link); - return null; - } - return $link; - } else { - $errors[] = getlocal("Could not connect. Please check server settings in config.php. Error: {0}", array(mysql_error())); - return null; - } -} - -function check_database($link) -{ - global $mysqldb, $page; - if (mysql_select_db($mysqldb, $link)) { - $page['done'][] = getlocal("Database \"{0}\" is created.", array($mysqldb)); - mysql_query("SET character set utf8", $link); - - return true; - } else { - $page['nextstep'] = getlocal("Create database \"{0}\"", array($mysqldb)); - $page['nextnotice'] = getlocal("The database was not found on the server. If you have permissions to create it now, click on the following link."); - $page['nextstepurl'] = MIBEW_WEB_ROOT . "/install/dbperform.php?act=createdb"; - } - return false; -} - -function check_tables($link) -{ - global $dbtables, $page; - $curr_tables = get_tables($link); - if ($curr_tables !== false) { - $tocreate = array_diff(array_keys($dbtables), $curr_tables); - if (count($tocreate) == 0) { - $page['done'][] = getlocal("Required tables are created."); - return true; - } else { - $page['nextstep'] = getlocal("Create required tables."); - $page['nextstepurl'] = MIBEW_WEB_ROOT . "/install/dbperform.php?act=ct"; - } - } - return false; -} - -function check_columns($link) -{ - global $dbtables, $dbtables_can_update, $dbtables_indexes, $errors, $page; - - $need_to_create_columns = false; - foreach ($dbtables as $id => $columns) { - $curr_columns = get_columns($id, $link); - if ($curr_columns === false) { - return false; - } - $tocreate = array_diff(array_keys($columns), $curr_columns); - if (count($tocreate) != 0) { - $cannot_update = array_diff($tocreate, $dbtables_can_update[$id]); - if (count($cannot_update) != 0) { - $errors[] = "Key columns are absent in table `$id'. Unable to continue installation."; - $page['nextstep'] = getlocal("Drop existing tables from database"); - $page['nextstepurl'] = MIBEW_WEB_ROOT . "/install/dbperform.php?act=dt"; - $page['nextnotice'] = getlocal("Impossible to update tables structure. Try to do it manually or recreate all tables (warning: all your data will be lost)."); - return false; - } - $need_to_create_columns = true; - } - } - - $need_to_create_indexes = false; - foreach ($dbtables_indexes as $id => $indexes) { - $curr_indexes = get_indexes($id, $link); - if ($curr_indexes === false) { - return false; - } - $tocreate = array_diff(array_keys($indexes), $curr_indexes); - if (count($tocreate) != 0) { - $need_to_create_indexes = true; - } - } - - if ($need_to_create_columns || $need_to_create_indexes) { - $page['nextstep'] = getlocal("Update tables"); - $page['nextstepurl'] = MIBEW_WEB_ROOT . "/install/dbperform.php?act=addcolumns"; - $page['nextnotice'] = getlocal("Structure of your tables should be adjusted for new version of Messenger."); - return false; - } - - $page['done'][] = getlocal("Tables structure is up to date."); - return true; -} - -function check_sound() -{ - global $page; - - $page['soundcheck'] = true; - $page['done'][] = getlocal("Click to check the sound: {0} and {1}", array( - "" . getlocal("New Visitor") . "", - "" . getlocal("New Message") . "" - )); -} - -function check_admin($link) -{ - global $mysqlprefix; - $result = mysql_query("select * from ${mysqlprefix}chatoperator where vclogin = 'admin'", $link); - if ($result) { - $line = mysql_fetch_array($result, MYSQL_ASSOC); - mysql_free_result($result); - return $line['vcpassword'] != md5(''); - } - - return false; -} - -function add_canned_messages($link){ - global $mysqlprefix; - $localesresult = mysql_query("select locale from ${mysqlprefix}chatresponses", $link); - $existlocales = array(); - for ($i = 0; $i < mysql_num_rows($localesresult); $i++) { - $existlocales[] = mysql_result($localesresult, $i, 'locale'); - } - $result = array(); - foreach (get_available_locales() as $locale) { - if (in_array($locale, $existlocales)) { - // Do not export canned messages for existing locales - continue; - } - - $file_path = MIBEW_FS_ROOT . '/locales/' . $locale . '/canned_messages.yml'; - if (!is_readable($file_path)) { - // Export canned messages only for locales which have canned messages - continue; - } - - $canned_messages = get_yml_file_content($file_path); - foreach ($canned_messages as $answer) { - $result[] = array('locale' => $locale, 'vctitle' => cut_string($answer, 97, '...'), 'vcvalue' => $answer); - } - } - if (count($result) > 0) { - $updatequery = "insert into ${mysqlprefix}chatresponses (vctitle,vcvalue,locale,groupid) values "; - for ($i = 0; $i < count($result); $i++) { - if ($i > 0) { - $updatequery .= ", "; - } - $updatequery .= "('" . mysql_real_escape_string($result[$i]['vctitle'], $link) . "', " - . "'" . mysql_real_escape_string($result[$i]['vcvalue'], $link) . "', " - . "'" . mysql_real_escape_string($result[$i]['locale'], $link) . "', NULL)"; - } - mysql_query($updatequery, $link); - } -} - -function add_mail_templates($link){ - global $mysqlprefix; - $localesresult = mysql_query("select distinct locale from ${mysqlprefix}mailtemplate", $link); - $existlocales = array(); - for ($i = 0; $i < mysql_num_rows($localesresult); $i++) { - $existlocales[] = mysql_result($localesresult, $i, 'locale'); - } - $result = array(); - foreach (get_available_locales() as $locale) { - if (in_array($locale, $existlocales)) { - // Do not export mail templates for existing locales - continue; - } - - $file_path = MIBEW_FS_ROOT . '/locales/' . $locale . '/mail_templates.yml'; - if (!is_readable($file_path)) { - // Export templates only for locales which have templates - continue; - } - - $templates = get_yml_file_content($file_path); - if (isset($templates['user_history'])) { - $result[] = array( - 'locale' => $locale, - 'name' => 'user_history', - 'subject' => $templates['user_history']['subject'], - 'body' => $templates['user_history']['body'], - ); - } - - if (isset($templates['password_recovery'])) { - $result[] = array( - 'locale' => $locale, - 'name' => 'password_recovery', - 'subject' => $templates['password_recovery']['subject'], - 'body' => $templates['password_recovery']['body'], - ); - } - - if (isset($templates['leave_message'])) { - $result[] = array( - 'locale' => $locale, - 'name' => 'leave_message', - 'subject' => $templates['leave_message']['subject'], - 'body' => $templates['leave_message']['body'], - ); - } - } - if (count($result) > 0) { - $updatequery = "insert into ${mysqlprefix}mailtemplate (name,locale,subject,body) values "; - for ($i = 0; $i < count($result); $i++) { - if ($i > 0) { - $updatequery .= ", "; - } - $updatequery .= "('" . mysql_real_escape_string($result[$i]['name'], $link) . "', " - . "'" . mysql_real_escape_string($result[$i]['locale'], $link) . "', " - . "'" . mysql_real_escape_string($result[$i]['subject'], $link) . "', " - . "'" . mysql_real_escape_string($result[$i]['body'], $link) . "')"; - } - mysql_query($updatequery, $link); - } -} - -function add_locales($link) -{ - global $mysqlprefix; - - $localesresult = mysql_query("select code from ${mysqlprefix}locale", $link); - $existlocales = array(); - for ($i = 0; $i < mysql_num_rows($localesresult); $i++) { - $existlocales[] = mysql_result($localesresult, $i, 'code'); - } - $locales = discover_locales(); - foreach ($locales as $locale) { - if (in_array($locale, $existlocales)) { - // Do not add locales twice. - continue; - } - $query = "insert into ${mysqlprefix}locale (code, enabled) values ('" - . mysql_real_escape_string($locale, $link) . "', 1)"; - mysql_query($query, $link); - } -} - -function get_yml_file_content($file) -{ - $yaml = new \Symfony\Component\Yaml\Parser(); - - return $yaml->parse(file_get_contents($file)); -} - -function check_status() -{ - global $page, $mysqlprefix; - - $page['done'][] = getlocal("PHP version {0}", array(phpversion())); - - if (!check_mibewroot()) { - return; - } - - if (!check_files()) { - return; - } - - $link = check_connection(); - if (!$link) { - return; - } - - if (!check_database($link)) { - mysql_close($link); - return; - } - - if (!check_tables($link)) { - mysql_close($link); - return; - } - - if (!check_columns($link)) { - mysql_close($link); - return; - } - - add_locales($link); - add_canned_messages($link); - add_mail_templates($link); - - check_sound(); - - $page['done'][] = getlocal("Application installed successfully."); - - if (!check_admin($link)) { - $page['nextstep'] = getlocal("Proceed to the login page"); - $page['nextnotice'] = getlocal("You can logon as admin with empty password.

!!! For security reasons please change your password immediately and remove the {0} folder from your server.", array(MIBEW_WEB_ROOT . "/install/")); - $page['nextstepurl'] = MIBEW_WEB_ROOT . "/operator/login?login=admin"; - } - - $page['show_small_login'] = true; - - // Update current dbversion - $res = mysql_query("select COUNT(*) as count from ${mysqlprefix}chatconfig where vckey = 'dbversion'", $link); - if(mysql_result($res, 0, 'count') == 0) { - mysql_query("insert into ${mysqlprefix}chatconfig (vckey) values ('dbversion')", $link); - } - - mysql_query("update ${mysqlprefix}chatconfig set vcvalue = '" . DB_VERSION . "' where vckey='dbversion'", $link); - mysql_close($link); - -} - -check_status(); - -$page['title'] = getlocal("Installation"); -$page['fixedwrap'] = true; -$page['errors'] = $errors; - -$page_style = new \Mibew\Style\PageStyle('default'); - -start_html_output(); -echo($page_style->render('install_index', $page)); - -?> \ No newline at end of file diff --git a/src/mibew/install/migrate.php b/src/mibew/install/migrate.php deleted file mode 100644 index f7161738..00000000 --- a/src/mibew/install/migrate.php +++ /dev/null @@ -1,68 +0,0 @@ -throwExeptions(true); - -$update_datetime = array( - '{chatthread}' => array( - 'dtmcreated', - 'dtmchatstarted', - 'dtmmodified', - 'lastpinguser', - 'lastpingagent' - ), - '{chatmessage}' => array( - 'dtmcreated' - ), - '{chatoperator}' => array( - 'dtmlastvisited', - 'dtmrestore' - ), - '{chatban}' => array( - 'dtmcreated', - 'dtmtill' - ), - '{chatsitevisitor}' => array( - 'firsttime', - 'lasttime', - 'invitationtime' - ), - '{visitedpage}' => array( - 'visittime' - ), - '{visitedpagestatistics}' => array( - 'visittime' - ) -); - -foreach($update_datetime as $table => $columns) { - echo("Table: {$table}
"); - foreach($columns as $column) { - echo("-- Column: {$column}
"); - $db->query("ALTER TABLE {$table} CHANGE {$column} {$column}_tmp datetime"); - $db->query("ALTER TABLE {$table} ADD COLUMN {$column} int NOT NULL DEFAULT 0 AFTER {$column}_tmp"); - $db->query("UPDATE {$table} SET {$column} = UNIX_TIMESTAMP({$column}_tmp)"); - $db->query("ALTER TABLE {$table} DROP COLUMN {$column}_tmp"); - } -} - - -?> \ No newline at end of file diff --git a/src/mibew/libs/classes/Mibew/Authentication/DummyAuthenticationManager.php b/src/mibew/libs/classes/Mibew/Authentication/DummyAuthenticationManager.php new file mode 100644 index 00000000..03e14058 --- /dev/null +++ b/src/mibew/libs/classes/Mibew/Authentication/DummyAuthenticationManager.php @@ -0,0 +1,73 @@ + MIBEW_VERSION, + 'localeLinks' => get_locale_links(), + 'fixedwrap' => true, + 'title' => getlocal("Installation"), + ); + + $installer = $this->getInstaller(); + $state = $installer->install($request->getBasePath()); + $installation_error = $state == Installer::STATE_NEED_UPDATE_TABLES + || $state == Installer::STATE_ERROR; + + if ($installation_error) { + $page['title'] = getlocal('Problem'); + $page['no_right_menu'] = true; + + if ($state == Installer::STATE_NEED_UPDATE_TABLES) { + // The installer should not update tables structure. + $page['errors'] = array( + getlocal('Mibew is already installed and must be updated. Use the updater.') + ); + } else { + // Installer thinks that something went wrong. Believe it and + // use its errors. + $page['errors'] = $installer->getErrors(); + } + + return $this->render('install_err', $page); + } + + $page['done'] = $installer->getLog(); + $page['errors'] = $installer->getErrors(); + + if ($state == Installer::STATE_SUCCESS || $state == Installer::STATE_NEED_CHANGE_PASSWORD) { + // Everything is ok. The installation is completed. + $page['soundcheck'] = true; + $page['done'][] = getlocal("Click to check the sound: {0} and {1}", array( + "" . getlocal("New Visitor") . "", + "" . getlocal("New Message") . "" + )); + $page['done'][] = getlocal("Application installed successfully."); + + if ($state == Installer::STATE_NEED_CHANGE_PASSWORD) { + $notice = getlocal('You can logon as admin with empty password.') + . '

' + . '' + . getlocal( + 'For security reasons please change your password immediately and remove {0} file from your server.', + array(MIBEW_WEB_ROOT . '/install.php') + ) + . ''; + + $page['nextstep'] = getlocal("Proceed to the login page"); + $page['nextnotice'] = $notice; + $page['nextstepurl'] = $this->generateUrl('login', array('login' => 'admin')); + } + } elseif ($state == Installer::STATE_NEED_CREATE_TABLES) { + // There is no tables in the database. We need to create them. + $page['nextstep'] = getlocal("Create required tables."); + $page['nextstepurl'] = $this->generateUrl('install_create_tables'); + } else { + throw new \RuntimeException( + sprintf('Unknown installer state "%s".', $state) + ); + } + + return $this->render('install_index', $page); + } + + /** + * An action that create necessary database tables. + * + * @param Request $request Incoming request + * @return string Rendered page content. + */ + public function createTablesAction(Request $request) + { + $installer = $this->getInstaller(); + + if (!$installer->createTables()) { + // By some reasons tables cannot be created. Tell it to the user. + return $this->render( + 'install_err', + array( + 'version' => MIBEW_VERSION, + 'localeLinks' => get_locale_links(), + 'title' => getlocal('Problem'), + 'no_right_menu' => true, + 'fixedwrap' => true, + 'errors' => $installer->getErrors(), + ) + ); + } + + // Tables are successfully created. Go back to the main installation + // page. + return $this->redirect($this->generateUrl('install')); + } + + /** + * Initialize installer. + * + * @return \Mibew\Installer + */ + protected function getInstaller() + { + if (is_null($this->installer)) { + $this->installer = new Installer(load_system_configs()); + } + + return $this->installer; + } + + /** + * {@inheritdoc} + */ + protected function getStyle() + { + if (is_null($this->style)) { + $this->style = new PageStyle('default'); + } + + return $this->style; + } +} diff --git a/src/mibew/libs/classes/Mibew/Installer.php b/src/mibew/libs/classes/Mibew/Installer.php new file mode 100644 index 00000000..5e869245 --- /dev/null +++ b/src/mibew/libs/classes/Mibew/Installer.php @@ -0,0 +1,771 @@ +configs = $system_configs; + $this->parser = new YamlParser(); + } + + /** + * Retuns list of all errors that took place during installation process. + * + * @return string[] + */ + public function getErrors() + { + return $this->errors; + } + + /** + * Returns list of all information messages. + * + * @return string[] + */ + public function getLog() + { + return $this->log; + } + + /** + * Install Mibew. + * + * @param string $real_base_path Real base path of the Mibew instance. For + * example if one tries to install Mibew to http://example.com/foo/mibew/ + * the argument should be equal to "foo/mibew". + * @return string Installation state. One of Installer::STATE_* constant. + */ + public function install($real_base_path) + { + if (!$this->checkPhpVersion()) { + return self::STATE_ERROR; + } + + $this->log[] = getlocal( + 'PHP version {0}', + array(format_version_id($this->getPhpVersionId())) + ); + + if (!$this->checkMibewRoot($real_base_path)) { + return self::STATE_ERROR; + } + + $this->log[] = getlocal( + 'Application path is {0}', + array($real_base_path) + ); + + if (!$this->checkConnection()) { + return self::STATE_ERROR; + } + + if (!$this->checkMysqlVersion()) { + return self::STATE_ERROR; + } + + $this->log[] = getlocal( + 'You are connected to MySQL server version {0}', + array($this->getMysqlVersion()) + ); + + if (!$this->databaseExists()) { + return self::STATE_NEED_CREATE_TABLES; + } + + if ($this->databaseNeedUpdate()) { + return self::STATE_NEED_UPDATE_TABLES; + } + + $this->log[] = getlocal('Required tables are created.'); + $this->log[] = getlocal('Tables structure is up to date.'); + + if (!$this->importLocales()) { + return self::STATE_ERROR; + } + $this->log[] = getlocal('Locales are imported.'); + + if (!$this->importLocalesContent()) { + return self::STATE_ERROR; + } + $this->log[] = getlocal('Locales content is imported.'); + + if ($this->needChangePassword()) { + return self::STATE_NEED_CHANGE_PASSWORD; + } + + return self::STATE_SUCCESS; + } + + /** + * Creates necessary tables. + * + * @return boolean Indicates if tables created or not. A list of all errors + * can be got using {@link \Mibew\Installer::getErrors()} method. + */ + public function createTables() + { + if (!($db = $this->getDatabase())) { + return false; + } + + try { + // Create tables according to database schema + $schema = $this->getDatabaseSchema(); + foreach ($schema as $table => $table_structure) { + $table_items = array(); + + // Add fields + foreach ($table_structure['fields'] as $field => $definition) { + $table_items[] = sprintf('%s %s', $field, $definition); + } + + // Add indexes + if (!empty($table_structure['indexes'])) { + foreach ($table_structure['indexes'] as $index => $fields) { + $table_items[] = sprintf( + 'INDEX %s (%s)', + $index, + implode(', ', $fields) + ); + } + } + + // Add unique keys + if (!empty($table_structure['unique_keys'])) { + foreach ($table_structure['unique_keys'] as $key => $fields) { + $table_items[] = sprintf( + 'UNIQUE KEY %s (%s)', + $key, + implode(', ', $fields) + ); + } + } + + $db->query(sprintf( + 'CREATE TABLE IF NOT EXISTS {%s} (%s) charset utf8 ENGINE=InnoDb', + $table, + implode(', ', $table_items) + )); + } + } catch(\Exception $e) { + $this->errors[] = getlocal( + 'Cannot create tables. Error: {0}', + array($e->getMessage()) + ); + + return false; + } + + if (!$this->prepopulateDatabase()) { + return false; + } + + return true; + } + + /** + * Saves some necessary data in the database. + * + * This method is called just once after tables are created. + * + * @return boolean Indicates if the data are saved to the database or not. + */ + protected function prepopulateDatabase() + { + if (!($db = $this->getDatabase())) { + return false; + } + + // Create The First Administrator if needed + try { + list($count) = $db->query( + 'SELECT COUNT(*) FROM {chatoperator} WHERE vclogin = :login', + array(':login' => 'admin'), + array( + 'return_rows' => Database::RETURN_ONE_ROW, + 'fetch_type' => Database::FETCH_NUM + ) + ); + if ($count == 0) { + $db->query( + ('INSERT INTO {chatoperator} ( ' + . 'vclogin, vcpassword, vclocalename, vccommonname, ' + . 'vcavatar, vcemail, iperm ' + . ') values ( ' + . ':login, :pass, :local_name, :common_name, ' + . ':avatar, :email, :permissions)'), + array( + ':login' => 'admin', + ':pass' => md5(''), + ':local_name' => 'Administrator', + ':common_name' => 'Administrator', + ':avatar' => '', + ':email' => '', + ':permissions' => 65535, + ) + ); + } + } catch(\Exception $e) { + $this->errors[] = getlocal( + 'Cannot create the first administrator. Error {0}', + array($e->getMessage()) + ); + + return false; + } + + // Initialize chat revision counter if it is needed + try { + list($count) = $db->query( + 'SELECT COUNT(*) FROM {chatrevision}', + null, + array( + 'return_rows' => Database::RETURN_ONE_ROW, + 'fetch_type' => Database::FETCH_NUM + ) + ); + if ($count == 0) { + $db->query( + 'INSERT INTO {chatrevision} VALUES (:init_revision)', + array(':init_revision' => 1) + ); + } + } catch(\Exception $e) { + $this->errors[] = getlocal( + 'Cannot initialize chat revision sequence. Error {0}', + array($e->getMessage()) + ); + + return false; + } + + // Set correct database structure version if needed + try { + list($count) = $db->query( + 'SELECT COUNT(*) FROM {chatconfig} WHERE vckey = :key', + array(':key' => 'dbversion'), + array( + 'return_rows' => Database::RETURN_ONE_ROW, + 'fetch_type' => Database::FETCH_NUM + ) + ); + if ($count == 0) { + $db->query( + 'INSERT INTO {chatconfig} (vckey, vcvalue) VALUES (:key, :value)', + array( + ':key' => 'dbversion', + ':value' => DB_VERSION, + ) + ); + } + } catch(\Exception $e) { + $this->errors[] = getlocal( + 'Cannot store database structure version. Error {0}', + array($e->getMessage()) + ); + + return false; + } + + return true; + } + + /** + * Checks if $mibewroot param in system configs is correct or not. + * + * @param string $real_base_path Real base path of the Mibew instance. + * @return boolean True if the $mibewroot param in config is correct and + * false otherwise. + */ + protected function checkMibewRoot($real_base_path) + { + if ($real_base_path != MIBEW_WEB_ROOT) { + $this->errors[] = getlocal( + "Please, check file {0}
Wrong value of \$mibewroot variable, should be \"{1}\"", + array( + $real_base_path . "/libs/config.php", + $real_base_path + ) + ); + + return false; + } + + return true; + } + + /** + * Checks database connection. + * + * @return boolean True if connection is established and false otherwise. + */ + protected function checkConnection() + { + if (!$this->getDatabase()) { + return false; + } + + return true; + } + + /** + * Checks if PHP version is high enough to run Mibew. + * + * @return boolean True if PHP version is suitable and false otherwise. + */ + protected function checkPhpVersion() + { + $current_version = $this->getPhpVersionId(); + + if ($current_version < self::MIN_PHP_VERSION) { + $this->errors[] = getlocal( + "PHP version is {0}, but Mibew works with {1} and later versions.", + array( + format_version_id($current_version), + format_version_id(self::MIN_PHP_VERSION) + ) + ); + + return false; + } + + return true; + } + + /** + * Checks if MySQL version is high enough or not to run Mibew. + * + * @return boolean True if MySQL version is suitable and false otherwise. + * @todo Add real version check. + */ + protected function checkMysqlVersion() + { + // At the moment minimal MySQL version is unknown. One should find + // it out and replace the following with a real check. + return ($this->getMysqlVersion() !== false); + } + + /** + * Returns current PHP version ID. + * + * For example, for PHP 5.3.3 the number 50303 will be returned. + * + * @return integer Verison ID. + */ + protected function getPhpVersionId() + { + // PHP_VERSION_ID is available as of PHP 5.2.7 so we need to use + // workaround for lower versions. + return defined('PHP_VERSION_ID') ? PHP_VERSION_ID : 0; + } + + /** + * Returns current MySQL server version. + * + * @return string|boolean Current MySQL version or boolean false it it + * cannot be determined. + */ + protected function getMysqlVersion() + { + if (!($db = $this->getDatabase())) { + return false; + } + + try { + $result = $db->query( + "SELECT VERSION() as c", + null, + array('return_rows' => Database::RETURN_ONE_ROW) + ); + } catch (\Exception $e) { + return false; + } + + return $result['c']; + } + + /** + * Gets version of existing database structure. + * + * If Mibew is not installed yet boolean false will be returned. + * + * @return int|boolean Database structure version or boolean false if the + * version cannot be determined. + */ + protected function getDatabaseVersion() + { + if (!($db = $this->getDatabase())) { + return false; + } + + try { + $result = $db->query( + "SELECT vcvalue AS version FROM {chatconfig} WHERE vckey = :key LIMIT 1", + array(':key' => 'dbversion'), + array('return_rows' => Database::RETURN_ONE_ROW) + ); + } catch (\Exception $e) { + return false; + } + + if (!$result) { + // It seems that database structure version isn't stored in the + // database. + return 0; + } + + return intval($result['version']); + } + + /** + * Checks if the database structure must be updated. + * + * @return boolean + */ + protected function databaseNeedUpdate() + { + return ($this->getDatabaseVersion() < DB_VERSION); + } + + /** + * Checks if database structure is already created. + * + * @return boolean + */ + protected function databaseExists() + { + return ($this->getDatabaseVersion() !== false); + } + + /** + * Check if the admin must change his password to a new one. + * + * @return boolean True if the password must be changed and false otherwise. + */ + protected function needChangePassword() + { + if (!($db = $this->getDatabase())) { + return false; + } + + try { + $admin = $db->query( + 'SELECT * FROM {chatoperator} WHERE vclogin = :login', + array(':login' => 'admin'), + array('return_rows' => Database::RETURN_ONE_ROW) + ); + } catch (\Exception $e) { + $this->errors[] = getlocal( + 'Cannot load the main administrator\'s data. Error: {0}', + array($e->getMessage()) + ); + + return false; + } + + if (!$admin) { + $this->errors[] = getlocal('The main administrator has disappeared ' + . 'from the database. Do not know how to continue'); + + return false; + } + + return ($admin['vcpassword'] == md5('')); + } + + /** + * Import all available locales to the database and enable each of them. + * + * @return boolean Indicates if the locales were imported correctly. True if + * everything is OK and false otherwise. + */ + protected function importLocales() + { + if (!($db = $this->getDatabase())) { + return false; + } + + try { + $rows = $db->query( + 'SELECT code FROM {locale}', + null, + array('return_rows' => Database::RETURN_ALL_ROWS) + ); + $exist_locales = array(); + foreach ($rows as $row) { + $exist_locales[] = $row['code']; + } + + $fs_locales = discover_locales(); + foreach ($fs_locales as $locale) { + if (in_array($locale, $exist_locales)) { + // Do not create locales twice. + continue; + } + + $db->query( + 'INSERT INTO {locale} (code, enabled) values (:code, :enabled)', + array( + ':code' => $locale, + // Mark the locale as disabled to indicate that it's + // content is not imported yet. + ':enabled' => 0, + ) + ); + } + } catch (\Exception $e) { + $this->errors[] = getlocal( + 'Cannot import locales. Error: {0}', + array($e->getMessage()) + ); + + return false; + } + + return true; + } + + /** + * Import locales content, namely translations, canned messages and mail + * templates. + * + * When the content will be imported the locale will be marked as enabled. + * @return boolean True if all content was imported successfully and false + * otherwise. + */ + protected function importLocalesContent() + { + if (!($db = $this->getDatabase())) { + return false; + } + + try { + $locales = $db->query( + 'SELECT * FROM {locale} WHERE enabled = :enabled', + array(':enabled' => 0), + array('return_rows' => Database::RETURN_ALL_ROWS) + ); + + foreach ($locales as $locale_info) { + $locale = $locale_info['code']; + + // Import localized messages + import_messages( + $locale, + MIBEW_FS_ROOT . '/locales/' . $locale . '/translation.po', + true + ); + + // Import canned messages + $canned_messages_file = MIBEW_FS_ROOT . '/locales/' . $locale + . '/canned_messages.yml'; + if (is_readable($canned_messages_file)) { + import_canned_messages($locale, $canned_messages_file); + } + + // Import mail templates + $mail_templates_file = MIBEW_FS_ROOT . '/locales/' . $locale + . '/mail_templates.yml'; + if (is_readable($mail_templates_file)) { + import_mail_templates($locale, $mail_templates_file); + } + + // Mark the locale as "enabled" to indicate that all its content + // is imported. + $db->query( + 'UPDATE {locale} SET enabled = :enabled WHERE code = :locale', + array( + ':locale' => $locale, + ':enabled' => 1, + ) + ); + } + } catch (\Exception $e) { + $this->errors[] = getlocal( + 'Cannot import locales content. Error: {0}', + array($e->getMessage()) + ); + + return false; + } + + return true; + } + + /** + * Returns initialized database object. + * + * @return \Mibew\Database|boolean A database class instance or boolean + * false if something went wrong. + */ + protected function getDatabase() + { + if (!Database::isInitialized()) { + try { + Database::initialize( + $this->configs['database']['host'], + $this->configs['database']['login'], + $this->configs['database']['pass'], + $this->configs['database']['use_persistent_connection'], + $this->configs['database']['db'], + $this->configs['database']['tables_prefix'] + ); + } catch(\PDOException $e) { + $this->errors[] = getlocal( + "Could not connect. Please check server settings in config.php. Error: {0}", + array($e->getMessage()) + ); + + return false; + } + } + + $db = Database::getInstance(); + $db->throwExeptions(true); + + return $db; + } + + /** + * Loads database schema. + * + * @return array Associative array of database schema. Each key of the array + * is a table name and each value is its description. Table array itself + * is an associative array with the following keys: + * - fields: An associative array, which keys are MySQL columns names + * and values are columns definitions. + * - unique_keys: An associative array. Each its value is a name of a + * table's unique key. Each value is an array with names of the + * columns the key is based on. + * - indexes: An associative array. Each its value is a name of a + * table's index. Each value is an array with names of the + * columns the index is based on. + */ + protected function getDatabaseSchema() + { + return $this->parser->parse(file_get_contents(MIBEW_FS_ROOT . '/libs/database_schema.yml')); + } + + /** + * Loads available canned messages for specified locale. + * + * @param string $locale Locale code. + * @return string[]|boolean List of canned messages boolean false if + * something went wrong. + */ + protected function getCannedMessages($locale) + { + $file_path = MIBEW_FS_ROOT . '/locales/' . $locale . '/canned_messages.yml'; + if (!is_readable($file_path)) { + return false; + } + $messages = $this->parser->parse(file_get_contents($file_path)); + + return $messages ? $messages : false; + } + + /** + * Loads available mail templates for the specified locale. + * + * @param string $locale Locale code. + * @return array|boolean List of mail template arrays or boolean false if + * something went wrong. + */ + protected function getMailTemplates($locale) + { + $file_path = MIBEW_FS_ROOT . '/locales/' . $locale . '/mail_templates.yml'; + if (!is_readable($file_path)) { + return false; + } + $templates = $this->parser->parse(file_get_contents($file_path)); + + return $templates ? $templates : false; + } +} diff --git a/src/mibew/libs/classes/Mibew/Routing/RouteCollectionLoader.php b/src/mibew/libs/classes/Mibew/Routing/RouteCollectionLoader.php index 4b0774a9..56fa1d18 100644 --- a/src/mibew/libs/classes/Mibew/Routing/RouteCollectionLoader.php +++ b/src/mibew/libs/classes/Mibew/Routing/RouteCollectionLoader.php @@ -38,10 +38,15 @@ class RouteCollectionLoader */ const ROUTES_PLUGINS = 2; + /** + * Indicates that only routes related with installation should be loaded. + */ + const ROUTES_INSTALLATION = 4; + /** * Indicates that all available routes should be loaded. */ - const ROUTES_ALL = 3; + const ROUTES_ALL = 7; /** * @var YamlFileLoader|null @@ -72,6 +77,11 @@ class RouteCollectionLoader $collection->addCollection($this->loadCoreRoutes()); } + // Load installation routes if needed + if ($type & self::ROUTES_INSTALLATION) { + $collection->addCollection($this->loadInstallationRoutes()); + } + // Load plugins routes if needed if ($type & self::ROUTES_PLUGINS) { $collection->addCollection($this->loadPluginRoutes()); @@ -95,6 +105,17 @@ class RouteCollectionLoader return $this->loader->load('libs/routing.yml'); } + /** + * Loads routes related with installation process. + * + * @return RouteCollection + * @throws \RuntimeException If core installation routing file is not found. + */ + protected function loadInstallationRoutes() + { + return $this->loader->load('libs/routing_install.yml'); + } + /** * Loads plugins' routes. * diff --git a/src/mibew/libs/common/constants.php b/src/mibew/libs/common/constants.php index 7bb5aa5c..4d180167 100644 --- a/src/mibew/libs/common/constants.php +++ b/src/mibew/libs/common/constants.php @@ -23,7 +23,7 @@ define('MIBEW_VERSION', '2.0'); /** * Current version of database structure */ -define('DB_VERSION', '2.0'); +define('DB_VERSION', 20000); /** * Current version of implemented features diff --git a/src/mibew/libs/common/string.php b/src/mibew/libs/common/string.php index e1fb6a9b..32e5b5be 100644 --- a/src/mibew/libs/common/string.php +++ b/src/mibew/libs/common/string.php @@ -167,3 +167,28 @@ function safe_htmlspecialchars($string) $string = preg_replace('/[\x00-\x08\x0b\x0c\x0e-\x1f]/', '', $string); return htmlspecialchars($string, ENT_QUOTES); } + +/** + * Converts version ID to human readable representation. + * + * Example of usage: + * + * $version = 50303; + * echo(format_version_id($version)); // Outputs "5.3.3" + * + * + * @param int $version_id Version ID + * @return string Human readable version. + */ +function format_version_id($version_id) +{ + $parts = array(); + $tmp = (int)$version_id; + + for ($i = 0; $i < 3; $i++) { + $parts[] = $tmp % 100; + $tmp = floor($tmp / 100); + } + + return implode('.', array_reverse($parts)); +} diff --git a/src/mibew/libs/database_schema.yml b/src/mibew/libs/database_schema.yml new file mode 100644 index 00000000..368c32df --- /dev/null +++ b/src/mibew/libs/database_schema.yml @@ -0,0 +1,284 @@ +# This file contains current database schema that is used for installation. +# Do not change anything in this file unless you know what you are doing! + +# Contains information about chat groups +chatgroup: + fields: + groupid: "int NOT NULL auto_increment PRIMARY KEY" + parent: "int DEFAULT NULL" + vcemail: "varchar(64)" + vclocalname: "varchar(64) NOT NULL" + vccommonname: "varchar(64) NOT NULL" + vclocaldescription: "varchar(1024) NOT NULL" + vccommondescription: "varchar(1024) NOT NULL" + iweight: "int NOT NULL DEFAULT 0" + vctitle: "varchar(255) DEFAULT ''" + vcchattitle: "varchar(255) DEFAULT ''" + vclogo: "varchar(255) DEFAULT ''" + vchosturl: "varchar(255) DEFAULT ''" + indexes: + parent: [parent] + +# Contains info about chat threads +chatthread: + fields: + # ID of the thread. + threadid: "int NOT NULL auto_increment PRIMARY KEY" + # Name of the user in chat. + userName: "varchar(64) NOT NULL" + # ID of the user. This field is foreign key for {chatsitevisitor}.userid + userid: "varchar(255)" + # Name of the operator who took place in the chat. + agentName: "varchar(64)" + # ID of the operator who took place in the chat. + agentId: "int NOT NULL DEFAULT 0" + # Unix timestamp of the moment when the thread was created. + dtmcreated: "int NOT NULL DEFAULT 0" + # Unix timestamp of the moment when chat actually started. + dtmchatstarted: "int NOT NULL DEFAULT 0" + # Unix timestamp of the last thread modification. + dtmmodified: "int NOT NULL DEFAULT 0" + # Unix timestamp of the moment when the thread was closed. + dtmclosed: "int NOT NULL DEFAULT 0" + # ID of the last thread revision. + lrevision: "int NOT NULL DEFAULT 0" + # State of the thread. It is one of Thread::STATE_* constants. + istate: "int NOT NULL DEFAULT 0" + # State of invitation related with the thread. It is one of + # Thread::INVITATION_* constants. + invitationstate: "int NOT NULL DEFAULT 0" + # Last token of the thread. + ltoken: "int NOT NULL" + # IP address of the user. + remote: "varchar(255)" + # Page from which chat thread was started. + referer: "text" + # ID of the operator who will next in the chat. + nextagent: "int NOT NULL DEFAULT 0" + # Code of chat locale. + locale: "varchar(8)" + # Unix timestamp of the last request from user's window to server. + lastpinguser: "int NOT NULL DEFAULT 0" + # Unix timestamp of the last request from operator's window to server. + lastpingagent: "int NOT NULL DEFAULT 0" + # Indicates if user typing or not. It can take two values 0 and 1. + userTyping: "int DEFAULT 0" + # Indicates if operator typing or not. It can take two values 0 and 1. + agentTyping: "int DEFAULT 0" + # ID of shown message in the chat. + shownmessageid: "int NOT NULL DEFAULT 0" + # User agent description that took from 'User-Agent' HTTP header. + userAgent: "varchar(255)" + # Total count of user's messages related with the thread. + messageCount: "varchar(16)" + # ID of the group at Mibew side related with the thread. + groupid: "int references {chatgroup}(groupid)" + +# Contains "by thread" statistics +chatthreadstatistics: + fields: + statid: "int NOT NULL auto_increment PRIMARY KEY" + date: "int NOT NULL DEFAULT 0" + threads: "int NOT NULL DEFAULT 0" + missedthreads: "int NOT NULL DEFAULT 0" + sentinvitations: "int NOT NULL DEFAULT 0" + acceptedinvitations: "int NOT NULL DEFAULT 0" + rejectedinvitations: "int NOT NULL DEFAULT 0" + ignoredinvitations: "int NOT NULL DEFAULT 0" + operatormessages: "int NOT NULL DEFAULT 0" + usermessages: "int NOT NULL DEFAULT 0" + averagewaitingtime: "FLOAT(10, 1) NOT NULL DEFAULT 0" + averagechattime: "FLOAT(10, 1) NOT NULL DEFAULT 0" + +requestbuffer: + fields: + requestid: "int NOT NULL auto_increment PRIMARY KEY" + # Use MD5 hashes as keys + requestkey: "char(32) NOT NULL" + request: "text NOT NULL" + indexes: + requestkey: [requestkey] + +requestcallback: + fields: + callbackid: "int NOT NULL auto_increment PRIMARY KEY" + token: "varchar(64) NOT NULL DEFAULT ''" + function: "varchar(64) NOT NULL" + arguments: "varchar(1024)" + indexes: + token: [token] + +# Contains updated translations +translation: + fields: + stringid: "int NOT NULL auto_increment PRIMARY KEY" + locale: "varchar(5) NOT NULL" + context: "varchar(256) NOT NULL DEFAULT ''" + source: "text COLLATE utf8_bin" + translation: "text" + +# Contains locales info +locale: + fields: + # Artificial primary key + localeid: "int NOT NULL auto_increment PRIMARY KEY" + # Locale code + code: "varchar(5) NOT NULL" + # Indicates if a locale is enabled or not. + enabled: "tinyint NOT NULL DEFAULT 0" + +# Contains localized mail templates +mailtemplate: + fields: + # Artificial primary key + templateid: "int NOT NULL auto_increment PRIMARY KEY" + # Locale code a template belongs to + locale: "varchar(5) NOT NULL" + # Machine name of a template + name: "varchar(256) NOT NULL" + # Mail subject + subject: "varchar(1024) NOT NULL" + # Mail body + body: "text" + +# Store chat thread messages +chatmessage: + fields: + # Message ID. + messageid: "int NOT NULL auto_increment PRIMARY KEY" + # ID of the thread related with the message. + threadid: "int NOT NULL references {chatthread}(threadid)" + # Message kind. It is one of Thread::KIND_* constants. + ikind: "int NOT NULL" + # ID of operator who sent the message. This value will be ignored for + # system messages and messages which sent by users. + agentId: "int NOT NULL DEFAULT 0" + # Message text body. + tmessage: "text NOT NULL" + # Name of the plugin which sent the message. If message was not sent by + # a plugin this field equals to an empty string. + plugin: "varchar(256) NOT NULL DEFAULT ''" + # Arbitrary serialized data related with message. + data: "text" + # Unix timestamp when message was created. + dtmcreated: "int NOT NULL DEFAULT 0" + # Name of the message sender. + tname: "varchar(64)" + indexes: + idx_agentid: [agentid] + +# Contains info about operators +chatoperator: + fields: + operatorid: "int NOT NULL auto_increment PRIMARY KEY" + vclogin: "varchar(64) NOT NULL" + vcpassword: "varchar(64) NOT NULL" + vclocalename: "varchar(64) NOT NULL" + vccommonname: "varchar(64) NOT NULL" + vcemail: "varchar(64)" + dtmlastvisited: "int NOT NULL DEFAULT 0" + # Current status of an operator: 0 - online, 1 - away + istatus: "int DEFAULT 0" + idisabled: "int DEFAULT 0" + vcavatar: "varchar(255)" + vcjabbername: "varchar(255)" + # Operators privileges bitmask. + iperm: "int DEFAULT 0" + dtmrestore: "int NOT NULL DEFAULT 0" + vcrestoretoken: "varchar(64)" + # Use to start chat with specified operator. + code: "varchar(64) DEFAULT ''" + +# Contains "by operator" statistics +chatoperatorstatistics: + fields: + statid: "int NOT NULL auto_increment PRIMARY KEY" + date: "int NOT NULL DEFAULT 0" + operatorid: "int NOT NULL" + threads: "int NOT NULL DEFAULT 0" + messages: "int NOT NULL DEFAULT 0" + averagelength: "FLOAT(10, 1) NOT NULL DEFAULT 0" + sentinvitations: "int NOT NULL DEFAULT 0" + acceptedinvitations: "int NOT NULL DEFAULT 0" + rejectedinvitations: "int NOT NULL DEFAULT 0" + ignoredinvitations: "int NOT NULL DEFAULT 0" + indexes: + operatorid: [operatorid] + +chatrevision: + fields: + id: "INT NOT NULL" + +# Contains relations between operators and groups +chatgroupoperator: + fields: + groupid: "int NOT NULL references {chatgroup}(groupid)" + operatorid: "int NOT NULL references {chatoperator}(operatorid)" + indexes: + groupid: [groupid] + operatorid: [operatorid] + +# Contains banned visitors +chatban: + fields: + banid: "INT NOT NULL auto_increment PRIMARY KEY" + dtmcreated: "int NOT NULL DEFAULT 0" + dtmtill: "int NOT NULL DEFAULT 0" + address: "varchar(255)" + comment: "varchar(255)" + blockedCount: "int DEFAULT 0" + +# Contains dynamic configs +chatconfig: + fields: + id: "INT NOT NULL auto_increment PRIMARY KEY" + vckey: "varchar(255)" + vcvalue: "varchar(255)" + +# Contains canned messages +chatresponses: + fields: + id: "INT NOT NULL auto_increment PRIMARY KEY" + locale: "varchar(8)" + groupid: "int references {chatgroup}(groupid)" + vctitle: "varchar(100) NOT NULL DEFAULT ''" + vcvalue: "varchar(1024) NOT NULL" + +chatsitevisitor: + fields: + visitorid: "INT NOT NULL auto_increment PRIMARY KEY" + userid: "varchar(255) NOT NULL" + username: "varchar(64)" + firsttime: "int NOT NULL DEFAULT 0" + lasttime: "int NOT NULL DEFAULT 0" + entry: "text NOT NULL" + details: "text NOT NULL" + invitations: "INT NOT NULL DEFAULT 0" + chats: "INT NOT NULL DEFAULT 0" + threadid: "INT references {chatthread}(threadid) on delete set null" + indexes: + threadid: [threadid] + +visitedpage: + fields: + pageid: "INT NOT NULL auto_increment PRIMARY KEY" + address: "varchar(1024)" + visittime: "int NOT NULL DEFAULT 0" + visitorid: "INT" + # Indicates if path included in 'by page' statistics + calculated: "tinyint NOT NULL DEFAULT 0" + indexes: + visitorid: [visitorid] + +# Contains "by page" statistics +visitedpagestatistics: + fields: + pageid: "INT NOT NULL auto_increment PRIMARY KEY" + date: "int NOT NULL DEFAULT 0" + address: "varchar(1024)" + visits: "int NOT NULL DEFAULT 0" + chats: "int NOT NULL DEFAULT 0" + sentinvitations: "int NOT NULL DEFAULT 0" + acceptedinvitations: "int NOT NULL DEFAULT 0" + rejectedinvitations: "int NOT NULL DEFAULT 0" + ignoredinvitations: "int NOT NULL DEFAULT 0" diff --git a/src/mibew/libs/routing_install.yml b/src/mibew/libs/routing_install.yml new file mode 100644 index 00000000..90ea3289 --- /dev/null +++ b/src/mibew/libs/routing_install.yml @@ -0,0 +1,9 @@ +install: + path: /install + defaults: + _controller: Mibew\Controller\InstallController::indexAction + +install_create_tables: + path: /install/create-tables + defaults: + _controller: Mibew\Controller\InstallController::createTablesAction