From bd75f98e451ac560c61a54ec363aa165b183e63d Mon Sep 17 00:00:00 2001
From: Kevin Duret <kduret@centreon.com>
Date: Wed, 5 Apr 2017 13:43:55 +0200
Subject: [PATCH] add kb migration script

---
 bin/migrateWikiPages.php                      |  64 ++++++
 www/api/class/centreon_wiki.class.php         |  99 +--------
 www/class/centreon-knowledge/wiki.class.php   |  61 ++----
 .../centreon-knowledge/wikiApi.class.php      | 198 +++++++++++++++++-
 .../configKnowledge/display-hostTemplates.php |  17 +-
 .../display-serviceTemplates.php              |  15 +-
 6 files changed, 294 insertions(+), 160 deletions(-)
 create mode 100644 bin/migrateWikiPages.php

diff --git a/bin/migrateWikiPages.php b/bin/migrateWikiPages.php
new file mode 100644
index 0000000000..5354358a50
--- /dev/null
+++ b/bin/migrateWikiPages.php
@@ -0,0 +1,64 @@
+<?php
+/*
+ * Copyright 2005-2017 Centreon
+ * Centreon is developped by : Julien Mathis and Romain Le Merlus under
+ * GPL Licence 2.0.
+ *
+ * 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 2 of the License.
+ *
+ * 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>.
+ *
+ * Linking this program statically or dynamically with other modules is making a
+ * combined work based on this program. Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this program give Centreon
+ * permission to link this program with independent modules to produce an executable,
+ * regardless of the license terms of these independent modules, and to copy and
+ * distribute the resulting executable under terms of Centreon choice, provided that
+ * Centreon also meet, for each linked independent module, the terms  and conditions
+ * of the license of that module. An independent module is a module which is not
+ * derived from this program. If you modify this program, you may extend this
+ * exception to your version of the program, but you are not obliged to do so. If you
+ * do not wish to do so, delete this exception statement from your version.
+ *
+ * For more information : contact@centreon.com
+ *
+ */
+
+require_once(realpath(dirname(__FILE__) . '/../config/centreon.config.php'));
+require_once _CENTREON_PATH_ . '/www/class/centreonDB.class.php';
+require_once _CENTREON_PATH_ . '/www/class/centreon-knowledge/wikiApi.class.php';
+
+$wikiApi = new WikiApi();
+$pages = $wikiApi->getAllPages();
+
+foreach ($pages as $page) {
+    $newName = '';
+    if (preg_match('/Host\:(.+)/', $page, $matches)) {
+        $newName = 'Host : ' . $matches[1];
+    } elseif (preg_match('/Host-Template\:(.+)/', $page, $matches)){
+        $newName = 'Host-Template : ' . $matches[1];
+    } elseif (preg_match('/Service\:(.+)/', $page, $matches)){
+        $name = explode(' ', $matches[1]);
+        if (count($name) > 1) {
+            $hostName = array_shift($name);
+            $serviceName = implode(' ', $name);
+            $newName = 'Service : ' . $hostName . ' / ' . $serviceName;
+        }
+    } elseif (preg_match('/Service-Template\:(.+)/', $page, $matches)){
+        $newName = 'Service-Template : ' . $matches[1];
+    }
+
+    if (!empty($newName)) {
+        $newName = str_replace(' ', '_', $newName);
+        $wikiApi->movePage($page, $newName);
+    }
+}
\ No newline at end of file
diff --git a/www/api/class/centreon_wiki.class.php b/www/api/class/centreon_wiki.class.php
index e8cea2e435..e189308945 100644
--- a/www/api/class/centreon_wiki.class.php
+++ b/www/api/class/centreon_wiki.class.php
@@ -34,7 +34,7 @@
  */
 
 require_once _CENTREON_PATH_ . "/www/class/centreonDB.class.php";
-require_once _CENTREON_PATH_ . "/www/include/configuration/configKnowledge/functions.php";
+require_once _CENTREON_PATH_ . "/www/class/centreon-knowledge/wikiApi.class.php";
 require_once dirname(__FILE__) . "/webService.class.php";
 
 class CentreonWiki extends CentreonWebService
