diff --git a/plugin/xapi/install.php b/plugin/xapi/install.php
new file mode 100644
index 0000000000..7629ee9e8a
--- /dev/null
+++ b/plugin/xapi/install.php
@@ -0,0 +1,4 @@
+install();
diff --git a/plugin/xapi/lang/english.php b/plugin/xapi/lang/english.php
new file mode 100644
index 0000000000..0b5c25acf5
--- /dev/null
+++ b/plugin/xapi/lang/english.php
@@ -0,0 +1,14 @@
+This is automatically by Chamilo LMS. Don\'t replace it.';
+$strings[XApiPlugin::SETTING_LRS_URL] = 'LRS: URL for API';
+$strings[XApiPlugin::SETTING_LRS_URL.'_help'] = 'Sets the LRS base URL.';
+$strings[XApiPlugin::SETTING_LRS_AUTH] = 'LRS: Authentication method';
+$strings[XApiPlugin::SETTING_LRS_AUTH.'_help'] = 'Sets HTTP authentication credentials.
';
+$strings[XApiPlugin::SETTING_LRS_AUTH.'_help'] .= 'Choose one auth method: Basic (basic:username:password) or OAuth1 (oauth:key:secret)';
diff --git a/plugin/xapi/plugin.php b/plugin/xapi/plugin.php
new file mode 100644
index 0000000000..0a0b304667
--- /dev/null
+++ b/plugin/xapi/plugin.php
@@ -0,0 +1,4 @@
+get_info();
diff --git a/plugin/xapi/src/XApiPlugin.php b/plugin/xapi/src/XApiPlugin.php
new file mode 100644
index 0000000000..0adfa20b18
--- /dev/null
+++ b/plugin/xapi/src/XApiPlugin.php
@@ -0,0 +1,142 @@
+',
+ ];
+ $settings = [
+ self::SETTING_UUID_NAMESPACE => 'text',
+ self::SETTING_LRS_URL => 'text',
+ self::SETTING_LRS_AUTH => 'text',
+ ];
+
+ parent::__construct(
+ $version,
+ implode(', ', $author),
+ $settings
+ );
+ }
+
+ /**
+ * @return \XApiPlugin
+ */
+ public static function create()
+ {
+ static $result = null;
+
+ return $result ? $result : $result = new self();
+ }
+
+ /**
+ * Process to install plugin.
+ */
+ public function install()
+ {
+ $this->installUuid();
+ }
+
+ /**
+ * @throws \Exception
+ */
+ private function installUuid()
+ {
+ $uuidNamespace = Uuid::uuid1();
+
+ $pluginName = $this->get_name();
+ $urlId = api_get_current_access_url_id();
+
+ api_add_setting(
+ $uuidNamespace,
+ $pluginName.'_'.self::SETTING_UUID_NAMESPACE,
+ $pluginName,
+ 'setting',
+ 'Plugins',
+ $pluginName,
+ '',
+ '',
+ '',
+ $urlId,
+ 1
+ );
+ }
+
+ /**
+ * Process to uninstall plugin.
+ */
+ public function uninstall()
+ {
+ }
+
+ /**
+ * @return \Xabbuh\XApi\Client\Api\StatementsApiClientInterface
+ */
+ public function getXApiStatementClient()
+ {
+ return $this->createXApiClient()->getStatementsApiClient();
+ }
+
+ /**
+ * @return \Xabbuh\XApi\Client\XApiClientInterface
+ */
+ public function createXApiClient()
+ {
+ $baseUrl = trim($this->get(self::SETTING_LRS_URL), "/ \t\n\r\0\x0B");
+
+ $clientBuilder = new XApiClientBuilder();
+ $clientBuilder
+ ->setHttpClient(Client::createWithConfig([RequestOptions::VERIFY => false]))
+ ->setRequestFactory(new GuzzleMessageFactory())
+ ->setBaseUrl($baseUrl);
+
+ return $this
+ ->setAuthMethodToClient($clientBuilder)
+ ->build();
+ }
+
+ /**
+ * @param \Xabbuh\XApi\Client\XApiClientBuilderInterface $clientBuilder
+ *
+ * @return \Xabbuh\XApi\Client\XApiClientBuilderInterface
+ */
+ private function setAuthMethodToClient(XApiClientBuilderInterface $clientBuilder)
+ {
+ $authString = $this->get(self::SETTING_LRS_AUTH);
+
+ $parts = explode(':', $authString);
+
+ if (!empty($parts)) {
+ $method = strtolower($parts[0]);
+
+ switch ($method) {
+ case 'basic':
+ return $clientBuilder->setAuth($parts[1], $parts[2]);
+ case 'oauth':
+ return $clientBuilder->setOAuthCredentials($parts[1], $parts[2]);
+ }
+ }
+
+ return $clientBuilder;
+ }
+}
diff --git a/plugin/xapi/uninstall.php b/plugin/xapi/uninstall.php
new file mode 100644
index 0000000000..3f9ffc97cf
--- /dev/null
+++ b/plugin/xapi/uninstall.php
@@ -0,0 +1,4 @@
+uninstall();