Merge branch '3.7'

This commit is contained in:
Romain Neutron
2013-03-22 15:01:00 +01:00
12 changed files with 352 additions and 155 deletions

View File

@@ -38,6 +38,10 @@
"doctrine/data-fixtures" : "dev-master"
},
"repositories": [
{
"type": "git",
"url": "https://github.com/romainneutron/Imagine.git"
},
{
"type" : "git",
"url" : "https://github.com/winmillwill/BadFaith"

27
composer.lock generated
View File

@@ -599,14 +599,17 @@
"require-dev": {
"sami/sami": "dev-master"
},
"time": "2012-12-13 18:31:18",
"suggest": {
"ext-gd": "to use the GD implementation",
"ext-gmagick": "to use the Gmagick implementation",
"ext-imagick": "to use the Imagick implementation"
},
"type": "library",
"autoload": {
"psr-0": {
"Imagine": "lib/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
@@ -620,11 +623,12 @@
"description": "Image processing for PHP 5.3",
"homepage": "http://imagine.readthedocs.org/",
"keywords": [
"image manipulation",
"image processing",
"drawing",
"graphics"
]
"graphics",
"image manipulation",
"image processing"
],
"time": "2013-03-21 10:11:30"
},
{
"name": "knplabs/knp-snappy",
@@ -738,13 +742,14 @@
],
"description": "An Object Oriented wrapper for easy multimedia conversion, based on Imagine, FFMpeg, SwfTools, Unoconv and other libs",
"keywords": [
"image processing",
"image",
"audio",
"video processing",
"audio processing",
"image",
"image processing",
"video",
"audio processing"
]
"video processing"
],
"time": "2013-03-21 09:21:45"
},
{
"name": "mediavorus/mediavorus",

View File

@@ -12,6 +12,7 @@
namespace Alchemy\Phrasea\Controller\Prod;
use Alchemy\Phrasea\Controller\RecordsRequest;
use Alchemy\Phrasea\Exception\RuntimeException;
use DataURI;
use Silex\Application;
use Silex\ControllerProviderInterface;
@@ -113,27 +114,29 @@ class Tools implements ControllerProviderInterface
$controllers->post('/hddoc/', function(Application $app, Request $request) {
$success = false;
$errorMessage = "";
$fileName = null;
$message = _('An error occured');
if ($file = $request->files->get('newHD')) {
if ($file->isValid()) {
$fileName = $file->getClientOriginalName();
$size = $file->getClientSize();
$tempoFile = tempnam(sys_get_temp_dir(), 'substit');
unlink($tempoFile);
mkdir($tempoFile);
$tempoFile = $tempoFile . DIRECTORY_SEPARATOR . $fileName;
copy($file->getPathname(), $tempoFile);
try {
$tempoDir = tempnam(sys_get_temp_dir(), 'substit');
unlink($tempoDir);
mkdir($tempoDir);
$tempoFile = $tempoDir . DIRECTORY_SEPARATOR . $fileName;
if (false === rename($file->getPathname(), $tempoFile)) {
throw new RuntimeException('Error while renaming file');
}
$record = new \record_adapter(
$app,
$request->request->get('sbas_id')
, $request->request->get('record_id')
$request->get('sbas_id'),
$request->get('record_id')
);
$media = $app['mediavorus']->guess($tempoFile);
@@ -144,72 +147,73 @@ class Tools implements ControllerProviderInterface
$record->set_original_name($fileName);
$app['phraseanet.SE']->updateRecord($record);
}
$success = true;
} catch (\Exception $e) {
$errorMessage = $e->getMessage();
}
unlink($tempoFile);
rmdir(dirname($tempoFile));
unlink($file->getPathname());
rmdir($tempoDir);
$success = true;
$message = _('Document has been successfully substitued');
} catch (\Exception $e) {
$message = _('file is not valid');
}
} else {
$errorMessage = _('file is not valid');
$message = _('file is not valid');
}
} else {
$app->abort(400, 'Missing file parameter');
}
$template = 'prod/actions/Tools/iframeUpload.html.twig';
$var = array(
'success' => $success
, 'fileName' => $fileName
, 'errorMessage' => $errorMessage
);
return $app['twig']->render($template, $var);
return $app['twig']->render('prod/actions/Tools/iframeUpload.html.twig', array(
'success' => $success,
'message' => $message,
));
});
$controllers->post('/chgthumb/', function(Application $app, Request $request) {
$success = false;
$errorMessage = "";
$message = _('An error occured');
if ($file = $request->files->get('newThumb')) {
$size = $file->getClientSize();
$fileName = $file->getClientOriginalName();
if ($size && $fileName && $file->isValid()) {
if ($file->isValid()) {
try {
$rootPath = $app['phraseanet.registry']->get('GV_RootPath');
$tmpFile = $rootPath . 'tmp/' . $fileName;
rename($file->getPathname(), $tmpFile);
$fileName = $file->getClientOriginalName();
$tempoDir = tempnam(sys_get_temp_dir(), 'substit');
unlink($tempoDir);
mkdir($tempoDir);
$tempoFile = $tempoDir . DIRECTORY_SEPARATOR . $fileName;
if (false === rename($file->getPathname(), $tempoFile)) {
throw new RuntimeException('Error while renaming file');
}
$record = new \record_adapter(
$app,
$request->request->get('sbas_id')
, $request->request->get('record_id')
$request->get('sbas_id'),
$request->get('record_id')
);
$media = $app['mediavorus']->guess($tmpFile);
$media = $app['mediavorus']->guess($tempoFile);
$record->substitute_subdef('thumbnail', $media, $app);
unlink($tempoFile);
rmdir($tempoDir);
$success = true;
$message = _('Thumbnail has been successfully substitued');
} catch (\Exception $e) {
$errorMessage = $e->getMessage();
var_dump($e->getMessage());
$message = _('file is not valid');
}
} else {
$errorMessage = _('file is not valid');
$message = _('file is not valid');
}
} else {
$app->abort(400, 'Missing file parameter');
}
$template = 'prod/actions/Tools/iframeUpload.html.twig';
$var = array(
'success' => $success
, 'fileName' => $fileName
, 'errorMessage' => $errorMessage
);
return $app['twig']->render($template, $var);
}
return $app['twig']->render('prod/actions/Tools/iframeUpload.html.twig', array(
'success' => $success,
'message' => $message,
));
});
$controllers->post('/thumb-extractor/confirm-box/', function(Application $app, Request $request) {

View File

@@ -1,7 +1,4 @@
<div class='content'>
{% if not success %}
{% trans 'an error occured' %}
{{errorMessage}}
{% endif %}
<div class='content {% if not success %}text-error{% endif %}'>
{{ message }}
</div>

View File

@@ -57,7 +57,7 @@
</a>
</li>
{% endif %}
{% if selectionLength == 1 and app['phraseanet.registry'].get('GV_seeOngChgDoc') %}
{% if selectionLength == 1 and (app['phraseanet.registry'].get('GV_seeOngChgDoc') or app['phraseanet.registry'].get('GV_seeNewThumb')) %}
<li>
<a href="#substitution">
{% trans "substitution" %}
@@ -73,7 +73,7 @@
{% endif %}
</ul>
</div>
{# subef section #}
{# subdef section #}
<div id="subdefs" class="tabBox">
<form id="new-img-form" action="/prod/tools/image/" method="post">
<fieldset style='border:1px solid #999; padding:20px;'>
@@ -124,7 +124,19 @@
<div class="PNB frame_video">
{% set previewHtml5 = record.getSubdfefByDeviceAndMime(constant('\\databox_subdef::DEVICE_SCREEN'), ['video/ogg', 'video/mp4', 'video/webm']) %}
<video id="thumb_video" controls="" preload="auto">
{% set dataW = constant('media_subdef::TC_DATA_WIDTH') %}
{% set dataH = constant('media_subdef::TC_DATA_HEIGHT') %}
{% set width = record.get_technical_infos(dataW) %}
{% set height = record.get_technical_infos(dataH) %}
{% if width and height %}
{% set ratio = width / height %}
{% else %}
{% set ratio = '' %}
{% endif %}
<video id="thumb_video" controls="" preload="auto" data-ratio="{{ ratio }}">
{% for subdef in previewHtml5 %}
<source type="{{ subdef.get_mime() }}" src="{{ subdef.get_url() }}" />
{% endfor %}
@@ -150,7 +162,7 @@
<img src="/skins/prod/ThumbExtractor/delete.png" />
</div>
<p id='thumb_info'>{% trans 'To take a screenshot click on camera' %}</p>
<canvas id="thumb_canvas" >
<canvas id="thumb_canvas">
</canvas>
</div>
<div class="PNB action_bar_right">
@@ -257,10 +269,13 @@
{% endif %}
{# hd sub section #}
{% if selectionLength == 1 %}
{% for record in records %}
{% if selectionLength == 1 and (app['phraseanet.registry'].get('GV_seeOngChgDoc') or app['phraseanet.registry'].get('GV_seeNewThumb')) %}
{% for record in selection %}
<div id="substitution" class="tabBox">
{% if "unknown" == record.get_type() %}
<i class="icon-warning-sign icon-white"></i>{% trans "Substitution is not possible for this kind of record" %}
{% else %}
{% if app['phraseanet.registry'].get('GV_seeOngChgDoc') %}
<div id="substitution-hd">
<form
@@ -273,8 +288,7 @@
<fieldset style='border:1px solid #999;padding:20px;'>
<legend style='color:#EEE'>&nbsp;<b>{% trans "substitution HD" %}</b>&nbsp;</legend>
<div>
<input type="hidden" name="MAX_FILE_SIZE" value="20000000" />
<input id='new-hd-file' name="newHD" type="file" />
<input id='new-hd-file' name="newHD" type="file"/>
<br />
<label for="CCFNALP" class="checkbox">
<input type="checkbox" name="ccfilename" id="CCFNALP" value="1">
@@ -306,7 +320,6 @@
<fieldset style='border:1px solid #999;padding:20px;'>
<legend style='color:#EEE'>&nbsp;<b>{% trans "substitution SD" %}</b>&nbsp;</legend>
<div>
<input type="hidden" name="MAX_FILE_SIZE" value="20000000" />
<input id='new-sd-file' name="newThumb" type="file" />
<input type="hidden" name="sbas_id" value="{{record.get_sbas_id()}}" />
<input type="hidden" name="record_id" value="{{record.get_record_id()}}" />
@@ -321,6 +334,7 @@
<div class='resultAction'></div>
</div>
{% endif %}
{% endif %}
</div>
{% endfor %}
{% endif %}

View File

@@ -77,6 +77,11 @@
<img style="cursor:help;" src="/skins/icons/ok.png" title="{% spaceless %}{{title|e}}{% endspaceless %}" />
{% endif %}
{% endif %}
<div style="position:absolute;bottom:4px;right:4px;">
<img class="infoTips" tooltipsrc="/prod/tooltip/tc_datas/{{element.get_sbas_id()}}/{{element.get_record_id()}}/" src="/skins/icons/info.gif"/>
<div tooltipsrc="/prod/tooltip/preview/{{element.get_sbas_id()}}/{{element.get_record_id()}}/" class="previewTips"></div>
<div tooltipsrc="/prod/tooltip/caption/{{element.get_sbas_id()}}/{{element.get_record_id()}}/preview/" class="captionRolloverTips"></div>
</div>
<input type="hidden" name="order_element_id" value="{{order_element_id}}"/>
</div>
</li>
@@ -155,6 +160,13 @@ $(document).ready(function(){
$this.addClass('last_selected');
});
$('.captionTips, .captionRolloverTips, .infoTips', dialog.getDomElement()).tooltip({
delay:0
});
$('.previewTips', dialog.getDomElement()).tooltip({
fixable:true
});
$('button.send', dialog.getDomElement()).bind('click',function(){
send_documents(order_id);
});

View File

@@ -0,0 +1,64 @@
<?php
namespace Alchemy\Tests\Phrasea\Controller\Prod;
use Symfony\Component\HttpFoundation\File\UploadedFile;
class ControllerToolsTest extends \PhraseanetWebTestCaseAuthenticatedAbstract
{
protected $client;
protected $tmpFile;
public function setUp()
{
parent::setUp();
$this->tmpFile = sys_get_temp_dir() . '/' . time() . mt_rand(1000, 9999) . '.jpg';
copy(__DIR__ . '/../../../../../files/cestlafete.jpg', $this->tmpFile);
}
public function tearDown()
{
if (file_exists($this->tmpFile)) {
unlink($this->tmpFile);
}
parent::tearDown();
}
public function testRouteChangeDoc()
{
$record = self::$DI['record_1'];
$crawler = self::$DI['client']->request('POST', '/prod/tools/hddoc/', array(
'sbas_id' => $record->get_sbas_id(),
'record_id' => $record->get_record_id(),
), array(
'newHD' => new UploadedFile(
$this->tmpFile, 'KIKOO.JPG', 'image/jpg', 2000
)
));
$response = self::$DI['client']->getResponse();
$message = trim($crawler->filterXPath('//div')->text());
$this->assertEquals(200, $response->getStatusCode());
$this->assertEquals(_('Document has been successfully substitued'), $message);
}
public function testRouteChangeThumb()
{
$record = self::$DI['record_1'];
$crawler = self::$DI['client']->request('POST', '/prod/tools/chgthumb/', array(
'sbas_id' => $record->get_sbas_id(),
'record_id' => $record->get_record_id(),
), array(
'newThumb' => new UploadedFile(
$this->tmpFile, 'KIKOO.JPG', 'image/jpg', 2000
)
));
$response = self::$DI['client']->getResponse();
$message = trim($crawler->filterXPath('//div')->text());
$this->assertEquals(200, $response->getStatusCode());
$this->assertEquals(_('Thumbnail has been successfully substitued'), $message);
}
}

View File

@@ -184,6 +184,59 @@ class API_V1_adapterTest extends PhraseanetPHPUnitAuthenticatedAbstract
}
}
public function testSearch_withOffset()
{
$request = new Request(array(), array(), array(), array(), array(), array('HTTP_Accept' => 'application/json'));
$result = $this->object->search_records($request);
$this->assertEquals(200, $result->get_http_code());
$this->assertEquals('application/json', $result->get_content_type());
$this->assertTrue(is_array(json_decode($result->format(), true)));
$data = json_decode($result->format(), true);
if ($data['response']['total_results'] < 2) {
$this->markTestSkipped('Not enough data to test');
}
$total = $data['response']['total_results'];
$request = new Request(array(
'offset_start' => 0,
'per_page' => 1,
), array(), array(), array(), array(), array('HTTP_Accept' => 'application/json'));
$resultData1 = $this->object->search_records($request);
$data = json_decode($resultData1->format(), true);
$this->assertCount(1, $data['response']['results']);
$result1 = array_pop($data['response']['results']);
$request = new Request(array(
'offset_start' => 1,
'per_page' => 1,
), array(), array(), array(), array(), array('HTTP_Accept' => 'application/json'));
$resultData2 = $this->object->search_records($request);
$data = json_decode($resultData2->format(), true);
$this->assertCount(1, $data['response']['results']);
$result2 = array_pop($data['response']['results']);
// item at offset #0 is different than offset at item #1
$this->assertNotEquals($result1['record_id'], $result2['record_id']);
// last item is last item
$request = new Request(array(
'offset_start' => $total - 1,
'per_page' => 10,
), array(), array(), array(), array(), array('HTTP_Accept' => 'application/json'));
$resultData = $this->object->search_records($request);
$data = json_decode($resultData->format(), true);
$this->assertCount(1, $data['response']['results']);
}
public function testSearch_recordsWithStories()
{
$auth = new \Session_Authentication_None(self::$DI['user']);

View File

@@ -429,8 +429,35 @@
}
}
top -= 10;
height += 20;
if(resizeImgTips)
{
var factor = Math.min((width - 45) / width, (height - 75) / height);
var imgWidth = Math.round(width * factor);
var imgHeight = Math.round(height * factor);
width = imgWidth + 45;
height = imgHeight + 85;
$imgTips.css({
maxWidth: imgWidth,
maxHeight: imgHeight
});
}
if(resizeVideoTips)
{
var factor = Math.min((width - 45) / width, (height - 75) / height);
var imgWidth = Math.round(width * factor);
var imgHeight = Math.round(height * factor);
width = imgWidth + 45;
height = imgHeight + 75;
$videoTips.css({
width: Math.round(imgWidth),
height: Math.round(imgHeight)
});
}
helper.parent.css({
width: Math.round(width),
@@ -439,22 +466,6 @@
top: top
});
if(resizeImgTips)
{
$imgTips.css({
maxWidth: Math.round(width - 50),
maxHeight: Math.round(height-70)
});
}
if(resizeVideoTips)
{
$videoTips.css({
width: Math.round(width - 50),
height: Math.round(height-70)
});
}
}
}