@@ -73,102 +73,11 @@ class CentreonWiki extends CentreonWebService
 
     public function postDeletePage()
     {
-        // get wiki info
-        $conf = getWikiConfig($this->pearDB);
-        $apiWikiURL = $conf['kb_wiki_url'] . '/api.php';
-        $wikiVersion = getWikiVersion($apiWikiURL);
-        $login = $conf['kb_wiki_account'];
-        $pass = $conf['kb_wiki_password'];
-        $title = $this->arguments['title'];
-
-        $path_cookie = '/tmp/temporary_wiki_connection.txt';
-        if (!file_exists($path_cookie)) {
-            touch($path_cookie);
-        }
-
-        // Get Connection Cookie/Token
-        $postfields = array(
-            'action' => 'login',
-            'format' => 'json',
-            'lgname' => $login,
-            'lgpassword' => $pass
-        );
-
-        $curl = curl_init();
-
-        curl_setopt($curl, CURLOPT_URL, $apiWikiURL);
-        curl_setopt($curl, CURLOPT_COOKIESESSION, true);
-        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
-        curl_setopt($curl, CURLOPT_POST, true);
-        curl_setopt($curl, CURLOPT_POSTFIELDS, $postfields);
-        curl_setopt($curl, CURLOPT_COOKIEJAR, $path_cookie); // you put your cookie in the file
-        $connexion = curl_exec($curl);
-        $json_connexion = json_decode($connexion, true);
-        $tokenConnexion = $json_connexion['login']['token'];
-        // you take the token and keep it in a var for your second login
-
-        // /!\ don't close the curl connection or initialize a new one or your session id will change !
-
-        // Launch Connection
-        $postfields = array(
-            'action' => 'login',
-            'format' => 'json',
-            'lgtoken' => $tokenConnexion,
-            'lgname' => $login,
-            'lgpassword' => $pass
-        );
-        curl_setopt($curl, CURLOPT_POSTFIELDS, $postfields);
-        $connexionToken = curl_exec($curl);
-        $json_connexion = json_decode($connexionToken, true);
-        $resultLogin = $json_connexion['login']['result'];
-
-        if ($resultLogin != 'Success') {
-            return array(
-                'result' => $resultLogin
-            );
-        }
-
-        // Get Delete Token
-        if ($wikiVersion >= 1.20) {
-            $postfields = array(
-                'action' => 'tokens',
-                'type' => 'delete',
-                'format' => 'json'
-            );
-        } else {
-            $postfields = array(
-                'action' => 'query',
-                'prop' => 'info',
-                'intoken' => 'delete',
-                'format' => 'json',
-                'titles' => $title
-            );
-        }
-        curl_setopt($curl, CURLOPT_POSTFIELDS, $postfields);
-        $deleteToken = curl_exec($curl);
-        $json_delete = json_decode($deleteToken, true);
-
-        if ($wikiVersion >= 1.20) {
-            $tokenDelete = $json_delete['tokens']['deletetoken'];
-        } else {
-            $page = array_pop($json_delete['query']['pages']);
-            $tokenDelete = $page['deletetoken'];
-        }
-
-        // Delete Page
-        $postfields = array(
-            'action' => 'delete',
-            'title' => $title,
-            'token' => $tokenDelete
-        );
-        curl_setopt($curl, CURLOPT_POSTFIELDS, $postfields);
-        curl_exec($curl);
-
-        // close the curl connection
-        curl_close($curl);
+        $wikiApi = new WikiApi();
+        $result =  $wikiApi->deletePage($this->arguments['title']);
 
         return array(
-            'result' => 'delete'
+            'result' => $result
         );
     }
 }
