From 85b7f73903dccd2dcc119206487325d5c12bc597 Mon Sep 17 00:00:00 2001 From: Vincent Vanwaelscappel Date: Fri, 19 Nov 2021 10:59:26 +0100 Subject: [PATCH] wip #4891 @1 --- .../FluidbookCollection/DownloadOperation.php | 5 +- app/Models/FluidbookCollection.php | 78 +++++++++++++ app/Services/WorkshopV2.php | 109 ++++++++++++------ 3 files changed, 153 insertions(+), 39 deletions(-) diff --git a/app/Http/Controllers/Admin/Operations/FluidbookCollection/DownloadOperation.php b/app/Http/Controllers/Admin/Operations/FluidbookCollection/DownloadOperation.php index c41ccda64..81f6e3892 100644 --- a/app/Http/Controllers/Admin/Operations/FluidbookCollection/DownloadOperation.php +++ b/app/Http/Controllers/Admin/Operations/FluidbookCollection/DownloadOperation.php @@ -27,9 +27,12 @@ trait DownloadOperation $entry->compile($compilepath); $fname = Str::slugCase('collection-' . date('Ymdhis') . '-' . Str::slug($entry->title)) . '.zip'; - $dest = protected_path('collection/download/' . $fname); + $dest = Files::mkdir(protected_path('collection/download/')) . $fname; Zip::archive($compilepath, $dest); + if(!file_exists($dest)){ + throw new \Exception('An error occured while compiling the collection'); + } return response(null)->header('Content-Type', 'application/zip') ->header('Content-Disposition', 'attachment; filename="' . $fname . '"') diff --git a/app/Models/FluidbookCollection.php b/app/Models/FluidbookCollection.php index bc06839f5..c92b4acfe 100644 --- a/app/Models/FluidbookCollection.php +++ b/app/Models/FluidbookCollection.php @@ -4,6 +4,7 @@ namespace App\Models; use App\Fields\User; use App\Http\Controllers\Admin\Operations\FluidbookCollection\DownloadOperation; +use App\Services\WorkshopV2; use App\SubForms\CollectionPublication; use Cubist\Backpack\Magic\Fields\BunchOfFieldsMultiple; use Cubist\Backpack\Magic\Fields\SelectFromArray; @@ -11,6 +12,7 @@ use Cubist\Backpack\Magic\Fields\Text; use Cubist\Backpack\Magic\Models\CubistMagicAbstractModel; use Illuminate\Database\Eloquent\Builder; use Illuminate\Support\Facades\Auth; +use function Symfony\Component\String\s; class FluidbookCollection extends CubistMagicAbstractModel { @@ -61,7 +63,83 @@ class FluidbookCollection extends CubistMagicAbstractModel } } + /** + * @throws \Exception + */ protected function compileSCORMMultilang($data, $path) { + $ws = new WorkshopV2(); + $user = backpack_user(); + $ws->login($user->email, $user->api_token); + + $first = true; + $langs = []; + foreach ($data->publications as $publication) { + $fbid = $publication['fluidbook']; + $metadata = $ws->getMetadata($fbid); + $langs[] = $metadata->lang; + $dir = $path . '/' . $metadata->lang; + $ws->installBook($fbid, $dir, 'scorm', 3); + if ($first) { + $first = false; + copy($dir . '/imsmanifest.xml', $path . '/imsmanifest.xml'); + } + unlink($dir . '/imsmanifest.xml'); + } + + if (in_array('en', $langs)) { + $default = 'en'; + } else { + $default = $langs[0]; + } + + $redirectionScript = " + + + + +"; + + file_put_contents($path.'/index.html',$redirectionScript); } } diff --git a/app/Services/WorkshopV2.php b/app/Services/WorkshopV2.php index 77c0c9005..44ce32a5a 100644 --- a/app/Services/WorkshopV2.php +++ b/app/Services/WorkshopV2.php @@ -6,6 +6,7 @@ use Cubist\Util\Files\Files; use Cubist\Util\Zip; use Exception; use GuzzleHttp\Client; +use GuzzleHttp\Cookie\FileCookieJar; use GuzzleHttp\Psr7\Request; use GuzzleHttp\Psr7\Utils; use SplFileInfo; @@ -22,12 +23,30 @@ class WorkshopV2 public function __construct() { - $this->_http = new Client(['base_uri' => $this->_domain, 'timeout' => 60000, 'read_timeout' => 60000]); + $this->_cookies = new FileCookieJar(Files::mkdir(protected_path('ws2cookies/')) . backpack_user()->id, true); + $this->_http = new Client(['base_uri' => $this->_domain, 'timeout' => 60000, 'read_timeout' => 60000, 'cookies' => $this->_cookies]); } - public function login($username, $password) + public function login($username, $api_key) { - $response = $this->_request('/', 'post', array('user_email' => $username, 'user_password' => $password)); + if ($this->isLoggedIn()) { + return true; + } + $res = $this->_request('/', 'POST', ['user_email' => $username, 'api_token' => $api_key]); + if (!$this->isLoggedIn()) { + dd($res); + throw new Exception('Login failed'); + } + return $res; + } + + public function isLoggedIn() + { + $res = $this->_request('/maintenance/loggedin'); + if (null === $res || $res->getBody()->getContents() === 'false') { + return false; + } + return true; } public function installBookIfNeeded($id, $dir, $timestamp = 'auto', $version = 'online') @@ -63,7 +82,8 @@ class WorkshopV2 $res = new stdClass(); $res->title = (string)$xml->title; - $res->date = intval((string)$xml->date); + $res->date = (int)$xml->date; + $res->lang = (string)$xml->lang; return $res; } @@ -89,17 +109,19 @@ class WorkshopV2 public function validDownloadBook($id) { - return $this->_request('ajax/downbook/' . $id . '/html', 'post', array('valide' => '1')); + return $this->_request('ajax/downbook/' . $id . '/html', 'post', array('valide' => '1')); } public function downloadBook($uri, $dir, $beforeInstallCallback = null) { set_time_limit(0); - $response = $this->_stream($uri); + $tmp = Files::tempnam() . '.zip'; + $this->_request($uri, 'GET', [], false, [], ['sink' => $tmp]); + // Unzip $tdir = $dir . '.temp'; - echo $response->getStreamName(); - Zip::extract($response->getStreamName(), $tdir); + Zip::extract($tmp, $tdir); + unlink($tmp); file_put_contents($tdir . '/TIME', time()); set_time_limit(0); @@ -109,7 +131,7 @@ class WorkshopV2 call_user_func($beforeInstallCallback); } Files::mkdir($dir); - echo shell_exec("mv -f \$tdir/* \$dir"); + echo shell_exec("mv -f $tdir/* $dir"); if (!file_exists($dir . '/_TIME')) { file_put_contents($dir . '/_TIME', time()); } @@ -122,7 +144,7 @@ class WorkshopV2 if (null !== $from) { $params['book'] = $from; } - $res = $this->_request('ajax/newBook', 'post', $params)->getBody(); + $res = $this->_request('ajax/newBook', 'POST', $params)->getBody(); preg_match('/\\/editor\/(\d+)\<\/url\>/i', $res, $matches); return $matches[1]; } @@ -141,7 +163,7 @@ class WorkshopV2 'creationDate' => $spl->getCTime(), ]; - return $this->_request('flash/uploadDocument', 'post', $args, false, [$spl]); + return $this->_request('flash/uploadDocument', 'POST', $args, false, [$spl]); } /** @@ -164,47 +186,58 @@ class WorkshopV2 * @return \Psr\Http\Message\ResponseInterface|void * @throws \GuzzleHttp\Exception\GuzzleException */ - protected function _request($uri, $method = 'get', $parameters = array(), $stream = false, $files = array()) + protected function _request($uri, $method = 'GET', $parameters = array(), $stream = false, $files = array(), $options = []) { - try { - - $options = ['stream' => $stream]; - if (count($files)) { - $options['multipart'] = []; - foreach ($parameters as $k => $v) { - $options['multipart'][] = ['name' => $k, 'content' => $v]; - } - foreach ($files as $file) { - if ($file instanceof SplFileInfo) { - $spl = $file; - } else { - $spl = new SplFileInfo($file); - } - $options['multipart'][] = ['name' => 'file[]', - 'contents' => Utils::tryFopen($spl->getPathname(), 'r'), - 'filename' => $spl->getFilename()]; + $method = mb_strtoupper($method); + if ($stream) { + $options['stream'] = $stream; + } + if (count($files)) { + $method = 'POST'; + $options['multipart'] = []; + foreach ($parameters as $k => $v) { + $options['multipart'][] = ['name' => $k, 'content' => $v]; + } + foreach ($files as $file) { + if ($file instanceof SplFileInfo) { + $spl = $file; + } else { + $spl = new SplFileInfo($file); } - } else if ($method === 'post') { + $options['multipart'][] = ['name' => 'file[]', + 'contents' => Utils::tryFopen($spl->getPathname(), 'r'), + 'filename' => $spl->getFilename()]; + } + } else if ($method === 'POST') { + if (count($parameters)) { $options['form_params'] = $parameters; - } else { + } + } else { + if (count($parameters)) { $options['query'] = $parameters; } + } + $options['timeout'] = $options['read_timeout'] = 60000; + $options['cookies'] = $this->_cookies; - $request = new Request($method, $this->_domain . ltrim($uri, '/'), $options); - return $this->_http->send($request); + $uri = $this->_domain . ltrim($uri, '/'); + $request = new Request($method, $uri); + try { + return $this->_http->send($request, $options); } catch (Exception $e) { - die($e->getMessage()); + throw $e; } + } /** - * - * @param string $uri + * @param $uri * @param string $method * @param array $parameters - * @return + * @return \Psr\Http\Message\ResponseInterface + * @throws \GuzzleHttp\Exception\GuzzleException */ - protected function _stream($uri, $method = 'get', $parameters = array()) + protected function _stream($uri, $method = 'GET', $parameters = array()) { return $this->_request($uri, $method, $parameters, true); } -- 2.39.5