Add unoconv support see BT#7058

1.10.x
Julio Montoya 10 years ago
parent 00ef924443
commit 4ff6568d67
  1. 6
      composer.json
  2. 9
      main/inc/lib/api.lib.php
  3. 77
      main/wiki/wiki.inc.php
  4. 16
      src/Chamilo/CoreBundle/Component/Editor/Driver/CourseDriver.php
  5. 287
      src/Chamilo/CoreBundle/Component/Filesystem/Data.php

@ -32,7 +32,6 @@
},
"require": {
"php": ">=5.4",
"php-ffmpeg/php-ffmpeg": "~0.6",
"sabre/vobject": "~3.1",
"toin0u/digitalocean": "~1.4",
"twig/twig": "1.*",
@ -79,7 +78,10 @@
"bower-asset/simplewebrtc": "@stable",
"clue/graph": "~0.9.0",
"graphp/graphviz": "~0.2.0",
"graphp/algorithms": "~0.8.0"
"graphp/algorithms": "~0.8.0",
"sunra/php-simple-html-dom-parser": "~1.5.0",
"media-alchemyst/media-alchemyst": "0.4.8",
"php-ffmpeg/php-ffmpeg": "0.5.1"
},
"require-dev": {
"behat/behat": "2.5.*@stable",

@ -7415,15 +7415,6 @@ function convert_double_quote_to_single($in_text) {
return api_preg_replace('/"/', "''", $in_text);
}
/**
* Is unoconv installed
* @return bool
*/
function api_is_unoconv_installed()
{
return false;
}
/**
* Get origin
*

@ -4,6 +4,10 @@
use Chamilo\CoreBundle\Component\Editor\Connector;
use Chamilo\CoreBundle\Component\Filesystem\Data;
use ChamiloSession as Session;
use MediaAlchemyst\Alchemyst;
use MediaAlchemyst\DriversContainer;
use Neutron\TemporaryFilesystem\Manager;
use Neutron\TemporaryFilesystem\TemporaryFilesystem;
use Symfony\Component\Filesystem\Filesystem;
/**
@ -276,23 +280,17 @@ class Wiki
'assignment' => null
);
$pageId = intval($values['page_id']);
// NOTE: visibility, visibility_disc and ratinglock_disc changes are not made here, but through the interce buttons
// cleaning the variables
$_clean['page_id'] = intval($values['page_id']);
$_clean['reflink'] = Database::escape_string(trim($values['reflink']));
$_clean['title'] = Database::escape_string(trim($values['title']));
$_clean['content'] = Database::escape_string($values['content']);
if (api_get_setting('htmlpurifier_wiki') == 'true'){
//$purifier = new HTMLPurifier();
$_clean['content'] = Security::remove_XSS($_clean['content']);
$values['content'] = Security::remove_XSS($values['content']);
}
$_clean['user_id'] = api_get_user_id();
$_clean['assignment']= Database::escape_string($values['assignment']);
$_clean['comment'] = Database::escape_string($values['comment']);
$_clean['progress'] = Database::escape_string($values['progress']);
$_clean['version'] = intval($values['version']) + 1 ;
$_clean['linksto'] = self::links_to($_clean['content']); //and check links content
$version = intval($values['version']) + 1 ;
$linkTo = self::links_to($_clean['content']); //and check links content
//cleaning config variables
if (!empty($values['task'])) {
@ -338,18 +336,18 @@ class Wiki
'visibility_disc' => 1,
'addlock_disc' => 1,
'ratinglock_disc' => 1,
'page_id' => $_clean['page_id'],
'reflink' => $_clean['reflink'],
'title' => $_clean['title'],
'content' => $_clean['content'],
'user_id' => $_clean['user_id'],
'page_id' => $pageId,
'reflink' => trim($values['reflink']),
'title' => trim($values['title']),
'content' => $values['content'],
'user_id' => api_get_user_id(),
'group_id' => $groupId,
'dtime' => $dtime,
'assignment' => $_clean['assignment'],
'comment' => $_clean['comment'],
'progress' => $_clean['progress'],
'version' => $_clean['version'],
'linksto' => $_clean['linksto'],
'assignment' => $values['assignment'],
'comment' => $values['comment'],
'progress' => $values['progress'],
'version' => $version,
'linksto' => $linkTo,
'user_ip' => $_SERVER['REMOTE_ADDR'],
'session_id' => $session_id,
];
@ -371,7 +369,7 @@ class Wiki
);
}
if ($_clean['page_id'] == 0) {
if ($pageId == 0) {
$sql = 'UPDATE '.$tbl_wiki.' SET
page_id="'.$id.'"
WHERE c_id = '.$course_id.' AND id="'.$id.'"';
@ -403,7 +401,7 @@ class Wiki
enddate_assig="'.$_clean['enddate_assig'].'",
delayedsubmit="'.$_clean['delayedsubmit'].'"
WHERE
page_id = "'.$_clean['page_id'].'" AND
page_id = "'.$pageId.'" AND
c_id = '.$course_id;
Database::query($sql);
}
@ -417,7 +415,7 @@ class Wiki
api_get_user_id(),
$groupId
);
self::check_emailcue($_clean['reflink'], 'P', $dtime, $_clean['user_id']);
self::check_emailcue($_clean['reflink'], 'P', $dtime, api_get_user_id());
$this->setWikiData($id);
return get_lang('Saved');
@ -960,9 +958,10 @@ class Wiki
echo '</span>';
}
if (api_is_unoconv_installed()) {
$unoconv = api_get_configuration_value('unoconv.binaries');
if ($unoconv) {
echo '<span style="float:right;">';
echo '<a href="'.api_get_path(WEB_CODE_PATH).'wiki/index.php?action=export_to_doc_file&id='.$row['id'].'">'.
echo '<a href="'.api_get_path(WEB_CODE_PATH).'wiki/index.php?action=export_to_doc_file&id='.$row['id'].'&'.api_get_cidreq().'">'.
Display::return_icon('export_doc.png', get_lang('ExportToDoc'), array(), ICON_SIZE_SMALL).'</a>';
echo '</span>';
}
@ -5240,17 +5239,33 @@ class Wiki
*/
public function exportTo($id, $format = 'doc')
{
$unoconv = api_get_configuration_value('unoconv.binaries');
if (empty($unoconv)) {
return false;
}
$data = self::get_wiki_data($id);
if (!empty($data['content'])) {
$fs = new Filesystem();
$paths = ['root_sys' => api_get_path(SYS_PATH)];
$paths = [
'root_sys' => api_get_path(SYS_PATH),
'path.temp' => api_get_path(SYS_ARCHIVE_PATH),
];
$connector = new Connector();
$data = new Data($paths, $fs, $connector);
$content = $data->convertRelativeToAbsoluteUrl($data['content']);
$filePath = $data->putContentInTempFile($content, $data['reflink'], 'html');
$convertedFile = $data->transcode($filePath, $format);
$drivers = new DriversContainer();
$drivers['configuration'] = array(
'unoconv.binaries' => $unoconv,
'unoconv.timeout' => 60,
);
$tempFilesystem = TemporaryFilesystem::create();
$manager = new Manager($tempFilesystem, $fs);
$alchemyst = new Alchemyst($drivers, $manager);
$dataFileSystem = new Data($paths, $fs, $connector, $alchemyst);
$content = $dataFileSystem->convertRelativeToAbsoluteUrl($data['content']);
$filePath = $dataFileSystem->putContentInTempFile($content, $data['reflink'], 'html');
$convertedFile = $dataFileSystem->transcode($filePath, $format);
DocumentManager::file_send_for_download($convertedFile);
}
return false;

@ -5,6 +5,7 @@ namespace Chamilo\CoreBundle\Component\Editor\Driver;
/**
* Class CourseDriver
*
* @package Chamilo\CoreBundle\Component\Editor\Driver
*
*/
@ -111,7 +112,7 @@ class CourseDriver extends Driver implements DriverInterface
{
$url = null;
if ($this->allow()) {
$directory = $this->connector->course['directory'];
$directory = $this->getCourseDirectory();
$coursePath = $this->connector->paths['sys_course_path'];
$url = $coursePath.$directory.'/document/';
}
@ -126,7 +127,7 @@ class CourseDriver extends Driver implements DriverInterface
{
$url = null;
if ($this->allow()) {
$directory = $this->connector->course['directory'];
$directory = $this->getCourseDirectory();
$url = api_get_path(REL_COURSE_PATH).$directory.'/document/';
}
@ -141,13 +142,22 @@ class CourseDriver extends Driver implements DriverInterface
{
$url = null;
if ($this->allow()) {
$directory = $this->connector->course->getDirectory();
$directory = $this->getCourseDirectory();
$url = api_get_path(WEB_COURSE_PATH).$directory.'/document/';
}
return $url;
}
/**
*
* @return string
*/
public function getCourseDirectory()
{
return $this->connector->course['directory'];
}
/**
* {@inheritdoc}
*/

@ -0,0 +1,287 @@
<?php
/* For licensing terms, see /license.txt */
namespace Chamilo\CoreBundle\Component\Filesystem;
use Chamilo\CoreBundle\Component\Editor\Connector;
use Chamilo\CoreBundle\Component\Editor\Driver\CourseDriver;
use Chamilo\UserBundle\Entity\User;
use MediaAlchemyst\Alchemyst;
use Sunra\PhpSimple\HtmlDomParser;
use Symfony\Component\Console;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Finder\Finder;
use Symfony\Component\Finder\SplFileInfo;
use Unoconv\Unoconv;
/**
* @todo use Gaufrette to manage course files (some day)
* @todo add security restrictions.
* Class DataFilesystem
* @package Chamilo\CoreBundle\Component\DataFilesystem
*/
class Data
{
/** @var array Chamilo paths */
private $paths;
/** @var Filesystem */
private $fs;
private $connector;
private $converter;
/**
* @param array $paths
* @param Filesystem $filesystem
* @param Connector $connector
* @param Alchemyst $converter
*/
public function __construct(
$paths,
Filesystem $filesystem,
Connector $connector,
$converter = null
) {
$this->paths = $paths;
$this->fs = $filesystem;
$this->converter = $converter;
$this->connector = $connector;
$this->connector->setDriver('CourseDriver');
}
/**
* Gets a file from the "data" folder
* @param string $file
*
* @return SplFileInfo
* @throws \InvalidArgumentException
*/
public function get($file)
{
$file = new SplFileInfo($this->paths['sys_data_path'].$file, null, null);
if ($this->fs->exists($file)) {
return $file;
} else {
throw new \InvalidArgumentException(
sprintf(
'The file "%s" does not exists .',
$file
)
);
}
}
/**
* Gets a file from the data/courses/MATHS/document directory
* @param string $courseCode
* @param string $file
*
* @return SplFileInfo
*/
public function getCourseDocument($courseCode, $file)
{
$file = 'courses/'.$courseCode.'/document/'.$file;
return $this->get($file);
}
/**
* Gets a file from the data/courses/MATHS/scorm directory
* @param string $courseCode
* @param string $file
*
* @return SplFileInfo
*/
public function getCourseScormDocument($courseCode, $file)
{
$file = 'courses/'.$courseCode.'/scorm/'.$file;
return $this->get($file);
}
/**
* Gets a file from the data/courses/MATHS/document directory
* @param string $courseCode
* @param string $file
*
* @return SplFileInfo
*/
public function getCourseUploadFile($courseCode, $file)
{
$file = 'courses/'.$courseCode.'/upload/'.$file;
return $this->get($file);
}
/**
* Create folders
* @param array $folderList
* @param OutputInterface $output
* @param string $folderPermissions
*/
public function createFolders(
array $folderList,
OutputInterface $output = null,
$folderPermissions = null
) {
if (empty($folderPermissions)) {
$folderPermissions = api_get_permissions_for_new_directories();
}
if (!empty($folderList)) {
foreach ($folderList as $folder) {
if (!is_dir($folder)) {
$this->fs->mkdir($folder, $folderPermissions);
if ($output) {
$output->writeln("Folder <comment>'$folder'</comment> created");
}
}
}
}
}
/**
* @param array $folderList
* @param OutputInterface $output
*/
public function copyFolders(array $folderList, OutputInterface $output = null)
{
if (!empty($folderList)) {
foreach ($folderList as $folderSource => $folderDestination) {
$this->fs->mirror($folderSource, $folderDestination);
$finder = new Finder();
$files = $finder->files()->in($folderDestination);
$this->fs->chmod($files, api_get_permissions_for_new_directories());
if ($output) {
$output->writeln("Contents were copied from <comment>$folderSource</comment> to <comment>$folderDestination</comment>");
}
}
}
}
/**
* @return Finder
*/
public function getStyleSheetFolders()
{
$finder = new Finder();
$styleSheetFolder = $this->paths['root_sys'].'main/css';
return $finder->directories()->depth('== 0')->in($styleSheetFolder);
}
/**
* Creates a empty file inside the temp folder
* @param string $fileName
* @param string $extension
*
* @return string
*/
public function createTempFile($fileName = null, $extension = null)
{
if (empty($fileName)) {
$fileName = mt_rand();
}
if (!empty($extension)) {
$extension = ".$extension";
}
$filePath = $this->paths['path.temp'].$fileName.$extension;
$this->fs->touch($filePath);
if ($this->fs->exists($filePath)) {
return $filePath;
}
return null;
}
/**
* Converts ../courses/ABC/document/file.jpg to
* http://chamilo/courses/ABC/document/file.jpg
* @param string $content
*
* @return string
*/
public function convertRelativeToAbsoluteUrl($content)
{
/** @var CourseDriver $courseDriver */
$courseDriver = $this->connector->getDriver('CourseDriver');
$dom = HtmlDomParser::str_get_html($content);
/** @var \simple_html_dom_node $image */
foreach ($dom->find('img') as $image) {
$image->src = str_replace(
$courseDriver->getCourseDocumentRelativeWebPath(),
$courseDriver->getCourseDocumentWebPath(),
$image->src
);
}
return $dom;
}
/**
* Save string in a temp file.
*
* @param string $content
* @param string $fileName
* @param string $extension
*
* @return string file path
*/
public function putContentInTempFile($content, $fileName = null, $extension = null)
{
$file = $this->createTempFile($fileName, $extension);
if (!empty($file)) {
$this->fs->dumpFile($file, $content);
return $file;
}
return null;
}
/**
* @param string $filePath
* @param string $format
*
* @return string
*/
public function transcode($filePath, $format)
{
if ($this->fs->exists($filePath)) {
$fileInfo = pathinfo($filePath);
$fileName = $fileInfo['filename'];
$newFilePath = str_replace(
$fileInfo['basename'],
$fileName.'.'.$format, $filePath
);
/** @var \MediaAlchemyst\DriversContainer $drivers */
$drivers = $this->converter->getDrivers();
$unoconv = $drivers['unoconv'];
/** @var Unoconv $unoconv */
//$drivers = $this->converter->turnInto($filePath, $newFilePath);
$unoconv->transcode($filePath, $format, $newFilePath);
if ($this->fs->exists($newFilePath)) {
return $newFilePath;
}
}
return false;
}
/**
* Creates the users/upload/X/my_files folder
* @param User $user
*/
public function createMyFilesFolder(User $user)
{
$userId = $user->getUserId();
$path = \UserManager::get_user_picture_path_by_id($userId, 'system');
if (!$this->fs->exists($path['dir'].'my_files')) {
$this->createFolders(array($path['dir'].'my_files'));
}
}
}
Loading…
Cancel
Save