diff --git a/www/class/centreon-knowledge/wiki.class.php b/www/class/centreon-knowledge/wiki.class.php
index 7039fd02fa..e5f873521a 100644
--- a/www/class/centreon-knowledge/wiki.class.php
+++ b/www/class/centreon-knowledge/wiki.class.php
@@ -39,7 +39,7 @@ require_once _CENTREON_PATH_ . "/www/class/centreonDB.class.php";
 class Wiki
 {
     private $db;
-    private $config;
+    private $config = null;
 
     /**
      * WikiApi constructor.
@@ -52,59 +52,26 @@ class Wiki
 
     public function getWikiConfig()
     {
-        $res = $this->db->query("SELECT * FROM `options` WHERE options.key LIKE 'kb_%'");
-        while ($opt = $res->fetchRow()) {
-            $gopt[$opt["key"]] = html_entity_decode($opt["value"], ENT_QUOTES, "UTF-8");
+        if (!is_null($this->config)) {
+            return $this->config;
         }
 
-        $pattern = '#^http://|https://#';
-        $WikiURL = $gopt['kb_wiki_url'];
-        $checkWikiUrl = preg_match($pattern, $WikiURL);
+        $options = array();
 
-        if (!$checkWikiUrl) {
-            $gopt['kb_wiki_url'] = 'http://' . $WikiURL;
+        $res = $this->db->query("SELECT * FROM `options` WHERE options.key LIKE 'kb_%'");
+        while ($opt = $res->fetchRow()) {
+            $options[$opt["key"]] = html_entity_decode($opt["value"], ENT_QUOTES, "UTF-8");
         }
-
         $res->free();
 
-        return $gopt;
-    }
-
-    public function getWikiUrl()
-    {
-        return $this->config['kb_wiki_url'];
-    }
-
-
-    function getWikiVersion()
-    {
-        $post = array(
-            'action' => 'query',
-            'meta' => 'siteinfo',
-            'format' => 'json',
-        );
-
-        $data = http_build_query($post);
-
-        $httpOpts = array(
-            'http' => array(
-                'method' => 'POST',
-                'header' => "Content-type: application/x-www-form-urlencoded",
-                'content' => $data,
-            )
-        );
-
-        /* Create context */
-        $httpContext = stream_context_create($httpOpts);
-
-        /* Get contents */
-        $content = @file_get_contents($this->config['kb_wiki_url'], false, $httpContext);
-        $content = json_decode($content);
+        if (!count($options)) {
+            throw new \Exception('Wiki is not configured.');
+        }
 
-        $wikiStringVersion = $content->query->general->generator;
-        $wikiDataVersion = explode(' ', $wikiStringVersion);
-        $wikiVersion = (float)$wikiDataVersion[1];
+        if (!preg_match('#^http://|https://#',  $options['kb_wiki_url'])) {
+            $options['kb_wiki_url'] = 'http://' .  $options['kb_wiki_url'];
+        }
 
-        return $wikiVersion;
+        return $options;
     }
 }
