diff --git a/main/admin/index.php b/main/admin/index.php
index 674ba17684..feac0b1dc0 100644
--- a/main/admin/index.php
+++ b/main/admin/index.php
@@ -3,7 +3,6 @@
use Chamilo\CoreBundle\Framework\Container;
use League\Flysystem\Filesystem;
-use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
/**
* Index page of the admin tools.
diff --git a/main/course_info/infocours.php b/main/course_info/infocours.php
index dcfe93b19f..85b97a9639 100755
--- a/main/course_info/infocours.php
+++ b/main/course_info/infocours.php
@@ -15,7 +15,6 @@
*
* @package chamilo.course_info
*/
-
use Chamilo\CoreBundle\Framework\Container;
require_once __DIR__.'/../inc/global.inc.php';
diff --git a/main/document/upload.php b/main/document/upload.php
index 0eb6de0728..48dca46f5d 100755
--- a/main/document/upload.php
+++ b/main/document/upload.php
@@ -178,7 +178,7 @@ if (!empty($_FILES)) {
if ($document) {
$redirectUrl .= '&'.http_build_query(
[
- 'id' => $document->getId(),
+ 'id' => $parent_id,
]
);
}
diff --git a/main/inc/ajax/document.ajax.php b/main/inc/ajax/document.ajax.php
index 1abe737ae2..d42144dd9e 100755
--- a/main/inc/ajax/document.ajax.php
+++ b/main/inc/ajax/document.ajax.php
@@ -111,7 +111,6 @@ switch ($action) {
);
$json['url'] = '#';
$json['size'] = format_file_size($document->getSize());
- //$json['type'] = api_htmlentities($file['type']);
$json['type'] = '';
$json['result'] = Display::return_icon(
'accept.png',
diff --git a/main/inc/lib/document.lib.php b/main/inc/lib/document.lib.php
index d9b2f99911..e95ade6631 100644
--- a/main/inc/lib/document.lib.php
+++ b/main/inc/lib/document.lib.php
@@ -6388,7 +6388,6 @@ class DocumentManager
return $list;
}
-
/**
* @param CDocument $document
* @param $path
@@ -6662,7 +6661,6 @@ class DocumentManager
return $document;
}
-
return false;
}
@@ -6731,7 +6729,7 @@ class DocumentManager
$img = Display::returnIconPath($icon);
if (!file_exists($img_sys_path.$icon)) {
- $img = Display::returnIconPath('default_small.gif');
+ $img = Display::returnIconPath('default_small.png');
}
$link = Display::url(
@@ -6829,7 +6827,7 @@ class DocumentManager
$image = Display::returnIconPath('nolines_minus.gif');
}
$return .= '
';
- $return .= Display::return_icon('lp_folder.gif').' ';
+ $return .= Display::return_icon('lp_folder.png').' ';
$return .= ''.$title.'';
$return .= '';
diff --git a/main/inc/lib/statistics.lib.php b/main/inc/lib/statistics.lib.php
index e9868e82f3..cd18c16514 100644
--- a/main/inc/lib/statistics.lib.php
+++ b/main/inc/lib/statistics.lib.php
@@ -629,7 +629,7 @@ class Statistics
/**
* get the number of recent logins.
*
- * @param bool $distinct Whether to only give distinct users stats, or *all* logins
+ * @param bool $distinct Whether to only give distinct users stats, or *all* logins
* @param int $sessionDuration
* @param bool $completeMissingDays Whether to fill the daily gaps (if any) when getting a list of logins
*
@@ -766,6 +766,7 @@ class Statistics
while ($obj = Database::fetch_object($res)) {
$result[$obj->course_language] = $obj->number_of_courses;
}
+
return $result;
}
@@ -1075,13 +1076,16 @@ class Statistics
false
);
}
+
/**
* Returns an array with indexes as the 'yyyy-mm-dd' format of each date
* within the provided range (including limits). Dates are assumed to be
- * given in UTC
- * @param string $startDate Start date, in Y-m-d or Y-m-d h:i:s format
- * @param string $endDate End date, in Y-m-d or Y-m-d h:i:s format
+ * given in UTC.
+ *
+ * @param string $startDate Start date, in Y-m-d or Y-m-d h:i:s format
+ * @param string $endDate End date, in Y-m-d or Y-m-d h:i:s format
* @param bool $removeYear Whether to remove the year in the results (for easier reading)
+ *
* @return array|bool False on error in the params, array of [date1 => 0, date2 => 0, ...] otherwise
*/
public static function buildDatesArray($startDate, $endDate, $removeYear = false)
@@ -1110,17 +1114,20 @@ class Statistics
}
$list[$datetime] = 0;
}
+
return $list;
}
+
/**
- * Prepare the JS code to load a chart
- * @param string $url URL for AJAX data generator
- * @param string $type bar, line, pie, etc
+ * Prepare the JS code to load a chart.
+ *
+ * @param string $url URL for AJAX data generator
+ * @param string $type bar, line, pie, etc
* @param string $options Additional options to the chart (see chart-specific library)
* @param string A JS code for loading the chart together with a call to AJAX data generator
*/
public static function getJSChartTemplate($url, $type = 'pie', $options = '', $elementId = 'canvas')
- {
+ {
$chartCode = '
';
+
return $chartCode;
}
}
diff --git a/main/lp/lp_view.php b/main/lp/lp_view.php
index 4c3c4b09f1..23160d7667 100755
--- a/main/lp/lp_view.php
+++ b/main/lp/lp_view.php
@@ -565,7 +565,6 @@ $template->assign(
ICON_SIZE_BIG
)
);
-
$template->displayTemplate('@ChamiloTheme/LearnPath/view.html.twig');
// Restore a global setting.
diff --git a/src/CoreBundle/Controller/IndexController.php b/src/CoreBundle/Controller/IndexController.php
index d67191cced..2c9ce93bd6 100644
--- a/src/CoreBundle/Controller/IndexController.php
+++ b/src/CoreBundle/Controller/IndexController.php
@@ -13,7 +13,6 @@ use Symfony\Component\Routing\Annotation\Route;
* author Julio Montoya .
*
* @package Chamilo\CoreBundle\Controller
- *
*/
class IndexController extends BaseController
{
diff --git a/src/CoreBundle/Menu/MenuVoter.php b/src/CoreBundle/Menu/MenuVoter.php
index 2e1e62fc5b..934327819b 100644
--- a/src/CoreBundle/Menu/MenuVoter.php
+++ b/src/CoreBundle/Menu/MenuVoter.php
@@ -3,10 +3,6 @@
namespace Chamilo\CoreBundle\Menu;
-use Chamilo\FaqBundle\Entity\Category;
-use Chamilo\PageBundle\Entity\Page;
-use Chamilo\PageBundle\Entity\Site;
-use Knp\Menu\FactoryInterface;
use Knp\Menu\ItemInterface;
use Knp\Menu\Matcher\Voter\VoterInterface;
use Symfony\Component\HttpFoundation\RequestStack;
@@ -50,7 +46,7 @@ class MenuVoter implements VoterInterface
if (strpos($currentUri, 'user_portal.php') !== false &&
strpos($currentUrl, 'user_portal.php') !== false
- ){
+ ) {
return true;
}
diff --git a/src/CoreBundle/Migrations/Schema/V200/Version20181126174500.php b/src/CoreBundle/Migrations/Schema/V200/Version20181126174500.php
index a641897b12..bac33ea885 100644
--- a/src/CoreBundle/Migrations/Schema/V200/Version20181126174500.php
+++ b/src/CoreBundle/Migrations/Schema/V200/Version20181126174500.php
@@ -7,7 +7,7 @@ use Chamilo\CoreBundle\Migrations\AbstractMigrationChamilo;
use Doctrine\DBAL\Schema\Schema;
/**
- * Class Version20181126174500
+ * Class Version20181126174500.
*
* @package Chamilo\CoreBundle\Migrations\Schema\V200
*/
diff --git a/src/LtiBundle/ChamiloLtiBundle.php b/src/LtiBundle/ChamiloLtiBundle.php
index 1111d29426..690d76f8ed 100644
--- a/src/LtiBundle/ChamiloLtiBundle.php
+++ b/src/LtiBundle/ChamiloLtiBundle.php
@@ -12,5 +12,4 @@ use Symfony\Component\HttpKernel\Bundle\Bundle;
*/
class ChamiloLtiBundle extends Bundle
{
-
}
diff --git a/src/LtiBundle/Controller/AdminController.php b/src/LtiBundle/Controller/AdminController.php
index 0d7c307e12..09d27c09ca 100644
--- a/src/LtiBundle/Controller/AdminController.php
+++ b/src/LtiBundle/Controller/AdminController.php
@@ -158,4 +158,4 @@ class AdminController extends BaseController
return $this->redirectToRoute('chamilo_lti_admin');
}
-}
\ No newline at end of file
+}
diff --git a/src/LtiBundle/Controller/CourseController.php b/src/LtiBundle/Controller/CourseController.php
index 102e2af3e0..b9703b08aa 100644
--- a/src/LtiBundle/Controller/CourseController.php
+++ b/src/LtiBundle/Controller/CourseController.php
@@ -7,7 +7,6 @@ use Chamilo\CoreBundle\Controller\BaseController;
use Chamilo\CoreBundle\Entity\Course;
use Chamilo\CoreBundle\Entity\Session;
use Chamilo\CourseBundle\Entity\CTool;
-use Chamilo\LtiBundle\Component\ServiceRequestFactory;
use Chamilo\LtiBundle\Entity\ExternalTool;
use Chamilo\LtiBundle\Form\ExternalToolType;
use Chamilo\LtiBundle\Util\Utils;
@@ -102,26 +101,6 @@ class CourseController extends BaseController
);
}
- /**
- * @param Course $course
- */
- private function setConfigureBreadcrumb(Course $course)
- {
- $breadcrumb = $this->get('chamilo_core.block.breadcrumb');
- $breadcrumb->addChild(
- $course->getTitle(),
- [
- 'uri' => $this->generateUrl(
- 'chamilo_course_home_home_index',
- ['course' => $course->getCode()]
- ),
- ]
- );
- $breadcrumb->addChild(
- $this->trans('Configure external tool')
- );
- }
-
/**
* @Route("/launch/{id}", name="chamilo_lti_launch", requirements={"id"="\d+"})
*
@@ -280,6 +259,234 @@ class CourseController extends BaseController
);
}
+ /**
+ * @Route("/item_return", name="chamilo_lti_return_item")
+ *
+ * @param Request $request
+ *
+ * @return Response
+ */
+ public function returnItemAction(Request $request): Response
+ {
+ $contentItems = $request->get('content_items');
+ $data = $request->get('data');
+
+ if (empty($contentItems) || empty($data)) {
+ throw $this->createAccessDeniedException();
+ }
+
+ $em = $this->getDoctrine()->getManager();
+
+ /** @var ExternalTool $tool */
+ $tool = $em->find('ChamiloLtiBundle:ExternalTool', str_replace('tool:', '', $data));
+
+ if (empty($tool)) {
+ throw $this->createNotFoundException('External tool not found');
+ }
+
+ $course = $this->getCourse();
+ $url = $this->generateUrl(
+ 'chamilo_lti_return_item',
+ ['code' => $course->getCode()],
+ UrlGeneratorInterface::ABSOLUTE_URL
+ );
+
+ $signatureIsValid = Utils::checkRequestSignature(
+ $url,
+ $request->get('oauth_consumer_key'),
+ $request->get('oauth_signature'),
+ $tool
+ );
+
+ if (!$signatureIsValid) {
+ throw $this->createAccessDeniedException();
+ }
+
+ $contentItems = json_decode($contentItems, true)['@graph'];
+
+ $supportedItemTypes = ['LtiLinkItem'];
+
+ foreach ($contentItems as $contentItem) {
+ if (!in_array($contentItem['@type'], $supportedItemTypes)) {
+ continue;
+ }
+
+ if ('LtiLinkItem' === $contentItem['@type']) {
+ $newTool = $this->createLtiLink($contentItem, $tool);
+
+ $this->addFlash(
+ 'success',
+ sprintf(
+ $this->trans('External tool added: %s'),
+ $newTool->getName()
+ )
+ );
+ }
+ }
+
+ return $this->render(
+ '@ChamiloTheme/Lti/item_return.html.twig',
+ ['course' => $course]
+ );
+ }
+
+ /**
+ * @Route("/{id}", name="chamilo_lti_show", requirements={"id"="\d+"})
+ *
+ * @param string $id
+ *
+ * @return Response
+ */
+ public function showAction($id): Response
+ {
+ $course = $this->getCourse();
+
+ $em = $this->getDoctrine()->getManager();
+
+ /** @var ExternalTool|null $externalTool */
+ $externalTool = $em->find('ChamiloLtiBundle:ExternalTool', $id);
+
+ if (empty($externalTool)) {
+ throw $this->createNotFoundException();
+ }
+
+ if (empty($externalTool->getCourse()) || $externalTool->getCourse()->getId() !== $course->getId()) {
+ throw $this->createAccessDeniedException('');
+ }
+
+ $breadcrumb = $this->get('chamilo_core.block.breadcrumb');
+ $breadcrumb->addChild(
+ $course->getTitle(),
+ [
+ 'uri' => $this->generateUrl(
+ 'chamilo_course_home_home_index',
+ ['course' => $course->getCode()]
+ ),
+ ]
+ );
+ $breadcrumb->addChild(
+ $this->trans($externalTool->getName())
+ );
+
+ return $this->render(
+ 'ChamiloThemeBundle:Lti:iframe.html.twig',
+ ['tool' => $externalTool, 'course' => $course]
+ );
+ }
+
+ /**
+ * @Route("/", name="chamilo_lti_configure")
+ * @Route("/add/{id}", name="chamilo_lti_configure_global", requirements={"id"="\d+"})
+ *
+ * @Security("has_role('ROLE_TEACHER')")
+ *
+ * @param string $id
+ * @param Request $request
+ *
+ * @return Response
+ */
+ public function courseConfigureAction($id = '', Request $request): Response
+ {
+ $em = $this->getDoctrine()->getManager();
+ $repo = $em->getRepository('ChamiloLtiBundle:ExternalTool');
+
+ $tool = new ExternalTool();
+ $parentTool = null;
+
+ if (!empty($id)) {
+ $parentTool = $repo->findOneBy(['id' => $id, 'course' => null]);
+
+ if (empty($parentTool)) {
+ throw $this->createNotFoundException('External tool not found');
+ }
+
+ $tool = clone $parentTool;
+ $tool->setParent($parentTool);
+ }
+
+ $course = $this->getCourse();
+
+ $form = $this->createForm(ExternalToolType::class, $tool);
+ $form->get('shareName')->setData($tool->isSharingName());
+ $form->get('shareEmail')->setData($tool->isSharingEmail());
+ $form->get('sharePicture')->setData($tool->isSharingPicture());
+ $form->handleRequest($request);
+
+ if (!$form->isSubmitted() || !$form->isValid()) {
+ $this->setConfigureBreadcrumb($course);
+
+ return $this->render(
+ '@ChamiloTheme/Lti/course_configure.twig',
+ [
+ 'title' => $this->trans('Add external tool'),
+ 'added_tools' => $repo->findBy(['course' => $course]),
+ 'global_tools' => $repo->findBy(['parent' => null, 'course' => null]),
+ 'form' => $form->createView(),
+ 'course' => $course,
+ ]
+ );
+ }
+
+ /** @var ExternalTool $tool */
+ $tool = $form->getData();
+ $tool->setCourse($course);
+
+ $em->persist($tool);
+ $em->flush();
+
+ $this->addFlash('success', $this->trans('External tool added'));
+
+ if (!$tool->isActiveDeepLinking()) {
+ $courseTool = new CTool();
+ $courseTool
+ ->setCourse($course)
+ ->setImage('plugin.png')
+ ->setName($tool->getName())
+ ->setVisibility(true)
+ ->setTarget('_self')
+ ->setCategory('interaction')
+ ->setLink(
+ $this->generateUrl(
+ 'chamilo_lti_show',
+ ['code' => $course->getCode(), 'id' => $tool->getId()]
+ )
+ );
+
+ $em->persist($courseTool);
+ $em->flush();
+
+ return $this->redirectToRoute(
+ 'chamilo_course_home_home_index',
+ ['course' => $course->getCode()]
+ );
+ }
+
+ return $this->redirectToRoute(
+ 'chamilo_lti_configure',
+ ['course' => $course->getCode()]
+ );
+ }
+
+ /**
+ * @param Course $course
+ */
+ private function setConfigureBreadcrumb(Course $course)
+ {
+ $breadcrumb = $this->get('chamilo_core.block.breadcrumb');
+ $breadcrumb->addChild(
+ $course->getTitle(),
+ [
+ 'uri' => $this->generateUrl(
+ 'chamilo_course_home_home_index',
+ ['course' => $course->getCode()]
+ ),
+ ]
+ );
+ $breadcrumb->addChild(
+ $this->trans('Configure external tool')
+ );
+ }
+
/**
* @param array $params
* @param array $customParams
@@ -446,77 +653,6 @@ class CourseController extends BaseController
];
}
- /**
- * @Route("/item_return", name="chamilo_lti_return_item")
- *
- * @param Request $request
- *
- * @return Response
- */
- public function returnItemAction(Request $request): Response
- {
- $contentItems = $request->get('content_items');
- $data = $request->get('data');
-
- if (empty($contentItems) || empty($data)) {
- throw $this->createAccessDeniedException();
- }
-
- $em = $this->getDoctrine()->getManager();
-
- /** @var ExternalTool $tool */
- $tool = $em->find('ChamiloLtiBundle:ExternalTool', str_replace('tool:', '', $data));
-
- if (empty($tool)) {
- throw $this->createNotFoundException('External tool not found');
- }
-
- $course = $this->getCourse();
- $url = $this->generateUrl(
- 'chamilo_lti_return_item',
- ['code' => $course->getCode()],
- UrlGeneratorInterface::ABSOLUTE_URL
- );
-
- $signatureIsValid = Utils::checkRequestSignature(
- $url,
- $request->get('oauth_consumer_key'),
- $request->get('oauth_signature'),
- $tool
- );
-
- if (!$signatureIsValid) {
- throw $this->createAccessDeniedException();
- }
-
- $contentItems = json_decode($contentItems, true)['@graph'];
-
- $supportedItemTypes = ['LtiLinkItem'];
-
- foreach ($contentItems as $contentItem) {
- if (!in_array($contentItem['@type'], $supportedItemTypes)) {
- continue;
- }
-
- if ('LtiLinkItem' === $contentItem['@type']) {
- $newTool = $this->createLtiLink($contentItem, $tool);
-
- $this->addFlash(
- 'success',
- sprintf(
- $this->trans('External tool added: %s'),
- $newTool->getName()
- )
- );
- }
- }
-
- return $this->render(
- '@ChamiloTheme/Lti/item_return.html.twig',
- ['course' => $course]
- );
- }
-
/**
* @param array $contentItem
* @param ExternalTool $baseTool
@@ -574,141 +710,4 @@ class CourseController extends BaseController
return $newTool;
}
-
- /**
- * @Route("/{id}", name="chamilo_lti_show", requirements={"id"="\d+"})
- *
- * @param string $id
- *
- * @return Response
- */
- public function showAction($id): Response
- {
- $course = $this->getCourse();
-
- $em = $this->getDoctrine()->getManager();
-
- /** @var ExternalTool|null $externalTool */
- $externalTool = $em->find('ChamiloLtiBundle:ExternalTool', $id);
-
- if (empty($externalTool)) {
- throw $this->createNotFoundException();
- }
-
- if (empty($externalTool->getCourse()) || $externalTool->getCourse()->getId() !== $course->getId()) {
- throw $this->createAccessDeniedException('');
- }
-
- $breadcrumb = $this->get('chamilo_core.block.breadcrumb');
- $breadcrumb->addChild(
- $course->getTitle(),
- [
- 'uri' => $this->generateUrl(
- 'chamilo_course_home_home_index',
- ['course' => $course->getCode()]
- ),
- ]
- );
- $breadcrumb->addChild(
- $this->trans($externalTool->getName())
- );
-
- return $this->render(
- 'ChamiloThemeBundle:Lti:iframe.html.twig',
- ['tool' => $externalTool, 'course' => $course]
- );
- }
-
- /**
- * @Route("/", name="chamilo_lti_configure")
- * @Route("/add/{id}", name="chamilo_lti_configure_global", requirements={"id"="\d+"})
- *
- * @Security("has_role('ROLE_TEACHER')")
- *
- * @param string $id
- * @param Request $request
- *
- * @return Response
- */
- public function courseConfigureAction($id = '', Request $request): Response
- {
- $em = $this->getDoctrine()->getManager();
- $repo = $em->getRepository('ChamiloLtiBundle:ExternalTool');
-
- $tool = new ExternalTool();
- $parentTool = null;
-
- if (!empty($id)) {
- $parentTool = $repo->findOneBy(['id' => $id, 'course' => null]);
-
- if (empty($parentTool)) {
- throw $this->createNotFoundException('External tool not found');
- }
-
- $tool = clone $parentTool;
- $tool->setParent($parentTool);
- }
-
- $course = $this->getCourse();
-
- $form = $this->createForm(ExternalToolType::class, $tool);
- $form->get('shareName')->setData($tool->isSharingName());
- $form->get('shareEmail')->setData($tool->isSharingEmail());
- $form->get('sharePicture')->setData($tool->isSharingPicture());
- $form->handleRequest($request);
-
- if (!$form->isSubmitted() || !$form->isValid()) {
- $this->setConfigureBreadcrumb($course);
-
- return $this->render(
- '@ChamiloTheme/Lti/course_configure.twig',
- [
- 'title' => $this->trans('Add external tool'),
- 'added_tools' => $repo->findBy(['course' => $course]),
- 'global_tools' => $repo->findBy(['parent' => null, 'course' => null]),
- 'form' => $form->createView(),
- 'course' => $course,
- ]
- );
- }
-
- /** @var ExternalTool $tool */
- $tool = $form->getData();
- $tool->setCourse($course);
-
- $em->persist($tool);
- $em->flush();
-
- $this->addFlash('success', $this->trans('External tool added'));
-
- if (!$tool->isActiveDeepLinking()) {
- $courseTool = new CTool();
- $courseTool
- ->setCourse($course)
- ->setImage('plugin.png')
- ->setName($tool->getName())
- ->setVisibility(true)
- ->setTarget('_self')
- ->setCategory('interaction')
- ->setLink(
- $this->generateUrl(
- 'chamilo_lti_show',
- ['code' => $course->getCode(), 'id' => $tool->getId()]
- )
- );
-
- $em->persist($courseTool);
- $em->flush();
-
- return $this->redirectToRoute(
- 'chamilo_course_home_home_index',
- ['course' => $course->getCode()]
- );
- }
-
- return $this->redirectToRoute(
- 'chamilo_lti_configure',
- ['course' => $course->getCode()]
- );
- }
}
diff --git a/src/LtiBundle/Entity/ExternalTool.php b/src/LtiBundle/Entity/ExternalTool.php
index 7eb72ead74..239b7f84b8 100644
--- a/src/LtiBundle/Entity/ExternalTool.php
+++ b/src/LtiBundle/Entity/ExternalTool.php
@@ -18,7 +18,7 @@ use Doctrine\ORM\Mapping as ORM;
class ExternalTool
{
/**
- * @var integer
+ * @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
@@ -118,6 +118,11 @@ class ExternalTool
$this->children = new ArrayCollection();
}
+ public function __clone()
+ {
+ $this->id = 0;
+ }
+
/**
* @return int
*/
@@ -307,31 +312,6 @@ class ExternalTool
return $params;
}
- /**
- * Map the key from custom param.
- *
- * @param string $key
- *
- * @return string
- */
- private static function parseCustomKey($key)
- {
- $newKey = '';
- $key = strtolower($key);
- $split = str_split($key);
- foreach ($split as $char) {
- if (
- ($char >= 'a' && $char <= 'z') || ($char >= '0' && $char <= '9')
- ) {
- $newKey .= $char;
- continue;
- }
- $newKey .= '_';
- }
-
- return $newKey;
- }
-
/**
* Get activeDeepLinking.
*
@@ -497,8 +477,28 @@ class ExternalTool
return $this;
}
- public function __clone()
+ /**
+ * Map the key from custom param.
+ *
+ * @param string $key
+ *
+ * @return string
+ */
+ private static function parseCustomKey($key)
{
- $this->id = 0;
+ $newKey = '';
+ $key = strtolower($key);
+ $split = str_split($key);
+ foreach ($split as $char) {
+ if (
+ ($char >= 'a' && $char <= 'z') || ($char >= '0' && $char <= '9')
+ ) {
+ $newKey .= $char;
+ continue;
+ }
+ $newKey .= '_';
+ }
+
+ return $newKey;
}
-}
\ No newline at end of file
+}