diff --git a/composer.json b/composer.json
index fb8c9c333..88e3c520a 100644
--- a/composer.json
+++ b/composer.json
@@ -22,7 +22,8 @@
"Chill\\ThirdPartyBundle\\": "src/Bundle/ChillThirdPartyBundle",
"Chill\\AsideActivityBundle\\": "src/Bundle/ChillAsideActivityBundle/src",
"Chill\\DocGeneratorBundle\\": "src/Bundle/ChillDocGeneratorBundle",
- "Chill\\CalendarBundle\\": "src/Bundle/ChillCalendarBundle"
+ "Chill\\CalendarBundle\\": "src/Bundle/ChillCalendarBundle",
+ "Chill\\WopiBundle\\": "src/Bundle/ChillWopiBundle/src"
}
},
"autoload-dev": {
@@ -30,8 +31,12 @@
"App\\": "tests/app/src/"
}
},
+ "minimum-stability": "dev",
+ "prefer-stable": true,
"require": {
"champs-libres/async-uploader-bundle": "dev-sf4",
+ "champs-libres/wopi-bundle": "dev-master",
+ "nyholm/psr7": "^1.4",
"graylog2/gelf-php": "^1.5",
"symfony/form": "4.*",
"symfony/twig-bundle": "^4.4",
diff --git a/src/Bundle/ChillCalendarBundle/Controller/CalendarController.php b/src/Bundle/ChillCalendarBundle/Controller/CalendarController.php
index 5e5746387..a894099e4 100644
--- a/src/Bundle/ChillCalendarBundle/Controller/CalendarController.php
+++ b/src/Bundle/ChillCalendarBundle/Controller/CalendarController.php
@@ -87,7 +87,8 @@ class CalendarController extends AbstractController
// $view = 'ChillCalendarBundle:Calendar:listByUser.html.twig';
} elseif ($accompanyingPeriod instanceof AccompanyingPeriod) {
$calendarItems = $em->getRepository(Calendar::class)->findBy(
- ['accompanyingPeriod' => $accompanyingPeriod]
+ ['accompanyingPeriod' => $accompanyingPeriod],
+ ['startDate' => 'DESC']
);
$view = 'ChillCalendarBundle:Calendar:listByAccompanyingCourse.html.twig';
@@ -139,10 +140,9 @@ class CalendarController extends AbstractController
$this->addFlash('success', $this->get('translator')->trans('Success : calendar item created!'));
- $params = $this->buildParamsToUrl($user, $accompanyingPeriod); //TODO useful?
- $params['id'] = $entity->getId();
+ $params = $this->buildParamsToUrl($user, $accompanyingPeriod);
- return $this->redirectToRoute('chill_calendar_calendar_show', $params);
+ return $this->redirectToRoute('chill_calendar_calendar', $params);
} elseif ($form->isSubmitted() and !$form->isValid()) {
$this->addFlash('error', $this->get('translator')->trans('This form contains errors'));
}
@@ -241,8 +241,7 @@ class CalendarController extends AbstractController
$this->addFlash('success', $this->get('translator')->trans('Success : calendar item updated!'));
$params = $this->buildParamsToUrl($user, $accompanyingPeriod);
- $params['id'] = $id;
- return $this->redirectToRoute('chill_calendar_calendar_show', $params);
+ return $this->redirectToRoute('chill_calendar_calendar', $params);
} elseif ($form->isSubmitted() and !$form->isValid()) {
$this->addFlash('error', $this->get('translator')->trans('This form contains errors'));
}
@@ -304,7 +303,7 @@ class CalendarController extends AbstractController
$em->flush();
$this->addFlash('success', $this->get('translator')
- ->trans("The calendar has been successfully removed."));
+ ->trans("The calendar item has been successfully removed."));
$params = $this->buildParamsToUrl($user, $accompanyingPeriod);
return $this->redirectToRoute('chill_calendar_calendar', $params);
diff --git a/src/Bundle/ChillCalendarBundle/Form/CalendarType.php b/src/Bundle/ChillCalendarBundle/Form/CalendarType.php
index c2f3ea6ba..990f7ea59 100644
--- a/src/Bundle/ChillCalendarBundle/Form/CalendarType.php
+++ b/src/Bundle/ChillCalendarBundle/Form/CalendarType.php
@@ -48,13 +48,13 @@ class CalendarType extends AbstractType
->add('comment', CommentType::class, [
'required' => false
])
- ->add('cancelReason', EntityType::class, [
- 'required' => false,
- 'class' => CancelReason::class,
- 'choice_label' => function (CancelReason $entity) {
- return $entity->getCanceledBy();
- },
- ])
+ // ->add('cancelReason', EntityType::class, [
+ // 'required' => false,
+ // 'class' => CancelReason::class,
+ // 'choice_label' => function (CancelReason $entity) {
+ // return $entity->getCanceledBy();
+ // },
+ // ])
->add('sendSMS', ChoiceType::class, [
'required' => false,
'choices' => [
diff --git a/src/Bundle/ChillCalendarBundle/Resources/public/chill/index.js b/src/Bundle/ChillCalendarBundle/Resources/public/chill/index.js
new file mode 100644
index 000000000..c6e439991
--- /dev/null
+++ b/src/Bundle/ChillCalendarBundle/Resources/public/chill/index.js
@@ -0,0 +1 @@
+require('./scss/calendar.scss');
\ No newline at end of file
diff --git a/src/Bundle/ChillCalendarBundle/Resources/public/chill/scss/calendar.scss b/src/Bundle/ChillCalendarBundle/Resources/public/chill/scss/calendar.scss
new file mode 100644
index 000000000..b224125f1
--- /dev/null
+++ b/src/Bundle/ChillCalendarBundle/Resources/public/chill/scss/calendar.scss
@@ -0,0 +1,10 @@
+div#calendarControls {
+ height: 50%;
+ display: flex;
+ flex-direction: column;
+ justify-content: flex-end;
+}
+
+div#fullCalendar{
+
+}
\ No newline at end of file
diff --git a/src/Bundle/ChillCalendarBundle/Resources/public/vuejs/Calendar/App.vue b/src/Bundle/ChillCalendarBundle/Resources/public/vuejs/Calendar/App.vue
index fb4429a1d..5999fdbd0 100644
--- a/src/Bundle/ChillCalendarBundle/Resources/public/vuejs/Calendar/App.vue
+++ b/src/Bundle/ChillCalendarBundle/Resources/public/vuejs/Calendar/App.vue
@@ -1,39 +1,35 @@
-
-
- {{ $t('choose_your_date') }}
-
-
- {{ arg.timeText }}
-
-
+
+
+
+
+
+
+
+ {{ arg.timeText }}
+ {{ arg.event.title }}
+
+
+
diff --git a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/components/FormEvaluation.vue b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/components/FormEvaluation.vue
index 721d15450..33436f222 100644
--- a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/components/FormEvaluation.vue
+++ b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/components/FormEvaluation.vue
@@ -67,19 +67,15 @@
-
+
+
-
-
@@ -88,6 +84,7 @@
import {dateToISO, ISOToDate, ISOToDatetime} from 'ChillMainAssets/chill/js/date.js';
import CKEditor from '@ckeditor/ckeditor5-vue';
import ClassicEditor from 'ChillMainAssets/module/ckeditor5/index.js';
+import { mapGetters, mapState } from 'vuex';
const i18n = {
messages: {
@@ -119,25 +116,19 @@ export default {
data() {
return {
editor: ClassicEditor,
- //evaluation: {
- // status: null,
- // startDate: null,
- // endDate: null,
- // maxDate: null,
- // warningInterval: null,
- // comment: null,
- // template: null,
- // //documents: null
- //}
+ template: null,
}
},
computed: {
- /*
- status: {
- get() { return this.evaluation.status; },
- set(v) { this.evaluation.status = v; }
+ ...mapGetters([
+ 'getTemplatesAvailaibleForEvaluation'
+ ]),
+ ...mapState([
+ 'isPosting'
+ ]),
+ canGenerate() {
+ return !this.$store.state.isPosting && this.template !== null;
},
- */
startDate: {
get() {
return dateToISO(this.evaluation.startDate);
@@ -171,10 +162,6 @@ export default {
get() { return this.evaluation.comment; },
set(v) { this.$store.commit('setEvaluationComment', { key: this.evaluation.key, comment: v }); }
},
- template: {
- get() { return this.evaluation.template; },
- set(v) { this.evaluation.template = v; }
- },
},
methods: {
listAllStatus() {
@@ -189,6 +176,10 @@ export default {
})
;
},
+ generateDocument() {
+ console.log('template picked', this.template);
+ this.$store.dispatch('generateDocument', { key: this.evaluation.key, templateId: this.template})
+ }
},
mounted() {
//this.listAllStatus();
diff --git a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/store.js b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/store.js
index 87b7d03e4..22218f04f 100644
--- a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/store.js
+++ b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/store.js
@@ -4,6 +4,7 @@ import { findSocialActionsBySocialIssue } from 'ChillPersonAssets/vuejs/_api/Soc
import { create } from 'ChillPersonAssets/vuejs/_api/AccompanyingCourseWork.js';
const debug = process.env.NODE_ENV !== 'production';
+const evalFQDN = encodeURIComponent("Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWorkEvaluation");
const store = createStore({
strict: debug,
@@ -32,6 +33,7 @@ const store = createStore({
return k;
}),
evaluationsForAction: [],
+ templatesAvailableForEvaluation: [],
personsPicked: window.accompanyingCourseWork.persons,
personsReachables: window.accompanyingCourseWork.accompanyingPeriod.participations.filter(p => p.endDate == null)
.map(p => p.person),
@@ -63,6 +65,9 @@ const store = createStore({
hasThirdParties(state) {
return state.thirdParties.length > 0;
},
+ getTemplatesAvailaibleForEvaluation(state) {
+ return state.templatesAvailableForEvaluation;
+ },
buildPayload(state) {
return {
type: 'accompanying_period_work',
@@ -99,6 +104,7 @@ const store = createStore({
accompanyingPeriodWorkEvaluations: state.evaluationsPicked.map(e => {
let o = {
type: e.type,
+ key: e.key,
evaluation: {
id: e.evaluation.id,
type: e.evaluation.type
@@ -216,6 +222,11 @@ const store = createStore({
let evaluation = state.evaluationsPicked.find(e => e.key === key);
evaluation.editEvaluation = !evaluation.editEvaluation;
},
+ setTemplatesAvailableForEvaluation(state, templates) {
+ for (let i in templates) {
+ state.templatesAvailableForEvaluation.push(templates[i]);
+ }
+ },
setPersonsPickedIds(state, ids) {
state.personsPicked = state.personsReachables
.filter(p => ids.includes(p.id))
@@ -317,7 +328,38 @@ const store = createStore({
commit('setEvaluationsForAction', data.results);
});
},
- submit({ getters, state, commit }) {
+ getReachableTemplatesForEvaluation({commit}) {
+ const
+ url = `/fr/doc/gen/templates/for/${evalFQDN}`
+ ;
+ window.fetch(url).then(r => {
+ if (r.ok) {
+ return r.json();
+ }
+ throw new Error("not possible to load templates for evaluations")
+ }).then(data => {
+ commit('setTemplatesAvailableForEvaluation', data.results);
+ }).catch(e => {
+ console.error(e);
+ })
+ },
+ generateDocument({ dispatch }, {key, templateId}) {
+ const callback = function(data) {
+ // get the evaluation id from the data
+ const
+ evaluationId = data.accompanyingPeriodWorkEvaluations.find(e => e.key === key).id,
+ returnPath = encodeURIComponent(window.location.pathname + window.location.search + window.location.hash),
+ url = `/fr/doc/gen/generate/from/${templateId}/for/${evalFQDN}/${evaluationId}?returnPath=${returnPath}`
+ ;
+ //http://localhost:8001/fr/doc/gen/generate/from/12/for/Chill%5CPersonBundle%5CEntity%5CAccompanyingPeriod%5CAccompanyingPeriodWorkEvaluation/41
+
+ console.log('I will generate your doc at', url);
+ window.location.assign(url);
+ };
+
+ dispatch('submit', callback);
+ },
+ submit({ getters, state, commit }, callback) {
let
payload = getters.buildPayload,
url = `/api/1.0/person/accompanying-course/work/${state.work.id}.json`,
@@ -345,6 +387,8 @@ const store = createStore({
}
commit('setErrors', errors);
commit('setIsPosting', false);
+ } else if (typeof(callback) !== 'undefined') {
+ callback(data);
} else {
console.info('nothing to do here, bye bye');
window.location.assign(`/fr/person/accompanying-period/${state.work.accompanyingPeriod.id}/work`);
@@ -360,6 +404,7 @@ const store = createStore({
dispatch('getReachablesResultsForAction');
dispatch('getReachablesGoalsForAction');
dispatch('getReachablesEvaluationsForAction');
+ dispatch('getReachableTemplatesForEvaluation');
},
}
});
diff --git a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/HouseholdMembersEditor/components/Household.vue b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/HouseholdMembersEditor/components/Household.vue
index fa3dd64b6..05746429c 100644
--- a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/HouseholdMembersEditor/components/Household.vue
+++ b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/HouseholdMembersEditor/components/Household.vue
@@ -7,35 +7,43 @@
-
À quelle adresse habite ce ménage ?
+
À quelle adresse habite ce ménage ?
-
- -
-
-
-
-
+
Supprimer cette adresse
-
+
@@ -51,7 +59,7 @@
class="btn btn-misc"
@click="toggleHouseholdSuggestion"
>
- {{ $tc('household_members_editor.show_household_suggestion',
+ {{ $tc('household_members_editor.show_household_suggestion',
countHouseholdSuggestion) }}
@@ -106,11 +114,24 @@
-
+
+
+
+
+
+
+
diff --git a/src/Bundle/ChillWopiBundle/src/Resources/views/Editor/page.html.twig b/src/Bundle/ChillWopiBundle/src/Resources/views/Editor/page.html.twig
new file mode 100644
index 000000000..6534dfd30
--- /dev/null
+++ b/src/Bundle/ChillWopiBundle/src/Resources/views/Editor/page.html.twig
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ encore_entry_link_tags('page_wopi_editor') }}
+ {{ encore_entry_script_tags('page_wopi_editor') }}
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Bundle/ChillWopiBundle/src/Service/Controller/Responder.php b/src/Bundle/ChillWopiBundle/src/Service/Controller/Responder.php
new file mode 100644
index 000000000..bc26be62d
--- /dev/null
+++ b/src/Bundle/ChillWopiBundle/src/Service/Controller/Responder.php
@@ -0,0 +1,101 @@
+twig = $twig;
+ $this->urlGenerator = $urlGenerator;
+ $this->serializer = $serializer;
+ }
+
+ public function file(
+ $file,
+ ?string $filename = null,
+ string $disposition = ResponseHeaderBag::DISPOSITION_ATTACHMENT
+ ): BinaryFileResponse {
+ $response = new BinaryFileResponse($file);
+
+ $filename ??= $response->getFile()->getFilename();
+ $response->setContentDisposition($disposition, $filename);
+
+ return $response;
+ }
+
+ public function json(
+ $data,
+ int $status = 200,
+ array $headers = [],
+ array $context = []
+ ): JsonResponse {
+ return new JsonResponse(
+ $this
+ ->serializer
+ ->serialize(
+ $data,
+ 'json',
+ array_merge(
+ [
+ 'json_encode_options' => JsonResponse::DEFAULT_ENCODING_OPTIONS,
+ ],
+ $context
+ )
+ ),
+ $status,
+ $headers,
+ true
+ );
+ }
+
+ public function redirect(string $url, int $status = 302, array $headers = []): RedirectResponse
+ {
+ return new RedirectResponse($url, $status, $headers);
+ }
+
+ public function redirectToRoute(
+ string $route,
+ array $parameters = [],
+ int $status = 302,
+ array $headers = []
+ ): RedirectResponse {
+ return $this->redirect($this->urlGenerator->generate($route, $parameters), $status, $headers);
+ }
+
+ public function render(string $template, array $context = [], int $status = 200, array $headers = []): Response
+ {
+ $response = new Response($this->twig->render($template, $context), $status, $headers);
+
+ if (!$response->headers->has('Content-Type')) {
+ $response->headers->set('Content-Type', 'text/html; charset=UTF-8');
+ }
+
+ return $response;
+ }
+}
diff --git a/src/Bundle/ChillWopiBundle/src/Service/Controller/ResponderInterface.php b/src/Bundle/ChillWopiBundle/src/Service/Controller/ResponderInterface.php
new file mode 100644
index 000000000..712b3cd59
--- /dev/null
+++ b/src/Bundle/ChillWopiBundle/src/Service/Controller/ResponderInterface.php
@@ -0,0 +1,74 @@
+|string> $headers
+ * @param array $context
+ */
+ public function json(
+ mixed $data,
+ int $status = 200,
+ array $headers = [],
+ array $context = []
+ ): JsonResponse;
+
+ /**
+ * Returns a RedirectResponse to the given URL.
+ *
+ * @param array|string> $headers
+ */
+ public function redirect(string $url, int $status = 302, array $headers = []): RedirectResponse;
+
+ /**
+ * Returns a RedirectResponse to the given route with the given parameters.
+ *
+ * @param array $parameters
+ * @param array> $headers
+ */
+ public function redirectToRoute(
+ string $route,
+ array $parameters = [],
+ int $status = 302,
+ array $headers = []
+ ): RedirectResponse;
+
+ /**
+ * Render the given twig template and return an HTML response.
+ *
+ * @param array|string> $headers
+ *
+ * @throws TwigError
+ */
+ public function render(string $template, array $context = [], int $status = 200, array $headers = []): Response;
+}
diff --git a/src/Bundle/ChillWopiBundle/src/Service/Wopi/ChillWopi.php b/src/Bundle/ChillWopiBundle/src/Service/Wopi/ChillWopi.php
new file mode 100644
index 000000000..bb0dfb8e2
--- /dev/null
+++ b/src/Bundle/ChillWopiBundle/src/Service/Wopi/ChillWopi.php
@@ -0,0 +1,305 @@
+psr17 = $psr17;
+ $this->wopiDiscovery = $wopiDiscovery;
+ $this->storedObjectRepository = $storedObjectRepository;
+ $this->httpClient = $httpClient;
+ $this->tempUrlGenerator = $tempUrlGenerator;
+ $this->userProvider = $userProvider;
+ }
+
+ public function checkFileInfo(
+ string $fileId,
+ ?string $accessToken,
+ RequestInterface $request
+ ): ResponseInterface {
+ try {
+ $user = $this->userProvider->loadUserByUsername($accessToken);
+ } catch (UsernameNotFoundException $e) {
+ return $this
+ ->psr17
+ ->createResponse(401);
+ }
+
+ $storedObject = $this->storedObjectRepository->findOneBy(['filename' => $fileId]);
+
+ if (null === $storedObject) {
+ throw new Exception(sprintf('Unable to find object named %s', $fileId));
+ }
+
+ $mimeType = $storedObject->getType();
+
+ if ([] === $this->wopiDiscovery->discoverMimeType($mimeType)) {
+ throw new Exception(sprintf('Unable to find mime type %s', $mimeType));
+ }
+
+ return $this
+ ->psr17
+ ->createResponse()
+ ->withHeader('Content-Type', 'application/json')
+ ->withBody($this->psr17->createStream((string) json_encode(
+ [
+ 'BaseFileName' => $storedObject->getFilename(),
+ 'OwnerId' => uniqid(),
+ 'Size' => 0,
+ 'UserId' => uniqid(),
+// 'Version' => 'v' . uniqid(),
+ 'ReadOnly' => false,
+ 'UserCanWrite' => true,
+ 'UserCanNotWriteRelative' => true,
+ 'SupportsLocks' => false,
+ 'UserFriendlyName' => sprintf('User %s', $user->getUsername()),
+ 'UserExtraInfo' => [],
+ 'LastModifiedTime' => date('Y-m-d\TH:i:s.u\Z', $storedObject->getCreationDate()->getTimestamp()),
+ 'CloseButtonClosesWindow' => true,
+ 'EnableInsertRemoteImage' => true,
+ 'EnableShare' => false,
+ 'SupportsUpdate' => true,
+ 'SupportsRename' => false,
+ 'DisablePrint' => false,
+ 'DisableExport' => false,
+ 'DisableCopy' => false,
+ ]
+ )));
+ }
+
+ public function deleteFile(string $fileId, ?string $accessToken, RequestInterface $request): ResponseInterface
+ {
+ return $this->getDebugResponse(__FUNCTION__, $request);
+ }
+
+ public function enumerateAncestors(
+ string $fileId,
+ ?string $accessToken,
+ RequestInterface $request
+ ): ResponseInterface {
+ return $this->getDebugResponse(__FUNCTION__, $request);
+ }
+
+ public function getFile(string $fileId, ?string $accessToken, RequestInterface $request): ResponseInterface
+ {
+ try {
+ $user = $this->userProvider->loadUserByUsername($accessToken);
+ } catch (UsernameNotFoundException $e) {
+ return $this
+ ->psr17
+ ->createResponse(401);
+ }
+
+ $storedObject = $this->storedObjectRepository->findOneBy(['filename' => $fileId]);
+
+ if (null === $storedObject) {
+ return $this
+ ->psr17
+ ->createResponse(404);
+ }
+
+ // TODO: Add strict typing in champs-libres/async-uploader-bundle
+ /** @var StdClass $object */
+ $object = $this->tempUrlGenerator->generate('GET', $storedObject->getFilename());
+
+ $response = $this->httpClient->sendRequest($this->psr17->createRequest('GET', $object->url));
+
+ if (200 !== $response->getStatusCode())
+ {
+ return $this
+ ->psr17
+ ->createResponse(500);
+ }
+
+ return $this
+ ->psr17
+ ->createResponse()
+ ->withHeader(
+ 'Content-Type',
+ 'application/octet-stream',
+ )
+ ->withHeader(
+ 'Content-Disposition',
+ sprintf('attachment; filename=%s', $storedObject->getFilename())
+ )
+ ->withBody($response->getBody());
+ }
+
+ public function getLock(string $fileId, ?string $accessToken, RequestInterface $request): ResponseInterface
+ {
+ return $this->getDebugResponse(__FUNCTION__, $request);
+ }
+
+ public function getShareUrl(
+ string $fileId,
+ ?string $accessToken,
+ RequestInterface $request
+ ): ResponseInterface {
+ return $this->getDebugResponse(__FUNCTION__, $request);
+ }
+
+ public function lock(
+ string $fileId,
+ ?string $accessToken,
+ string $xWopiLock,
+ RequestInterface $request
+ ): ResponseInterface {
+ return $this->getDebugResponse(__FUNCTION__, $request);
+ }
+
+ public function putFile(
+ string $fileId,
+ ?string $accessToken,
+ string $xWopiLock,
+ string $xWopiEditors,
+ RequestInterface $request
+ ): ResponseInterface {
+ try {
+ $user = $this->userProvider->loadUserByUsername($accessToken);
+ } catch (UsernameNotFoundException $e) {
+ return $this
+ ->psr17
+ ->createResponse(401);
+ }
+
+ $storedObject = $this->storedObjectRepository->findOneBy(['filename' => $fileId]);
+
+ if (null === $storedObject) {
+ throw new Exception(sprintf('Unable to find object named %s', $fileId));
+ }
+
+ // TODO: Add strict typing in champs-libres/async-uploader-bundle
+ /** @var StdClass $object */
+ $object = $this->tempUrlGenerator->generate('PUT', $storedObject->getFilename());
+
+ $response = $this->httpClient->sendRequest($this->psr17->createRequest('PUT', $object->url)->withBody($request->getBody()));
+
+ if (201 !== $response->getStatusCode())
+ {
+ return $this
+ ->psr17
+ ->createResponse(500);
+ }
+
+ return $this
+ ->psr17
+ ->createResponse()
+ ->withHeader('Content-Type', 'application/json')
+ ->withAddedHeader('X-WOPI-Lock', $xWopiLock)
+ ->withBody($this->psr17->createStream((string) json_encode([])));
+ }
+
+ public function putRelativeFile(string $fileId, ?string $accessToken, RequestInterface $request): ResponseInterface
+ {
+ return $this->getDebugResponse(__FUNCTION__, $request);
+ }
+
+ public function putUserInfo(string $fileId, ?string $accessToken, RequestInterface $request): ResponseInterface
+ {
+ return $this->getDebugResponse(__FUNCTION__, $request);
+ }
+
+ public function refreshLock(
+ string $fileId,
+ ?string $accessToken,
+ string $xWopiLock,
+ RequestInterface $request
+ ): ResponseInterface {
+ return $this->getDebugResponse(__FUNCTION__, $request);
+ }
+
+ public function renameFile(
+ string $fileId,
+ ?string $accessToken,
+ string $xWopiLock,
+ string $xWopiRequestedName,
+ RequestInterface $request
+ ): ResponseInterface {
+ return $this->getDebugResponse(__FUNCTION__, $request);
+ }
+
+ public function unlock(
+ string $fileId,
+ ?string $accessToken,
+ string $xWopiLock,
+ RequestInterface $request
+ ): ResponseInterface {
+ return $this->getDebugResponse(__FUNCTION__, $request);
+ }
+
+ public function unlockAndRelock(
+ string $fileId,
+ ?string $accessToken,
+ string $xWopiLock,
+ string $xWopiOldLock,
+ RequestInterface $request
+ ): ResponseInterface {
+ return $this->getDebugResponse(__FUNCTION__, $request);
+ }
+
+ private function getDebugResponse(string $method, RequestInterface $request): ResponseInterface
+ {
+ $params = [];
+ parse_str($request->getUri()->getQuery(), $params);
+
+ $data = (string) json_encode(array_merge(
+ ['method' => $method],
+ $params,
+ $request->getHeaders()
+ ));
+
+ return $this
+ ->psr17
+ ->createResponse()
+ ->withHeader('content', 'application/json')
+ ->withBody($this->psr17->createStream($data));
+ }
+
+ private function getLockFilepath(string $fileId): string
+ {
+ return sprintf(
+ '%s/%s.lock',
+ $this->filesRepository,
+ $fileId
+ );
+ }
+}