diff --git a/www/class/centreon-knowledge/wikiApi.class.php b/www/class/centreon-knowledge/wikiApi.class.php
index bdab07abdd..01f2d4a106 100644
--- a/www/class/centreon-knowledge/wikiApi.class.php
+++ b/www/class/centreon-knowledge/wikiApi.class.php
@@ -42,7 +42,11 @@ class WikiApi
 {
     private $db;
     private $wikiObj;
-    private $wikiUrl;
+    private $url;
+    private $username;
+    private $password;
+    private $version;
+    private $curl;
 
     /**
      * WikiApi constructor.
@@ -51,7 +55,195 @@ class WikiApi
     {
         $this->db = new CentreonDB();
         $this->wikiObj = new Wiki();
-        $this->wikiUrl = $this->wikiObj->getWikiUrl();
+        $config = $this->wikiObj->getWikiConfig();
+        $this->url = $config['kb_wiki_url'] . '/api.php';
+        $this->username = $config['kb_wiki_account'];
+        $this->password = $config['kb_wiki_password'];
+        $this->curl = $this->getCurl();
+        $this->version = $this->getWikiVersion();
+    }
+
+    private function getCurl()
+    {
+        $curl = curl_init();
+
+        curl_setopt($curl, CURLOPT_URL, $this->url);
+        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
+        curl_setopt($curl, CURLOPT_POST, true);
+
+        return $curl;
+    }
+
+    function getWikiVersion()
+    {
+        $postfields = array(
+            'action' => 'query',
+            'meta' => 'siteinfo',
+            'format' => 'json',
+        );
+
+        curl_setopt($this->curl, CURLOPT_POSTFIELDS, $postfields);
+        $result = curl_exec($this->curl);
+        $result = json_decode($result, true);
+
+        $version = $result['query']['general']['generator'];
+        $version = explode(' ', $version);
+        return (float)$version[1];
+    }
+
+    public function login()
+    {
+        // Get Connection Cookie/Token
+        $postfields = array(
+            'action' => 'login',
+            'format' => 'json',
+            'lgname' => $this->username,
+            'lgpassword' => $this->password
+        );
+
+        curl_setopt($this->curl, CURLOPT_POSTFIELDS, $postfields);
+        $result = curl_exec($this->curl);
+        $result = json_decode($result, true);
+        $token = $result['login']['lgtoken'];
+
+        // Launch Connection
+        $postfields['lgtoken'] = $token;
+
+        curl_setopt($this->curl, CURLOPT_POSTFIELDS, $postfields);
+        curl_setopt($this->curl, CURLOPT_HEADER, true);
+        $result = curl_exec($this->curl);
+        curl_setopt($this->curl, CURLOPT_HEADER, false);
+
+        $header_size = curl_getinfo($this->curl, CURLINFO_HEADER_SIZE);
+        $header = substr($result, 0, $header_size);
+        $body = substr($result, $header_size);
+
+        // Get cookies
+        preg_match_all('/^Set-Cookie:\s*([^;]*)/mi', $header, $matches);
+        $cookies = implode(';', $matches[1]);
+        curl_setopt($this->curl, CURLOPT_COOKIE, $cookies);
+
+        $result = json_decode($body, true);
+        $resultLogin = $result['login']['result'];
+
+        $login = false;
+        if ($resultLogin == 'Success') {
+            $login = true;
+        }
+
+        return $login;
+    }
+
+    public function logout()
+    {
+        $postfields = array(
+            'action' => 'logout'
+        );
+
+        curl_setopt($this->curl, CURLOPT_POSTFIELDS, $postfields);
+        curl_exec($this->curl);
+    }
+
+    public function getMethodToken($method = 'delete', $title = '')
+    {
+        if ($this->version >= 1.24) {
+            $postfields = array(
+                'action' => 'query',
+                'meta' => 'tokens',
+                'type' => 'csrf',
+                'format' => 'json'
+            );
+        } elseif ($this->version >= 1.20) {
+            $postfields = array(
+                'action' => 'tokens',
+                'type' => $method,
+                'format' => 'json'
+            );
+        } else {
+            $postfields = array(
+                'action' => 'query',
+                'prop' => 'info',
+                'intoken' => $method,
+                'format' => 'json',
+                'titles' => $title
+            );
+        }
+
+        curl_setopt($this->curl, CURLOPT_POSTFIELDS, $postfields);
+        $result = curl_exec($this->curl);
+        $result = json_decode($result, true);
+
+        if ($this->version >= 1.24) {
+            $methodToken = $result['query']['tokens']['csrftoken'];
+        } elseif ($this->version >= 1.20) {
+            $methodToken = $result['tokens'][$method . 'token'];
+        } else {
+            $page = array_pop($result['query']['pages']);
+            $methodToken = $page[$method . 'token'];
+        }
+
+        return $methodToken;
+    }
+
+    public function movePage($oldTitle = '', $newTitle = '')
+    {
+        $this->login();
+
+        $token = $this->getMethodToken('move', $oldTitle);
+
+        $postfields = array(
+            'action' => 'move',
+            'from' => $oldTitle,
+            'to' => $newTitle,
+            'token' => $token
+        );
+
+        curl_setopt($this->curl, CURLOPT_POSTFIELDS, $postfields);
+        curl_exec($this->curl);
+
+        $this->logout();
+
+        return true;
+    }
+
+    public function deletePage($title = '')
+    {
+        $this->login();
+
+        $token = $this->getMethodToken('delete', $title);
+
+        $postfields = array(
+            'action' => 'delete',
+            'title' => $title,
+            'token' => $token
+        );
+
+        curl_setopt($this->curl, CURLOPT_POSTFIELDS, $postfields);
+        curl_exec($this->curl);
+
+        $this->logout();
+
+        return true;
+    }
+
+    public function getAllPages()
+    {
+        $postfields = array(
+            'format' => 'json',
+            'action' => 'query',
+            'list' => 'allpages'
+        );
+
+        curl_setopt($this->curl, CURLOPT_POSTFIELDS, $postfields);
+        $result = curl_exec($this->curl);
+        $result = json_decode($result);
+
+        $pages = array();
+        foreach ($result->query->allpages as $page) {
+            $pages[] = $page->title;
+        }
+
+        return $pages;
     }
 
     /**
@@ -61,7 +253,7 @@ class WikiApi
     public function getChangedPages($count = 50)
     {
         // Connecting to Mediawiki API
-        $apiUrl = $this->wikiUrl . '/api.php?format=json&action=query&list=recentchanges' .
+        $apiUrl = $this->url . '/api.php?format=json&action=query&list=recentchanges' .
             '&rclimit=' . $count . '&rcprop=title&rctype=new|edit';
 
         // Sending request
diff --git a/www/include/configuration/configKnowledge/display-hostTemplates.php b/www/include/configuration/configKnowledge/display-hostTemplates.php
index 4e21775be9..4a6580fff0 100644
--- a/www/include/configuration/configKnowledge/display-hostTemplates.php
+++ b/www/include/configuration/configKnowledge/display-hostTemplates.php
@@ -118,10 +118,11 @@ $proc = new procedures(
 $proc->setHostInformations();
 $proc->setServiceInformations();
 
-$query = "SELECT SQL_CALC_FOUND_ROWS host_name, host_id, host_register, ehi_icon_image
-              FROM host, extended_host_information ehi
-              WHERE host.host_id = ehi.host_host_id
-			  AND host.host_register = '0' ";
+$query = "SELECT SQL_CALC_FOUND_ROWS host_name, host_id, host_register, ehi_icon_image " .
+    "FROM host, extended_host_information ehi " .
+    "WHERE host.host_id = ehi.host_host_id " .
+    "AND host.host_register = '0' " .
+    "AND host.host_locked = '0' ";
 if (isset($_REQUEST['searchHostTemplate']) && $_REQUEST['searchHostTemplate']) {
     $query .= " AND host.host_name LIKE '%" . $_REQUEST['searchHostTemplate'] . "%' ";
 }
@@ -176,12 +177,12 @@ foreach ($selection as $key => $value) {
         $firstTpl = 1;
         foreach ($tplArr as $key1 => $value1) {
             if ($firstTpl) {
-                $tplStr .= "<a href='" . $WikiURL . "/index.php?title=Host-Template:$value1' target='_blank'>" .
-                    $value1 . "</a>";
+                $tplStr .= " <a href='" . $WikiURL . "/index.php?title=Host-Template:$value1' target = '_blank' > " .
+                    $value1 . "</a > ";
                 $firstTpl = 0;
             } else {
-                $tplStr .= "&nbsp;|&nbsp;<a href='" . $WikiURL .
-                    "/index.php?title=Host-Template:$value1' target='_blank'>" . $value1 . "</a>";
+                $tplStr .= "&nbsp;|&nbsp;<a href = '" . $WikiURL .
+                    "/index.php?title=Host-Template:$value1' target = '_blank' > " . $value1 . "</a > ";
             }
         }
     }
diff --git a/www/include/configuration/configKnowledge/display-serviceTemplates.php b/www/include/configuration/configKnowledge/display-serviceTemplates.php
index 712a5d00b0..abcaee13b4 100644
--- a/www/include/configuration/configKnowledge/display-serviceTemplates.php
+++ b/www/include/configuration/configKnowledge/display-serviceTemplates.php
@@ -120,11 +120,12 @@ $proc->setServiceInformations();
 /*
  * Get Services Template Informations
  */
-$query = "SELECT SQL_CALC_FOUND_ROWS service_description, service_id
-              FROM service
-	          WHERE service_register = '0' ";
+$query = "SELECT SQL_CALC_FOUND_ROWS service_description, service_id " .
+    "FROM service " .
+    "WHERE service_register = '0' " .
+    "AND service_locked = '0' ";
 if (isset($_REQUEST['searchServiceTemplate']) && $_REQUEST['searchServiceTemplate']) {
-    $query .= " AND service_description LIKE '%" . $_REQUEST['searchServiceTemplate'] . "%' ";
+    $query .= " AND service_description LIKE ' % " . $_REQUEST['searchServiceTemplate'] . " % ' ";
 }
 $query .= "ORDER BY $orderby $order LIMIT " . $num * $limit . ", " . $limit;
 $DBRESULT = $pearDB->query($query);
@@ -176,11 +177,11 @@ foreach ($selection as $key => $value) {
         foreach ($tplArr as $key1 => $value1) {
             if ($firstTpl) {
                 $tplStr .= "<a href='" . $WikiURL .
-                    "/index.php?title=Service-Template:$value1' target='_blank'>" . $value1 . "</a>";
+                    " / index . php ? title = Service - Template : $value1' target='_blank'>" . $value1 . "</a>";
                 $firstTpl = 0;
             } else {
                 $tplStr .= "&nbsp;|&nbsp;<a href='" . $WikiURL .
-                    "/index.php?title=Service-Template:$value1' target='_blank'>" . $value1 . "</a>";
+                    " / index . php ? title = Service - Template : $value1' target='_blank'>" . $value1 . "</a>";
             }
         }
     }
@@ -194,7 +195,7 @@ if (isset($templateHostArray)) {
     $tpl->assign("templateHostArray", $templateHostArray);
 }
 
-$WikiVersion = getWikiVersion($WikiURL . '/api.php');
+$WikiVersion = getWikiVersion($WikiURL . ' / api . php');
 $tpl->assign("WikiVersion", $WikiVersion);
 $tpl->assign("WikiURL", $WikiURL);
 $tpl->assign("content", $diff);
-- 
GitLab