View File

@@ -6,12 +6,23 @@
*****************/
var Canva = function(domCanva){
this.domCanva = domCanva;
}
};
Canva.prototype = {
resize : function(elementDomNode){
var h = elementDomNode.getHeight();
var w = elementDomNode.getWidth();
var maxH = elementDomNode.getHeight();
if ('' !== elementDomNode.getAspectRatio()) {
var h = Math.round(w * (1 / elementDomNode.getAspectRatio()));
if (h > maxH) {
var h = maxH;
var w = Math.round(h * elementDomNode.getAspectRatio());
}
} else {
var h = maxH;
}
this.domCanva.setAttribute("width", w);
this.domCanva.setAttribute("height", h);
@@ -20,7 +31,7 @@
},
getContext2d : function(){
if (this.domCanva.getContext == undefined)
if (undefined === this.domCanva.getContext)
{
return G_vmlCanvasManager
.initElement(this.domCanva)
@@ -94,6 +105,7 @@
var Video = function(domElement){
Image.call(this, domElement);
this.aspectRatio = domElement.getAttribute('data-ratio');
};
Video.prototype = new Image();
@@ -101,6 +113,9 @@
Video.prototype.getCurrentTime = function(){
return Math.floor(this.domElement.currentTime);
};
Video.prototype.getAspectRatio = function(){
return this.aspectRatio;
};
/******************
* Cache Object
@@ -148,7 +163,7 @@
this.timestamp = date.getTime();
this.dataURI = canva.extractImage();
this.videoTime = video.getCurrentTime();
}
};
ScreenShot.prototype = {
getId:function(){

View File

@@ -3741,7 +3741,7 @@ dans l'onglet thesaurus : arbres, menus contextuels
#thumbExtractor .main_title {
height: 15px;
font-weight: bold;
top: 15px
top: 15px;
}
#thumbExtractor .part_title_left {
@@ -3780,11 +3780,18 @@ dans l'onglet thesaurus : arbres, menus contextuels
border: 1px solid #1A1B1B;
border-bottom: none;
height: 210px;
line-height:210px;
width: 320px;
top: 50px;
left: 380px;
z-index: 2;
text-align: center
text-align: center;
}
#thumbExtractor #thumb_canvas {
vertical-align:middle;
display:inline-block;
line-height: 20px;
}
#thumbExtractor .action_bar_left {
@@ -3811,7 +3818,7 @@ dans l'onglet thesaurus : arbres, menus contextuels
#thumbExtractor .action_bar_right .action_icon {
padding-right: 10px;
display: table-cell;
vertical-align: middle
vertical-align: middle;
}
#thumbExtractor .action_bar_right .action_icon:hover {
@@ -3825,6 +3832,7 @@ dans l'onglet thesaurus : arbres, menus contextuels
bottom: 10px;
right: 60px;
display: none;
line-height: 20px;
}
#thumbExtractor #thumb_delete_button {
@@ -3833,7 +3841,8 @@ dans l'onglet thesaurus : arbres, menus contextuels
position: absolute;
bottom: 10px;
right: 10px;
display: none
display: none;
line-height: 20px;
}
#thumbExtractor #thumb_delete_button,

View File

@@ -3925,6 +3925,7 @@ dans l'onglet thesaurus : arbres, menus contextuels
border: 1px solid #1A1B1B;
border-bottom: none;
height: 210px;
line-height:210px;
width: 320px;
top: 50px;
left: 380px;
@@ -3932,6 +3933,12 @@ dans l'onglet thesaurus : arbres, menus contextuels
text-align: center;
}
#thumbExtractor #thumb_canvas {
vertical-align:middle;
display:inline-block;
line-height: 20px;
}
#thumbExtractor .action_bar_left {
height: 20px;
width: 320px;
@@ -3970,6 +3977,7 @@ dans l'onglet thesaurus : arbres, menus contextuels
bottom: 10px;
right: 60px;
display: none;
line-height: 20px;
}
#thumbExtractor #thumb_delete_button {
@@ -3979,6 +3987,7 @@ dans l'onglet thesaurus : arbres, menus contextuels
bottom: 10px;
right: 10px;
display: none;
line-height: 20px;
}
#thumbExtractor #thumb_delete_button,