|
@@ -0,0 +1,293 @@
|
|
|
+<?php
|
|
|
+/* For licensing terms, see /license.txt */
|
|
|
+
|
|
|
+use Chamilo\CoreBundle\Entity\ExtraField;
|
|
|
+use Chamilo\CoreBundle\Entity\ExtraFieldValues;
|
|
|
+use Chamilo\UserBundle\Entity\User;
|
|
|
+
|
|
|
+/**
|
|
|
+ * Class WhispeakAuthPlugin.
|
|
|
+ */
|
|
|
+class WhispeakAuthPlugin extends Plugin
|
|
|
+{
|
|
|
+ const SETTING_ENABLE = 'enable';
|
|
|
+ const SETTING_API_URL = 'api_url';
|
|
|
+ const SETTING_TOKEN = 'token';
|
|
|
+ const SETTING_INSTRUCTION = 'instruction';
|
|
|
+
|
|
|
+ const EXTRAFIELD_AUTH_UID = 'whispeak_auth_uid';
|
|
|
+
|
|
|
+ /**
|
|
|
+ * StudentFollowUpPlugin constructor.
|
|
|
+ */
|
|
|
+ protected function __construct()
|
|
|
+ {
|
|
|
+ parent::__construct(
|
|
|
+ '0.1',
|
|
|
+ 'Angel Fernando Quiroz',
|
|
|
+ [
|
|
|
+ self::SETTING_ENABLE => 'boolean',
|
|
|
+ self::SETTING_API_URL => 'text',
|
|
|
+ self::SETTING_TOKEN => 'text',
|
|
|
+ self::SETTING_INSTRUCTION => 'html',
|
|
|
+ ]
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @return WhispeakAuthPlugin
|
|
|
+ */
|
|
|
+ public static function create()
|
|
|
+ {
|
|
|
+ static $result = null;
|
|
|
+
|
|
|
+ return $result ? $result : $result = new self();
|
|
|
+ }
|
|
|
+
|
|
|
+ public function install()
|
|
|
+ {
|
|
|
+ UserManager::create_extra_field(
|
|
|
+ self::EXTRAFIELD_AUTH_UID,
|
|
|
+ \ExtraField::FIELD_TYPE_TEXT,
|
|
|
+ $this->get_lang('Whispeak uid'),
|
|
|
+ ''
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ public function uninstall()
|
|
|
+ {
|
|
|
+ $extraField = self::getAuthUidExtraField();
|
|
|
+
|
|
|
+ if (empty($extraField)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ $em = Database::getManager();
|
|
|
+
|
|
|
+ $em->createQuery('DELETE FROM ChamiloCoreBundle:ExtraFieldValues efv WHERE efv.field = :field')
|
|
|
+ ->execute(['field' => $extraField]);
|
|
|
+
|
|
|
+ $em->remove($extraField);
|
|
|
+ $em->flush();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @return ExtraField
|
|
|
+ */
|
|
|
+ public static function getAuthUidExtraField()
|
|
|
+ {
|
|
|
+ $em = Database::getManager();
|
|
|
+ $efRepo = $em->getRepository('ChamiloCoreBundle:ExtraField');
|
|
|
+
|
|
|
+ /** @var ExtraField $extraField */
|
|
|
+ $extraField = $efRepo->findOneBy(
|
|
|
+ [
|
|
|
+ 'variable' => self::EXTRAFIELD_AUTH_UID,
|
|
|
+ 'extraFieldType' => ExtraField::USER_FIELD_TYPE,
|
|
|
+ ]
|
|
|
+ );
|
|
|
+
|
|
|
+ return $extraField;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @param int $userId
|
|
|
+ *
|
|
|
+ * @return ExtraFieldValues
|
|
|
+ */
|
|
|
+ public static function getAuthUidValue($userId)
|
|
|
+ {
|
|
|
+ $extraField = self::getAuthUidExtraField();
|
|
|
+ $em = Database::getManager();
|
|
|
+ $efvRepo = $em->getRepository('ChamiloCoreBundle:ExtraFieldValues');
|
|
|
+
|
|
|
+ /** @var ExtraFieldValues $value */
|
|
|
+ $value = $efvRepo->findOneBy(['field' => $extraField, 'itemId' => $userId]);
|
|
|
+
|
|
|
+ return $value;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @param int $userId
|
|
|
+ *
|
|
|
+ * @return bool
|
|
|
+ */
|
|
|
+ public static function checkUserIsEnrolled($userId)
|
|
|
+ {
|
|
|
+ $value = self::getAuthUidValue($userId);
|
|
|
+
|
|
|
+ if (empty($value)) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ return !empty($value->getValue());
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @return string
|
|
|
+ */
|
|
|
+ public static function getEnrollmentUrl()
|
|
|
+ {
|
|
|
+ return api_get_path(WEB_PLUGIN_PATH).'whispeakauth/enrollment.php';
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @param User $user
|
|
|
+ * @param string $filePath
|
|
|
+ *
|
|
|
+ * @return array
|
|
|
+ */
|
|
|
+ public function requestEnrollment(User $user, $filePath)
|
|
|
+ {
|
|
|
+ $metadata = [
|
|
|
+ 'motherTongue' => $user->getLanguage(),
|
|
|
+ 'spokenTongue' => $user->getLanguage(),
|
|
|
+ 'audioType' => 'pcm',
|
|
|
+ ];
|
|
|
+
|
|
|
+ return $this->sendRequest(
|
|
|
+ 'enrollment',
|
|
|
+ $metadata,
|
|
|
+ $user,
|
|
|
+ $filePath
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @param User $user
|
|
|
+ * @param string $uid
|
|
|
+ *
|
|
|
+ * @throws \Doctrine\ORM\OptimisticLockException
|
|
|
+ */
|
|
|
+ public function saveEnrollment(User $user, $uid)
|
|
|
+ {
|
|
|
+ $em = Database::getManager();
|
|
|
+ $value = self::getAuthUidValue($user->getId());
|
|
|
+
|
|
|
+ if (empty($value)) {
|
|
|
+ $ef = self::getAuthUidExtraField();
|
|
|
+ $now = new DateTime('now', new DateTimeZone('UTC'));
|
|
|
+
|
|
|
+ $value = new ExtraFieldValues();
|
|
|
+ $value
|
|
|
+ ->setField($ef)
|
|
|
+ ->setItemId($user->getId())
|
|
|
+ ->setUpdatedAt($now);
|
|
|
+ }
|
|
|
+
|
|
|
+ $value->setValue($uid);
|
|
|
+
|
|
|
+ $em->persist($value);
|
|
|
+ $em->flush();
|
|
|
+ }
|
|
|
+
|
|
|
+ public function requestAuthentify(User $user, $filePath)
|
|
|
+ {
|
|
|
+ $value = self::getAuthUidValue($user->getId());
|
|
|
+
|
|
|
+ if (empty($value)) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ $metadata = [
|
|
|
+ 'uid' => $value->getValue(),
|
|
|
+ 'audioType' => 'pcm',
|
|
|
+ ];
|
|
|
+
|
|
|
+ return $this->sendRequest(
|
|
|
+ 'authentify',
|
|
|
+ $metadata,
|
|
|
+ $user,
|
|
|
+ $filePath
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @return string
|
|
|
+ */
|
|
|
+ public function getAuthentifySampleText()
|
|
|
+ {
|
|
|
+ $phrases = [];
|
|
|
+
|
|
|
+ for ($i = 1; $i <= 6; $i++) {
|
|
|
+ $phrases[] = $this->get_lang("AuthentifySampleText$i");
|
|
|
+ }
|
|
|
+
|
|
|
+ $rand = array_rand($phrases, 1);
|
|
|
+
|
|
|
+ return $phrases[$rand];
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @return bool
|
|
|
+ */
|
|
|
+ public function toolIsEnabled()
|
|
|
+ {
|
|
|
+ return 'true' === $this->get(self::SETTING_ENABLE);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Access not allowed when tool is not enabled.
|
|
|
+ *
|
|
|
+ * @param bool $printHeaders Optional. Print headers.
|
|
|
+ */
|
|
|
+ public function protectTool($printHeaders = true)
|
|
|
+ {
|
|
|
+ if ($this->toolIsEnabled()) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ api_not_allowed($printHeaders);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @return string
|
|
|
+ */
|
|
|
+ private function getApiUrl()
|
|
|
+ {
|
|
|
+ $url = $this->get(self::SETTING_API_URL);
|
|
|
+
|
|
|
+ return trim($url, " \t\n\r \v/");
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @param string $endPoint
|
|
|
+ * @param array $metadata
|
|
|
+ * @param User $user
|
|
|
+ * @param string $filePath
|
|
|
+ *
|
|
|
+ * @return array
|
|
|
+ */
|
|
|
+ private function sendRequest($endPoint, array $metadata, User $user, $filePath)
|
|
|
+ {
|
|
|
+ $moderator = $user->getCreatorId() ?: $user->getId();
|
|
|
+ $apiUrl = $this->getApiUrl()."/$endPoint";
|
|
|
+ $headers = [
|
|
|
+ //"Content-Type: application/x-www-form-urlencoded",
|
|
|
+ "Authorization: Bearer ".$this->get(self::SETTING_TOKEN),
|
|
|
+ ];
|
|
|
+ $post = [
|
|
|
+ 'metadata' => json_encode($metadata),
|
|
|
+ 'moderator' => "moderator_$moderator",
|
|
|
+ 'client' => base64_encode($user->getUserId()),
|
|
|
+ 'voice' => new CURLFile($filePath),
|
|
|
+ ];
|
|
|
+
|
|
|
+ $ch = curl_init();
|
|
|
+ curl_setopt($ch, CURLOPT_URL, $apiUrl);
|
|
|
+ curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
|
|
|
+ curl_setopt($ch, CURLOPT_POST, true);
|
|
|
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
|
|
|
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
|
|
+ $result = curl_exec($ch);
|
|
|
+ curl_close($ch);
|
|
|
+
|
|
|
+ $result = json_decode($result, true);
|
|
|
+
|
|
|
+ if (!empty($result['error'])) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ return json_decode($result, true);
|
|
|
+ }
|
|
|
+}
|