Files
Phraseanet/lib/index_utils2.php
2011-04-27 17:12:16 +02:00

2874 lines
88 KiB
PHP
Raw Blame History

<?php
function get_xml(&$baseprefs, &$propfile, $readmeta=true)
{
global $msg;
$domxml = new DOMDocument('1.0', 'UTF-8');
$domxml->standalone = true;
$domxml->preserveWhiteSpace = false;
$domxml->formatOutput = true;
$element = $domxml->createElement('record');
$domrec = $domxml->appendChild($element);
$domrec->setAttribute('recordid', $propfile['recordid']);
$element = $domxml->createElement('description');
$domdesc = $domrec->appendChild($element);
$debug = false;
$tfields = array();
$cwd = getcwd();
if ($readmeta)
{
$propfile['doctype'] = giveMeDocType($propfile['mime']);
switch ($propfile['doctype'])
{
case 'image' :
get_fields_from_jpg($baseprefs, $propfile, $tfields);
break;
case 'application/pdf';
get_fields_from_jpg($baseprefs, $propfile, $tfields);
get_fields_from_pdf($baseprefs, $propfile, $tfields);
break;
case 'video':
get_fields_from_jpg($baseprefs, $propfile, $tfields);
break;
case 'audio':
get_fields_from_jpg($baseprefs, $propfile, $tfields);
break;
default:
get_fields_from_unknown($baseprefs, $propfile, $tfields);
break;
}
chdir($cwd);
}
$tfields['tf-recordid'] = array(($propfile['recordid']));
$tfields['tf-mimetype'] = array(($propfile['mime']));
$tfields['tf-size'] = array(($propfile['size']));
$tfields['tf-filepath'] = array(($propfile['subpath']));
$tfields['tf-parentdir'] = array(($propfile['parentdirectory']));
$tfields['tf-filename'] = array(($propfile['originalname']));
$tfields['tf-extension'] = isset($propfile['extension']) ? array(($propfile['extension'])) : array();
$tfields['tf-width'] = isset($propfile['width']) ? array(($propfile['width'])) : array();
$tfields['tf-height'] = isset($propfile['height']) ? array(($propfile['height'])) : array();
$tfields['tf-bits'] = isset($propfile['bits']) ? array(($propfile['bits'])) : array();
$tfields['tf-channels'] = isset($propfile['channels']) ? array(($propfile['channels'])) : array();
if ($stat = stat($propfile['hotfolderfile']))
{
$tfields['tf-ctime'] = array(utf8_encode(date('Y/m/d H:i:s', $stat['ctime'])));
$tfields['tf-mtime'] = array(utf8_encode(date('Y/m/d H:i:s', $stat['mtime'])));
$tfields['tf-atime'] = array(utf8_encode(date('Y/m/d H:i:s', $stat['atime'])));
}
if (isset($propfile['appletLastModified']))
{
$x = ($propfile['appletLastModified']); // milisecondes since epoch (64 bits)
$x = substr($x, 0, strlen($x) - 3); // division / 1000
$tfields['tf-mtime'] = array(utf8_encode(date('Y/m/d H:i:s', $x)));
}
$tfields['tf-archivedate'] = array(utf8_encode(date('Y/m/d H:i:s', time())));
$tfields['tf-editdate'] = array(utf8_encode(date('Y/m/d H:i:s', time())));
$tfields['tf-chgdocdate'] = array(utf8_encode(date('Y/m/d H:i:s', time())));
// $tfields['tf-chgcoldate'] = array(date('Y/m/d H:i:s', time()));
// $tfields['tf-chgstatdate'] = array(date('Y/m/d H:i:s', time()));
$errcode = 0;
$errmsg = '';
// tous les champs de la structure
if (isset($baseprefs->description[0]))
{
foreach ($baseprefs->description->children() as $fname => $fpref)
{
// $src = (string)$fpref['src']; // l'attribut 'src' du champ
$src = mb_strtolower((string) $fpref['src']); // l'attribut 'src' du champ
$typ = mb_strtolower((string) $fpref['type']); // l'attribut 'type' du champ
$distinct = mb_strtolower((string) $fpref['distinct']); // l'attribut 'distinct' du champ
$multi = (int) ((string) $fpref['multi']); // l'attribut 'multi' du champ
if ($src != '' && isset($tfields[$src]))
{
// un champ iptc peut etre multi-value, on recoit donc toujours un tableau comme valeur
$tmpval = array();
foreach ($tfields[$src] as $val)
{
// on remplace les caracteres de controle (tous < 32 sauf 9,10,13)
$val = kill_ctrlchars($val);
if ($typ == 'date')
{
$val = str_replace(array('-', ':', '/', '.'), array(' ', ' ', ' ', ' '), $val);
$ip_date_yyyy = 0;
$ip_date_mm = 0;
$ip_date_dd = 0;
$ip_date_hh = 0;
$ip_date_nn = 0;
$ip_date_ss = 0;
switch (sscanf($val, '%d %d %d %d %d %d', $ip_date_yyyy, $ip_date_mm, $ip_date_dd, $ip_date_hh, $ip_date_nn, $ip_date_ss))
{
case 1:
$val = sprintf('%04d/00/00 00:00:00', $ip_date_yyyy);
break;
case 2:
$val = sprintf('%04d/%02d/00 00:00:00', $ip_date_yyyy, $ip_date_mm);
break;
case 3:
$val = sprintf('%04d/%02d/%02d 00:00:00', $ip_date_yyyy, $ip_date_mm, $ip_date_dd);
break;
case 4:
$val = sprintf('%04d/%02d/%02d %02d:00:00', $ip_date_yyyy, $ip_date_mm, $ip_date_dd, $ip_date_hh);
break;
case 5:
$val = sprintf('%04d/%02d/%02d %02d:%02d:00', $ip_date_yyyy, $ip_date_mm, $ip_date_dd, $ip_date_hh, $ip_date_nn);
break;
case 6:
$val = sprintf('%04d/%02d/%02d %02d:%02d:%02d', $ip_date_yyyy, $ip_date_mm, $ip_date_dd, $ip_date_hh, $ip_date_nn, $ip_date_ss);
break;
default:
$val = '0000/00/00 00:00:00';
}
}
if (!in_array($val, $tmpval))
$tmpval[] = $val;
}
foreach ($tmpval as $val)
{
$domfld = $domdesc->appendChild($domxml->createElement($fname));
$domfld->appendChild($domxml->createTextNode($val));
}
}
}
}
$element = $domxml->createElement('doc');
$domdoc = $domrec->appendChild($element);
$docProps = array('size', 'originalname', 'channels', 'bits', 'mime', 'width', 'height', 'frameRate', 'duration', 'audiocodec', 'videocodec', 'pixelformat', 'bitrate', 'videobitrate', 'audiobitrate', 'audiosamplerate', 'video_aspect');
foreach ($docProps as $k)
{
if (isset($propfile[$k]))
{
$domdoc->setAttribute($k, $propfile[$k]);
}
}
// ici on a un record/description DOM provenant du DOCUMENT principal (ex:iptc)
// on va eventuellement merger avec un fichier xml de description externe
// printf("------ DOMDOC : --------\n%s\n----------------\n", $domxml->saveXML());
$statBit = null;
$sxcaption = null;
if (isset($propfile['hotfoldercaptionfile']) && $propfile['hotfoldercaptionfile'])
{
// on a une description xml en plus a lire dans un fichier externe
if ($domcaption = @DOMDocument::load($propfile['hotfoldercaptionfile']))
{
if ($domcaption->documentElement->tagName == 'description') // il manque 'record' (<28>a commence par 'description') : on repare
{
$newdomcaption = new DOMDocument('1.0', 'UTF-8');
$newdomcaption->standalone = true;
$newdomrec = $newdomcaption->appendChild($newdomcaption->createElement('record'));
$newdomrec->appendChild($newdomcaption->importNode($domcaption->documentElement, true));
$sxcaption = simplexml_load_string($newdomcaption->saveXML());
}
else
{
$sxcaption = simplexml_load_file($propfile['hotfoldercaptionfile']);
}
if ($inStatus = $sxcaption->status)
{
if ($inStatus && $inStatus != '')
{
$statBit = $inStatus;
}
}
}
if ($sxcaption)
{
// printf("------NEED MERGE - sxcaption : --------\n%s\n----------------\n", $sxcaption->asXML() );
// on merge avec le xml en provenance du fichier principal
xml_merge($baseprefs, $domdesc, $sxcaption);
}
}
keepdistinct($baseprefs, $domxml);
if ($debug)
echo "\nOn a trouve un status bit dans le xml : " . $statBit . " de longueur " . strlen($statBit) . " caracteres\n";
return(array('xml' => $domxml, 'status' => $statBit, 'exif' => NULL));
}
function read_meta(&$baseprefs, &$propfile, $domxml)
{
global $msg;
$xp = new DOMXPath($domxml);
$debug = false;
$tfields = array();
$cwd = getcwd();
$propfile['doctype'] = giveMeDocType($propfile['mime']);
switch ($propfile['doctype'])
{
case 'image' :
get_fields_from_jpg($baseprefs, $propfile, $tfields);
break;
case 'document';
get_fields_from_jpg($baseprefs, $propfile, $tfields);
get_fields_from_pdf($baseprefs, $propfile, $tfields);
break;
case 'video':
get_fields_from_jpg($baseprefs, $propfile, $tfields);
break;
case 'audio':
get_fields_from_jpg($baseprefs, $propfile, $tfields);
break;
default:
get_fields_from_unknown($baseprefs, $propfile, $tfields);
break;
}
chdir($cwd);
$tfields['tf-mimetype'] = array(utf8_encode($propfile['mime']));
$tfields['tf-size'] = array(utf8_encode($propfile['size']));
$tfields['tf-extension'] = isset($propfile['extension']) ? array(utf8_encode($propfile['extension'])) : array();
$tfields['tf-width'] = isset($propfile['width']) ? array(utf8_encode($propfile['width'])) : array();
$tfields['tf-height'] = isset($propfile['height']) ? array(utf8_encode($propfile['height'])) : array();
$tfields['tf-bits'] = isset($propfile['bits']) ? array(utf8_encode($propfile['bits'])) : array();
$tfields['tf-channels'] = isset($propfile['channels']) ? array(utf8_encode($propfile['channels'])) : array();
//printf("tfields : %s\n", var_export($tfields, true));
// printf("%s (%d):\n%s\n", __FILE__, __LINE__, var_export($tfields, true));
$desc = $xp->query('/record/description');
if ($desc->length == 1)
$domdesc = $desc->item(0);
$errcode = 0;
$errmsg = '';
// tous les champs de la structure
if (isset($baseprefs->description[0]))
{
foreach ($baseprefs->description->children() as $fname => $fpref)
{
// $src = (string)$fpref['src']; // l'attribut 'src' du champ
$src = mb_strtolower((string) $fpref['src']); // l'attribut 'src' du champ
$typ = mb_strtolower((string) $fpref['type']); // l'attribut 'type' du champ
$distinct = mb_strtolower((string) $fpref['distinct']); // l'attribut 'distinct' du champ
$multi = (int) ((string) $fpref['multi']); // l'attribut 'multi' du champ
if ($src != '' && isset($tfields[$src]))
{
// delete old value(s)
//printf("deleting nodes '%s'\n", $fname);
$old = $xp->query($fname, $domdesc);
foreach ($old as $f)
$domdesc->removeChild($f);
//printf("apr<70>s delete : %s\n", $domxml->saveXML());
// un champ iptc peut etre multi-value, on re<72>oit donc toujours un tableau comme valeur
// delete duplicates values from multi-values
$tmpval = array();
foreach ($tfields[$src] as $val)
{
// on remplace les caracteres de controle (tous < 32 sauf 9,10,13)
$val = trim(kill_ctrlchars($val));
if ($typ == 'date')
{
$val = str_replace(array('-', ':', '/', '.'), array(' ', ' ', ' ', ' '), $val);
$ip_date_yyyy = 0;
$ip_date_mm = 0;
$ip_date_dd = 0;
$ip_date_hh = 0;
$ip_date_nn = 0;
$ip_date_ss = 0;
switch (sscanf($val, '%d %d %d %d %d %d', $ip_date_yyyy, $ip_date_mm, $ip_date_dd, $ip_date_hh, $ip_date_nn, $ip_date_ss))
{
case 1:
$val = sprintf('%04d/00/00 00:00:00', $ip_date_yyyy);
break;
case 2:
$val = sprintf('%04d/%02d/00 00:00:00', $ip_date_yyyy, $ip_date_mm);
break;
case 3:
$val = sprintf('%04d/%02d/%02d 00:00:00', $ip_date_yyyy, $ip_date_mm, $ip_date_dd);
break;
case 4:
$val = sprintf('%04d/%02d/%02d %02d:00:00', $ip_date_yyyy, $ip_date_mm, $ip_date_dd, $ip_date_hh);
break;
case 5:
$val = sprintf('%04d/%02d/%02d %02d:%02d:00', $ip_date_yyyy, $ip_date_mm, $ip_date_dd, $ip_date_hh, $ip_date_nn);
break;
case 6:
$val = sprintf('%04d/%02d/%02d %02d:%02d:%02d', $ip_date_yyyy, $ip_date_mm, $ip_date_dd, $ip_date_hh, $ip_date_nn, $ip_date_ss);
break;
default:
$val = '0000/00/00 00:00:00';
}
}
if (!in_array($val, $tmpval))
$tmpval[] = $val;
}
foreach ($tmpval as $val)
{
$domfld = $domdesc->appendChild($domxml->createElement($fname));
$domfld->appendChild($domxml->createTextNode($val));
}
//printf("apr<70>s insert : %s\n", $domxml->saveXML());
}
}
}
// printf("%s (%d):\n%s\n", __FILE__, __LINE__, var_export($domxml->saveXML(), true));
keepdistinct($baseprefs, $domxml);
// printf("%s (%d):\n%s\n", __FILE__, __LINE__, var_export($domxml->saveXML(), true));
$doc = $xp->query('/record/doc');
if ($doc->length == 1)
$domdoc = $doc->item(0);
$docProps = array('size', 'originalname', 'channels', 'bits', 'mime', 'width', 'height', 'frameRate', 'duration', 'audiocodec', 'videocodec', 'pixelformat', 'bitrate', 'videobitrate', 'audiobitrate', 'audiosamplerate', 'video_aspect');
foreach ($docProps as $k)
{
if (isset($propfile[$k]))
{
$domdoc->setAttribute($k, $propfile[$k]);
}
}
$lexml = $domxml->saveXML();
unset($domxml);
return(array('xml' => $lexml, 'exif' => NULL, 'errcode' => $errcode, 'errmsg' => $errmsg));
}
// jy 20060802 : supprime les doublons des champs multivalues marques 'distinct'
function keepdistinct(&$sxstruct, &$domdesc)
{
$debug = false;
if ($debug)
printf("before keepdistinct(...) : \n%s\n", $domdesc->saveXML());
$domdesc->normalize();
$nodestodelete = array();
foreach ($sxstruct->description->children() as $fname => $fpref)
{
if ($fpref['multi'])
{
$nodes2add = array();
$separator = mb_strtolower((string) $fpref['separator']); // l'attribut 'separator' du champ
if (strpos($separator, ';') === false) // le ';' est le separator par defaut, et un separator obligatoire
$separator .= ';';
if (strlen($separator) > 1)
{
// s'il y'a plusieurs delimiters, on transforme en regexp pour utiliser split
$separator = preg_split('//', $separator, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
$separator = '/\\' . implode('|\\', $separator) . '/';
}
if ($debug)
{
printf("separator : '$separator'\n");
printf("<b>%s</b> : %s \n", __LINE__, htmlentities($domdesc->saveXML()));
}
$flds = $domdesc->getElementsByTagName($fname);
for ($i = 0; $i < $flds->length; $i++)
{
$val = trim($flds->item($i)->nodeValue);
if (strlen($separator) == 1)
$tval = explode($separator, $val);
else
$tval = preg_split($separator, $val);
foreach ($tval as $val)
{
if (($val = trim($val)) != '')
$nodes2add[] = array('v' => $val, 'ref' => $flds->item($i));
}
$flds->item($i)->setAttribute('todelete', '1');
}
if ($debug)
{
printf("<b>%s</b> : %s \n", __LINE__, var_export($nodes2add, true));
}
foreach ($nodes2add as $node)
{
$nn = $domdesc->createElement($fname);
$nn->appendChild($domdesc->createTextNode($node['v']));
$node['ref']->parentNode->insertBefore($nn, $node['ref']);
}
}
if ($fpref['distinct'] == '1')
{
$flds = $domdesc->getElementsByTagName($fname);
for ($i = 0; $i < $flds->length; $i++)
{
for ($j = $i + 1; $j < $flds->length; $j++)
{
if (trim($flds->item($j)->nodeValue) == trim($flds->item($i)->nodeValue))
$flds->item($j)->setAttribute('todelete', '1');
}
}
}
// !!! ne pas supprimer directement a partir de la nodelist (pb iterator)
$flds = $domdesc->getElementsByTagName($fname);
for ($i = 0; $i < $flds->length; $i++)
{
if ($flds->item($i)->getAttribute('todelete') == '1')
{
$nodestodelete[] = $flds->item($i);
if ($flds->item($i)->previousSibling->nodeValue == "\x0a\t\t")
$nodestodelete[] = $flds->item($i)->previousSibling;
}
}
}
foreach ($nodestodelete as $f)
$f->parentNode->removeChild($f);
if ($debug)
printf("after keepdistinct(...) : \n%s\n", $domdesc->saveXML());
}
function xml_merge(&$baseprefs, &$domdesc, &$sxcaption)
{
$domdoc = $domdesc->ownerDocument;
foreach ($sxcaption->description->children() as $fn => $fld)
{
$fv = trim((string) $fld);
if (isset($baseprefs->description->$fn))
{
// le champ de la fiche xml existe bien dans la structure
// printf("ext caption %s(%s) : %s\n", (string)$fn, $baseprefs->description->$fn, $fv);
// est-ce qu'il existe dans la description actuelle
$dnl = $domdesc->getElementsByTagName($fn);
$multi = ( $baseprefs->description->{$fn}['multi'] == '1' );
// jy 20060802 : les dates dans un fichier xml doivent <20>tre iso, ou le format precise DANS LE CHAMP DE LA FICHE
// (et non plus dans la structure)
if ($baseprefs->description->{$fn}['type'] == 'date')
{
if ($fld['format'])
{
$fv = p4date::dateToIsodate($fv, $fld['format']);
}
}
// $fv = str_replace(array("&", "<", ">"), array("&amp;", "&lt;", "&gt;"), $fv);
// AS : ajout de multi le 20050125
if (!$multi && $dnl->length > 0)
{
// oui : on l'ecrase ou on le complete ?
$xmloverdoc = true; // !!! a placer dans les prefs !!!
if ($xmloverdoc)
{
$domfld = $domdoc->createElement($fn);
$domfld->appendChild($domdoc->createTextNode($fv));
$domdesc->replaceChild($domfld, $dnl->item(0));
}
else
{
// on le complete
$domfld = $dnl->item(0)->appendChild($domdoc->createTextNode($fv));
}
}
else
{
// non : ajoute le champ
// printf("fv:$fv\n");
$domfld = $domdesc->appendChild($domdoc->createElement($fn));
$domfld->appendChild($domdoc->createTextNode($fv));
}
}
}
}
function get_fields_from_pdf(&$baseprefs, &$propfile, &$tfields)
{
$PDF_TEXT_REF = 'pdf-text';
$system = p4utils::getSystem();
if (!(isset($propfile['hotfoldercaptionfile'])))
{
$cmd = '';
$tmpfile = GV_RootPath . 'tmp/pdf-extract' . time() . mt_rand(00000, 99999);
if ($system == 'DARWIN' || $system == 'LINUX')
{
$cmd = GV_pdftotext . ' -f 1 -l ' . GV_pdfmaxpages . ' -raw -enc UTF-8 -eol unix -q ' . str_replace(' ', '\ ', addslashes($propfile['hotfolderfile'])) . ' ' . $tmpfile;
}
else // WINDOWS
{
$cmd = GV_pdftotext . ' -f 1 -l ' . GV_pdfmaxpages . ' -raw -enc UTF-8 -eol unix -q ' . str_replace(' ', '\ ', addslashes($propfile['hotfolderfile'])) . ' ' . $tmpfile;
}
if ($cmd)
{
$s = shell_exec($cmd);
if (file_exists($tmpfile))
{
$tfields['pdf-text'] = array(file_get_contents($tmpfile));
unlink($tmpfile);
}
}
}
}
function get_fields_from_unknown(&$baseprefs, &$propfile, &$tfields)
{
return;
}
function get_fields_from_jpg(&$baseprefs, &$propfile, &$tfields)
{
// (8x except 85, 8C) + (9x except 9C) + (BC, BD, BE)
static $macchars = "\x81\x82\x83\x84\x86\x87\x88\x89\x8A\x8B\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9D\x9E\x9F\xBC\xBD\xBE";
if ($size = getimagesize($propfile['hotfolderfile'], $info))
{
$propfile['width'] = $size[0];
$propfile['height'] = $size[1];
if (array_key_exists('bits', $size))
$propfile['bits'] = $size['bits'];
if (array_key_exists('channels', $size))
$propfile['channels'] = $size['channels'];
}
$cmd = NULL;
$system = p4utils::getSystem();
if ($system == 'DARWIN')
{
$cmd = GV_exiftool . ' -X -n -fast ' . escapeshellarg($propfile['hotfolderfile']) . '';
}
else if ($system == 'LINUX')
{
$cmd = GV_exiftool . ' -X -n -fast ' . escapeshellarg($propfile['hotfolderfile']) . '';
}
else // WINDOWS
{
if (chdir(GV_RootPath . 'tmp/'))
{
$cmd = 'start /B /LOW ' . GV_exiftool . ' -X -n -fast ' . escapeshellarg($propfile['hotfolderfile']) . '';
}
}
if ($cmd)
{
$s = @shell_exec($cmd);
if ($s != '')
{
$domrdf = new DOMDocument();
$domrdf->recover = true;
$domrdf->preserveWhiteSpace = false;
if ($domrdf->loadXML($s))
{
$xptrdf = new DOMXPath($domrdf);
$xptrdf->registerNamespace('rdf', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#');
$pattern = "(xmlns:([a-zA-Z-_0-9]+)=[']{1}(https?:[/{2,4}|\\{2,4}][\w:#%/;$()~_?/\-=\\\.&]*)[']{1})";
preg_match_all($pattern, $s, $matches, PREG_PATTERN_ORDER, 0);
foreach ($matches[2] as $key => $value)
$xptrdf->registerNamespace($matches[1][$key], $value);
$descriptionNode = @$xptrdf->query('/rdf:RDF/rdf:Description')->item(0);
if ($descriptionNode)
{
for ($x = $descriptionNode->firstChild; $x; $x = $x->nextSibling)
{
if ($x->nodeType == XML_ELEMENT_NODE)
{
switch ($x->nodeName)
{
case 'Composite:ImageSize':
if ((count($_t = explode('x', $x->textContent))) == 2)
{
$propfile['width'] = 0 + $_t[0];
$propfile['height'] = 0 + $_t[1];
}
break;
case 'ExifIFD:ExifImageWidth':
if (!array_key_exists('width', $propfile))
$propfile['width'] = 0 + $x->textContent;
break;
case 'ExifIFD:ExifImageHeight':
if (!array_key_exists('height', $propfile))
$propfile['height'] = 0 + $x->textContent;
break;
case 'File:ColorComponents':
case 'IFD0:SamplesPerPixel':
if (!array_key_exists('channels', $propfile))
$propfile['channels'] = 0 + $x->textContent;
break;
case 'File:BitsPerSample':
case 'IFD0:BitsPerSample':
if (!array_key_exists('bits', $propfile))
$propfile['bits'] = 0 + $x->textContent;
break;
}
if (count($_t = explode(':', $x->nodeName)) == 2)
{
switch ($_t[1])
{
case 'ImageWidth':
if (!array_key_exists('width', $propfile))
$propfile['width'] = 0 + $x->textContent;
break;
case 'ImageHeight':
if (!array_key_exists('height', $propfile))
$propfile['height'] = 0 + $x->textContent;
break;
}
}
}
}
}
$x = @$xptrdf->query('/rdf:RDF/rdf:Description/XMP-exif:ImageUniqueID');
if ($x && $x->length > 0)
{
$x = $x->item(0);
$encoding = strtolower($x->getAttribute('rdf:datatype') . $x->getAttribute('et:encoding'));
$base64_encoded = (strpos($encoding, 'base64') !== false);
if (($v = $x->firstChild) && $v->nodeType == XML_TEXT_NODE)
{
$value = $base64_encoded ? base64_decode($v->nodeValue) : $v->nodeValue;
$utf8value = guessCharset($value, $macchars);
$propfile['UniqueID'] = $utf8value;
}
}
foreach ($baseprefs->description->children() as $fname => $fpref)
{
$src = (string) $fpref['src']; // l'attribut 'src' du champ
$srclow = mb_strtolower($src);
if (!$src)
continue;
$x = @$xptrdf->query($src);
if (!$x || $x->length != 1)
{
continue;
}
$tfields[$fname] = array();
$x = $x->item(0);
//double check -- exiftool uses et:encoding in version prior 7.71
$encoding = strtolower($x->getAttribute('rdf:datatype') . $x->getAttribute('et:encoding'));
$base64_encoded = (strpos($encoding, 'base64') !== false);
$bag = $xptrdf->query('rdf:Bag', $x);
if ($bag && $bag->length == 1)
{
$li = $xptrdf->query('rdf:li', $bag->item(0));
if ($li->length > 0)
{
$tfields[$fname] = array();
for ($ili = 0; $ili < $li->length; $ili++)
{
$value = $base64_encoded ? base64_decode($li->item($ili)->nodeValue) : $li->item($ili)->nodeValue;
$utf8value = trim(guessCharset($value, $macchars));
$tfields[$srclow][] = $utf8value;
}
}
}
else
{
if (($v = $x->firstChild) && $v->nodeType == XML_TEXT_NODE)
{
$value = $base64_encoded ? base64_decode($v->nodeValue) : $v->nodeValue;
$utf8value = guessCharset($value, $macchars);
$tfields[$srclow] = array($utf8value);
}
}
}
}
}
}
if (isset($propfile['doctype']) && in_array($propfile['doctype'], array('audio', 'video')))
{
$extended_props = getVideoInfos($propfile['hotfolderfile']);
$propfile = array_merge($propfile, $extended_props);
}
return;
}
function guessCharset($s, &$macchars)
{
if (mb_convert_encoding(mb_convert_encoding($s, 'UTF-32', 'UTF-8'), 'UTF-8', 'UTF-32') == $s)
{
$mac = mb_convert_encoding($s, 'windows-1252', 'UTF-8');
for ($i = strlen($mac); $i;)
{
if (strpos($macchars, $mac[--$i]) !== false)
return(iconv('MACINTOSH', 'UTF-8', $mac));
}
return($s);
}
else
{
for ($i = strlen($s); $i;)
{
if (strpos($macchars, $s[--$i]) !== false)
return(iconv('MACINTOSH', 'UTF-8', $s));
}
return(iconv('windows-1252', 'UTF-8', $s));
}
}
function microtime_float()
{
list($usec, $sec) = explode(' ', microtime());
return ((float) $usec + (float) $sec);
}
function kill_ctrlchars($s) // ok en utf8 !
{
static $a_in = null;
static $a_out = null;
if ($a_in === null)
{
$a_in = array();
$a_out = array();
for ($cc = 0; $cc < 32; $cc++)
{
if ($cc != 10 && $cc != 13 && $cc != 9)
{
$a_in[] = chr($cc);
$a_out[] = '_';
}
}
}
return(str_replace($a_in, $a_out, $s));
}
/**
* remplace les {{Y}}, {{m}}, {{d}}... dans un path (pour ventiler dans le repositories)
* @param string $path le path a corriger
* @param int $date la date en unixtimestamp
* @return string le path corrige
*/
function makeSubdefs($sbas_id, $hdDoc)
{
$zdate = time();
$debug = false;
$ret = array('subdefs' => array());
//avalaible subdefs
$AvSubdefs = databox::get_subdefs($sbas_id);
if ($debug)
{
echo "Subdefs disponibles : \n";
var_dump($AvSubdefs);
}
$ret = array();
$ret['subdefs'] = array();
$what = isset($AvSubdefs[$hdDoc['type']]) ? $hdDoc['type'] : ( isset($AvSubdefs['image']) ? 'image' : false);
if ($debug)
echo "\nJe deduis le type de document : $what d'apres " . $hdDoc['type'] . "\n\n";
if ($what !== false)
{
$subdefs = $AvSubdefs[$what];
if ($debug)
echo "\nJe deduis le groupe de subdefs : \n" . var_export($subdefs, true) . "\n";
$HDFile = p4string::addEndSlash($hdDoc['path']) . $hdDoc['file'];
$HDprops = getHDprops($HDFile, $what);
$ret['document'] = $HDprops;
$HDprops['recordid'] = $hdDoc['record_id'];
$HDprops['mime'] = $hdDoc['mime'];
// $HDprops['Orientation'] = '?';
if ($debug)
echo "\nHDprops : \n" . var_export($HDprops, true) . "\n";
$tryMakeSubdef = false;
if ($debug)
{
echo "\nOn genere les subdefs... pour '$what'\n";
}
$i = 1;
foreach ($subdefs as $subdef)
{
$physdpath = (string) ($subdef->path);
$physdpath = p4string::addEndSlash(p4::dispatch($physdpath));
if (!is_dir($physdpath))
p4::fullmkdir($physdpath);
$ret['subdefs'][$i] = subdefDispatcher($what // 'image', 'video' or 'audio'
, $HDFile // path to document
, $subdef // subdef settings from struct (simplexml)
, $physdpath // where to create the subdef
, $HDprops // recordid, width, height, mime, CMYK etc...
);
// complete le resultat
if ($ret['subdefs'][$i] !== false)
{
$ret['subdefs'][$i]['record_id'] = $hdDoc['record_id'];
$ret['subdefs'][$i]['name'] = (string) ($subdef->attributes()->name);
$ret['subdefs'][$i]['path'] = $physdpath;
$ret['subdefs'][$i]['inbase'] = 1;
$baseurl = '';
if (($baseurl = trim((string) ($subdef->baseurl))))
$baseurl = p4string::addEndSlash($baseurl) . substr($physdpath, strlen(p4string::addEndSlash((string) ($subdef->path))));
$ret['subdefs'][$i]['baseurl'] = $baseurl;
$ret['subdefs'][$i]['size'] = @filesize(p4string::addEndSlash($physdpath) . $ret['subdefs'][$i]['file']);
}
$i++;
}
/*
*/
unset($HDprops);
unset($subdefs);
}
if ($debug)
print("\nfin de make_subdef(...)\n");
if ($debug)
{
echo "\nOn a comme retour \n";
var_dump($ret);
}
unset($what);
unset($AvSubdefs);
return($ret);
}
function subdefDispatcher($what, $originalDoc, $sd, $physdpath, $prop)
{
$makeSubdef = false;
switch ($what)
{
case 'video':
$makeSubdef = make1VideoSubdef($originalDoc, $sd, $physdpath, $prop);
break;
case 'audio':
$makeSubdef = make1AudioSubdef($originalDoc, $sd, $physdpath, $prop);
break;
case 'document':
$makeSubdef = make1DocumentSubdef($originalDoc, $sd, $physdpath, $prop);
break;
case 'image':
default:
$makeSubdef = make1subdef($originalDoc, $sd, $physdpath, $prop);
break;
case 'flash':
$makeSubdef = make1flashsubdef($originalDoc, $sd, $physdpath, $prop);
break;
}
return $makeSubdef;
}
function getHDprops($hdPath, $type)
{
switch ($type)
{
case 'video':
case 'audio':
$return = getVideoInfos($hdPath);
break;
case 'image':
default:
$return = getImageInfos($hdPath);
break;
}
return $return;
}
function getVideoInfos($hdPath)
{
$retour = array('width' => 0, 'height' => 0, 'CMYK' => false);
$datas = exiftool::get_fields($hdPath, array('Duration', 'Image Width', 'Image Height'));
$duration = 0;
if ($datas['Duration'])
{
$data = explode('_', trim($datas['Duration']));
$data = explode(':', $data[0]);
$factor = 1;
while ($segment = array_pop($data))
{
$duration += $segment * $factor;
$factor *=60;
}
}
$width = $height = false;
if ($datas['Image Width'])
{
if ((int) $datas['Image Width'] > 0)
$width = $datas['Image Width'];
}
if ($datas['Image Height'])
{
if ((int) $datas['Image Height'] > 0)
$height = $datas['Image Height'];
}
$cmd = GV_mplayer . ' -identify ' . escapeshellarg($hdPath) . ' -ao null -vo null -frames 0 | grep ^ID_';
$docProps = array(
'ID_VIDEO_WIDTH' => 'width',
'ID_VIDEO_HEIGHT' => 'height',
'ID_VIDEO_FPS' => 'frameRate',
// 'ID_LENGTH' => 'duration',
'ID_AUDIO_CODEC' => 'audiocodec',
'ID_VIDEO_CODEC' => 'videocodec',
'ID_VIDEO_BITRATE' => 'videobitrate',
'ID_AUDIO_BITRATE' => 'audiobitrate',
'ID_AUDIO_RATE' => 'audiosamplerate',
'ID_VIDEO_ASPECT' => 'video_aspect'
);
$stdout = shell_exec($cmd);
$propfile = array();
$stdout = explode("\n", $stdout);
foreach ($stdout as $property)
{
$props = explode('=', $property);
if (array_key_exists($props[0], $docProps))
$propfile[$docProps[$props[0]]] = $props[1];
}
$propfile['duration'] = $duration;
if ($width)
$propfile['width'] = $width;
if ($height)
$propfile['height'] = $height;
$retour = array_merge($retour, $propfile);
return $retour;
}
/*
function getImageInfos($hdPath)
{
$retour = array('width'=>0, 'height'=>0, 'CMYK'=>false);
if( ($tempHD = getimagesize($hdPath)) )
{
if(isset($tempHD['channels']) && $tempHD['channels']==4)
$retour['CMYK'] = true;
$retour['width'] = $tempHD[0];
$retour['height'] = $tempHD[1];
}
if($ex = @exif_read_data($hdPath, 'FILE') )
{
if(array_key_exists('Orientation', $ex))
$retour['Orientation'] = $ex['Orientation'];
}
var_dump($retour);
return $retour;
}
*/
/*
* return width, height, Orientation, CMYK for a (image) file, using exiftool
*/
function getImageInfos($hdPath)
{
$ret = array();
$cmd = NULL;
$system = p4utils::getSystem();
if ($system == 'DARWIN' || $system == 'LINUX')
$cmd = GV_exiftool . ' -X -n -fast ' . escapeshellarg($hdPath) . '';
elseif (chdir(GV_RootPath . 'tmp/')) // WINDOWS
$cmd = 'start /B /LOW ' . GV_exiftool . ' -X -n -fast ' . escapeshellarg($hdPath) . '';
if ($cmd && ($s = @shell_exec($cmd)) != '')
{
$domrdf = new DOMDocument();
$domrdf->recover = true;
$domrdf->preserveWhiteSpace = false;
if ($domrdf->loadXML($s))
{
$xptrdf = new DOMXPath($domrdf);
$xptrdf->registerNamespace('rdf', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#');
$pattern = "(xmlns:([a-zA-Z-_0-9]+)=[']{1}(https?:[/{2,4}|\\{2,4}][\w:#%/;$()~_?/\-=\\\.&]*)[']{1})";
preg_match_all($pattern, $s, $matches, PREG_PATTERN_ORDER, 0);
foreach ($matches[2] as $key => $value)
$xptrdf->registerNamespace($matches[1][$key], $value);
$descriptionNode = @$xptrdf->query('/rdf:RDF/rdf:Description')->item(0);
if ($descriptionNode)
{
// exiftool fields giving tech infos, in order of 'reliability'
$fpri = array(
'File:ColorComponents' => array('f' => 'channels', 'v' => NULL)
, 'Composite:ImageWidth' => array('f' => 'width', 'v' => NULL)
, 'Composite:ImageHeight' => array('f' => 'height', 'v' => NULL)
, 'Composite:ImageSize' => array('f' => 'imageSize', 'v' => NULL)
, 'ExifIFD:ExifImageWidth' => array('f' => 'width', 'v' => NULL)
, 'ExifIFD:ExifImageHeight' => array('f' => 'height', 'v' => NULL)
, 'XMP-exif:ExifImageWidth' => array('f' => 'width', 'v' => NULL)
, 'XMP-exif:ExifImageHeight' => array('f' => 'height', 'v' => NULL)
, 'XMP-tiff:Orientation' => array('f' => 'Orientation', 'v' => NULL)
, 'IFD0:ImageWidth' => array('f' => 'width', 'v' => NULL)
, 'IFD0:ImageHeight' => array('f' => 'height', 'v' => NULL)
, 'IFD0:Orientation' => array('f' => 'Orientation', 'v' => NULL)
, 'IFD0:SamplesPerPixel' => array('f' => 'channels', 'v' => NULL)
, 'IFD0:BitsPerSample' => array('f' => 'bits', 'v' => NULL)
// last chanche values
, '*:ImageWidth' => array('f' => 'width', 'v' => NULL)
, '*:ImageHeight' => array('f' => 'height', 'v' => NULL)
, '*:BitsPerSample' => array('f' => 'bits', 'v' => NULL)
, '*:Orientation' => array('f' => 'Orientation', 'v' => NULL)
);
for ($x = $descriptionNode->firstChild; $x; $x = $x->nextSibling)
{
if ($x->nodeType == XML_ELEMENT_NODE)
{
$nodeName = $x->nodeName;
if (!array_key_exists($nodeName, $fpri))
{
// if not a well known field, try (rename) it as a last chance one
if (count($tmp = explode(':', $nodeName)) == 2)
$nodeName = '*:' . $tmp[1];
}
if (array_key_exists($nodeName, $fpri) && $fpri[$nodeName]['v'] === NULL)
{
$fpri[$nodeName]['v'] = trim($x->textContent);
}
}
}
// fill result with the most reliable found values
foreach ($fpri as $f)
{
if ($f['v'] !== NULL && !array_key_exists($f['f'], $ret))
$ret[$f['f']] = $f['v'];
}
// patch some values
if (array_key_exists('channels', $ret))
$ret['CMYK'] = ((int) ($ret['channels']) == 4);
if ((!array_key_exists('width', $ret) || !array_key_exists('height', $ret)) && array_key_exists('imageSize', $ret))
{
if (count($tmp = explode('x', $ret['imageSize'])) == 2)
{
$ret['width'] = $tmp[0];
$ret['height'] = $tmp[1];
}
}
foreach (array('width', 'height', 'channels', 'bits', 'Orientation') as $f)
{
if (array_key_exists($f, $ret))
$ret[$f] = (int) ($ret[$f]);
}
}
}
}
// create some default values to unfound fields
$ret = array_merge(array('width' => 0, 'height' => 0, 'CMYK' => false), $ret);
return($ret);
}
function isRaw($mime)
{
$raws = array(
'3fr' => 'image/x-tika-hasselblad'
, 'arw' => 'image/x-tika-sony'
, 'bay' => 'image/x-tika-casio'
, 'cap' => 'image/x-tika-phaseone'
, 'cr2' => 'image/x-tika-canon'
, 'crw' => 'image/x-tika-canon'
, 'dcs' => 'image/x-tika-kodak'
, 'dcr' => 'image/x-tika-kodak'
, 'dng' => 'image/x-tika-dng'
, 'drf' => 'image/x-tika-kodak'
, 'erf' => 'image/x-tika-epson'
, 'fff' => 'image/x-tika-imacon'
, 'iiq' => 'image/x-tika-phaseone'
, 'kdc' => 'image/x-tika-kodak'
, 'k25' => 'image/x-tika-kodak'
, 'mef' => 'image/x-tika-mamiya'
, 'mos' => 'image/x-tika-leaf'
, 'mrw' => 'image/x-tika-minolta'
, 'nef' => 'image/x-tika-nikon'
, 'nrw' => 'image/x-tika-nikon'
, 'orf' => 'image/x-tika-olympus'
, 'pef' => 'image/x-tika-pentax'
, 'ppm' => 'image/x-portable-pixmap'
, 'ptx' => 'image/x-tika-pentax'
, 'pxn' => 'image/x-tika-logitech'
, 'raf' => 'image/x-tika-fuji'
, 'raw' => 'image/x-tika-panasonic'
, 'r3d' => 'image/x-tika-red'
, 'rw2' => 'image/x-tika-panasonic'
, 'rwz' => 'image/x-tika-rawzor'
, 'sr2' => 'image/x-tika-sony'
, 'srf' => 'image/x-tika-sony'
, 'x3f' => 'image/x-tika-sigma');
if (in_array($mime, $raws))
return true;
return false;
}
function giveMimeExt($doc, $OrDoc=null)
{
// printf("--------------\n %s \n--------------\n", $doc);
if ($OrDoc == null)
$OrDoc = $doc;
static $mimeTypes = array(
'ai' => 'application/postscript'
, '3gp' => 'video/3gpp'
, 'aif' => 'audio/aiff'
, 'aiff' => 'audio/aiff'
, 'asf' => 'video/x-ms-asf'
, 'asx' => 'video/x-ms-asf'
, 'avi' => 'video/avi'
, 'bmp' => 'image/bmp'
, 'bz2' => 'application/x-bzip'
, '3fr' => 'image/x-tika-hasselblad'
, 'arw' => 'image/x-tika-sony'
, 'bay' => 'image/x-tika-casio'
, 'cap' => 'image/x-tika-phaseone'
, 'cr2' => 'image/x-tika-canon'
, 'crw' => 'image/x-tika-canon'
, 'dcs' => 'image/x-tika-kodak'
, 'dcr' => 'image/x-tika-kodak'
, 'dng' => 'image/x-tika-dng'
, 'drf' => 'image/x-tika-kodak'
, 'erf' => 'image/x-tika-epson'
, 'fff' => 'image/x-tika-imacon'
, 'iiq' => 'image/x-tika-phaseone'
, 'kdc' => 'image/x-tika-kodak'
, 'k25' => 'image/x-tika-kodak'
, 'mef' => 'image/x-tika-mamiya'
, 'mos' => 'image/x-tika-leaf'
, 'mrw' => 'image/x-tika-minolta'
, 'nef' => 'image/x-tika-nikon'
, 'nrw' => 'image/x-tika-nikon'
, 'orf' => 'image/x-tika-olympus'
, 'pef' => 'image/x-tika-pentax'
, 'ppm' => 'image/x-portable-pixmap'
, 'ptx' => 'image/x-tika-pentax'
, 'pxn' => 'image/x-tika-logitech'
, 'raf' => 'image/x-tika-fuji'
, 'raw' => 'image/x-tika-panasonic'
, 'r3d' => 'image/x-tika-red'
, 'rw2' => 'image/x-tika-panasonic'
, 'rwz' => 'image/x-tika-rawzor'
, 'sr2' => 'image/x-tika-sony'
, 'srf' => 'image/x-tika-sony'
, 'x3f' => 'image/x-tika-sigma'
, 'css' => 'text/css'
, 'doc' => 'application/msword'
, 'docx' => 'application/msword'
, 'eps' => 'application/postscript'
, 'exe' => 'application/x-msdownload'
, 'flv' => 'video/x-flv'
, 'gif' => 'image/gif'
, 'gz' => 'application/x-gzip'
, 'htm' => 'text/html'
, 'html' => 'text/html'
, 'jpeg' => 'image/jpeg'
, 'jpg' => 'image/jpeg'
, 'm3u' => 'audio/x-mpegurl'
, 'mid' => 'audio/mid'
, 'midi' => 'audio/mid'
, 'mkv' => 'video/matroska'
, 'mp3' => 'audio/mpeg'
, 'mp4' => 'video/mp4'
, 'vob' => 'video/mpeg'
, 'mp2p' => 'video/mpeg'
, 'mpeg' => 'video/mpeg'
, 'mpg' => 'video/mpeg'
, 'ods' => 'application/vnd.oasis.opendocument.spreadsheet'
, 'odt' => 'application/vnd.oasis.opendocument.text'
, 'odp' => 'application/vnd.oasis.opendocument.presentation'
, 'ogg' => 'audio/ogg'
, 'pdf' => 'application/pdf'
, 'pls' => 'audio/scpls'
, 'png' => 'image/png'
, 'pps' => 'application/vnd.ms-powerpoint'
, 'ppt' => 'application/vnd.ms-powerpoint'
, 'pptx' => 'application/vnd.ms-powerpoint'
, 'psd' => 'image/psd'
, 'ra' => 'audio/x-pn-realaudio'
, 'ram' => 'audio/x-pn-realaudio'
, 'rm' => 'application/vnd.rn-realmedia'
, 'rtf' => 'application/msword'
, 'rv' => 'video/vnd.rn-realvideo'
, 'swf' => 'application/x-shockwave-flash'
, 'tar' => 'application/x-tar'
, 'tif' => 'image/tiff'
, 'txt' => 'text/plain'
, 'wav' => 'audio/wav'
, 'wma' => 'audio/x-ms-wma'
, 'wmv' => 'video/x-ms-wmv'
, 'wmx' => 'video/x-ms-wmx'
, 'xls' => 'application/excel'
, 'xlsx' => 'application/excel'
, 'xml' => 'text/xml'
, 'xsl' => 'text/xsl'
, 'zip' => 'application/zip'
);
$type_pj = '';
$debug = false;
if (function_exists('finfo_open'))
{
$magicfile = NULL;
if (is_file('/usr/share/misc/magic'))
{
$magicfile = '/usr/share/misc/magic';
}
elseif (is_file('/usr/share/misc/magic.mgc'))
{
$magicfile = '/usr/share/misc/magic.mgc';
}
elseif (is_file(GV_RootPath . 'www/include/magic'))
{
$magicfile = GV_RootPath . 'www/include/magic';
}
if (($finfo = @finfo_open(FILEINFO_MIME, $magicfile)) !== false)//, GV_RootPath.'include/magic'); // Retourne le type mime
{
$type_pj = finfo_file($finfo, $doc);
finfo_close($finfo);
}
elseif (($finfo = @finfo_open(FILEINFO_MIME, NULL)) !== false)
{
$type_pj = finfo_file($finfo, $doc);
finfo_close($finfo);
}
if ($debug)
echo "fileinfo OK et renvoie " . $type_pj . "\n";
}
$mime = '';
$pi = pathinfo($OrDoc);
if (!isset($pi['extension']))
$pi['extension'] = '';
$ext = mb_strtolower($pi['extension']);
$mime = $type_pj;
if (trim($type_pj) == '')
{
if ($ext != '' && isset($mimeTypes[$ext]))
{
$mime = $mimeTypes[$ext];
}
elseif ($ext == '')
{
$gis = getimagesize($doc);
if ($gis['mime'] != '')
$mime = $gis['mime'];
}
}
if ($debug)
echo "mime_content_type OK et renvoie " . mime_content_type($doc) . "\n";
if ($mime == '' || $mime == NULL)
$mime = mime_content_type($doc);
if (( $pos = strpos($mime, '; charset=')) !== false)
{
$mime = substr($mime, 0, $pos);
}
if ($mime == 'application/pdf' && $ext == 'ai')
$mime = 'image/vnd.adobe.illustrator';
elseif ($mime == 'text/plain' && $ext == 'mkv')
$mime = 'video/matroska';
elseif (in_array($mime, array('application/octet-stream', 'image/tiff', 'application/vnd.ms-office', 'application/zip')) && isset($mimeTypes[$ext]))
$mime = $mimeTypes[$ext];
elseif ($mime == '' && $ext == 'm4v')
$mime = 'video/x-m4v';
return array('mime' => $mime, 'ext' => $ext);
}
if (!function_exists('mime_content_type'))
{
function mime_content_type($f)
{
$ext2mime = array(
'dwg' => 'application/acad' // Fichiers AutoCAD
, 'ccad' => 'application/clariscad' // Fichiers ClarisCAD
, 'drw' => 'application/drafting' // Fichiers MATRA Prelude drafting
, 'dxf' => 'application/dxf' // Fichiers AutoCAD
, 'unv' => 'application/i-deas' // Fichiers SDRC I-deas
, 'igs' => 'application/iges' // Format d'echange CAO IGES
, 'iges' => 'application/iges' // Format d'echange CAO IGES
, 'bin' => 'application/octet-stream' // Fichiers binaires non interpretes
, 'oda' => 'application/oda' // Fichiers ODA
, 'pdf' => 'application/pdf' // Fichiers Adobe Acrobat
, 'ai' => 'application/postscript' // Fichiers PostScript
, 'eps' => 'application/postscript' // Fichiers PostScript
, 'ps' => 'application/postscript' // Fichiers PostScript
, 'prt' => 'application/pro_eng' // Fichiers ProEngineer
, 'rtf' => 'application/rtf' // Format de texte enrichi
, 'set' => 'application/set' // Fichiers CAO SET
, 'stl' => 'application/sla' // Fichiers stereolithographie
, 'dwg' => 'application/solids' // Fichiers MATRA Solids
, 'step' => 'application/step' // Fichiers de donnees STEP
, 'vda' => 'application/vda' // Fichiers de surface
, 'mif' => 'application/x-mif' // Fichiers Framemaker
, 'dwg' => 'application/x-csh' // Script C-Shell (UNIX)
, 'dvi' => 'application/x-dvi' // Fichiers texte dvi
, 'hdf' => 'application/hdf' // Fichiers de donnees
, 'latex' => 'application/x-latex' // Fichiers LaTEX
, 'nc' => 'application/x-netcdf' // Fichiers netCDF
, 'cdf' => 'application/x-netcdf' // Fichiers netCDF
, 'dwg' => 'application/x-sh' // Script Bourne Shell
, 'tcl' => 'application/x-tcl' // Script Tcl
, 'tex' => 'application/x-tex' // fichiers Tex
, 'texinfo' => 'application/x-texinfo' // Fichiers eMacs
, 'texi' => 'application/x-texinfo' // Fichiers eMacs
, 't' => 'application/x-troff' // Fichiers Troff
, 'tr' => 'application/x-troff' // Fichiers Troff
, 'troff' => 'application/x-troff' // Fichiers Troff
, 'man' => 'application/x-troff-man' // Fichiers Troff/macro man
, 'me' => 'application/x-troff-me' // Fichiers Troff/macro ME
, 'ms' => 'application/x-troff-ms' // Fichiers Troff/macro MS
, 'src' => 'application/x-wais-source' // Source Wais
, 'bcpio' => 'application/x-bcpio' // CPIO binaire
, 'cpio' => 'application/x-cpio' // CPIO Posix
, 'gtar' => 'application/x-gtar' // Tar GNU
, 'shar' => 'application/x-shar' // Archives Shell
, 'sv4cpio' => 'application/x-sv4cpio' // CPIO SVR4n
, 'sc4crc' => 'application/x-sv4crc' // CPIO SVR4 avec CRC
, 'tar' => 'application/x-tar' // Fichiers compresses tar
, 'man' => 'application/x-ustar' // Fichiers compresses tar Posix
, 'man' => 'application/zip' // Fichiers compresses ZIP
, 'au' => 'audio/basic' // Fichiers audio basiques
, 'snd' => 'audio/basic' // Fichiers audio basiques
, 'aif' => 'audio/x-aiff' // Fichiers audio AIFF
, 'aiff' => 'audio/x-aiff' // Fichiers audio AIFF
, 'aifc' => 'audio/x-aiff' // Fichiers audio AIFF
, 'wav' => 'audio/x-wav' // Fichiers audio Wave
, 'man' => 'image/gif' // Images gif
, 'ief' => 'image/ief' // Images exchange format
, 'jpg' => 'image/jpeg' // Images Jpeg
, 'jpeg' => 'image/jpeg' // Images Jpeg
, 'jpe' => 'image/jpeg' // Images Jpeg
, 'tiff' => 'image/tiff' // Images Tiff
, 'tif' => 'image/tiff' // Images Tiff
, 'cmu' => 'image/x-cmu-raster' // Raster cmu
, 'pnm' => 'image/x-portable-anymap' // Fichiers Anymap PBM
, 'pbm' => 'image/x-portable-bitmap' // Fichiers Bitmap PBM
, 'pgm' => 'image/x-portable-graymap' // Fichiers Graymap PBM
, 'ppm' => 'image/x-portable-pixmap' // Fichiers Pixmap PBM
, 'rgb' => 'image/x-rgb' // Image RGB
, 'xbm' => 'image/x-xbitmap' // Images Bitmap X
, 'xpm' => 'image/x-xpixmap' // Images Pixmap X
, 'man' => 'image/x-xwindowdump' // Images dump X Window
, 'zip' => 'multipart/x-zip' // Fichiers archive zip
, 'gz' => 'multipart/x-gzip' // Fichiers archive GNU zip
, 'gzip' => 'multipart/x-gzip' // Fichiers archive GNU zip
, 'htm' => 'text/html' // Fichiers HTML
, 'html' => 'text/html' // Fichiers HTML
, 'txt' => 'text/plain' // Fichiers texte sans mise en forme
, 'g' => 'text/plain' // Fichiers texte sans mise en forme
, 'h' => 'text/plain' // Fichiers texte sans mise en forme
, 'c' => 'text/plain' // Fichiers texte sans mise en forme
, 'cc' => 'text/plain' // Fichiers texte sans mise en forme
, 'hh' => 'text/plain' // Fichiers texte sans mise en forme
, 'm' => 'text/plain' // Fichiers texte sans mise en forme
, 'f90' => 'text/plain' // Fichiers texte sans mise en forme
, 'rtx' => 'text/richtext' // Fichiers texte enrichis
, 'tsv' => 'text/tab-separated-value' // Fichiers texte avec separation des valeurs
, 'etx' => 'text/x-setext' // Fichiers texte Struct
, 'mpeg' => 'video/mpeg' // Videos MPEG
, 'mpg' => 'video/mpeg' // Videos MPEG
, 'mpe' => 'video/mpeg' // Videos MPEG
, 'qt' => 'video/quicktime' // Videos QuickTime
, 'mov' => 'video/quicktime' // Videos QuickTime
, 'avi' => 'video/msvideo' // Videos Microsoft Windows
, 'movie' => 'video/x-sgi-movie' // Videos MoviePlayer
);
$ret = 'application/octet-stream';
$ext = mb_strtolower(substr($f, stripos($f, '.') + 1));
if (array_key_exists($ext, $ext2mime))
$ret = $ext2mime[$ext];
// printf("%s : %s : %s<br/>\n", $f, $ext, $ret);
return($ret);
}
}
function giveMeDocType($mime)
{
$return = false;
switch ($mime)
{
case 'image/png':
case 'image/gif':
case 'image/bmp':
case 'image/x-ms-bmp':
case 'image/jpeg':
case 'image/pjpeg':
case 'image/psd':
case 'image/photoshop':
case 'image/vnd.adobe.photoshop':
case 'image/ai':
case 'image/illustrator':
case 'image/vnd.adobe.illustrator':
case 'image/tiff':
case 'image/x-photoshop':
case 'application/postscript':
case 'image/x-tika-canon':
case 'image/x-tika-casio':
case 'image/x-tika-dng':
case 'image/x-tika-epson':
case 'image/x-tika-fuji':
case 'image/x-tika-hasselblad':
case 'image/x-tika-imacon':
case 'image/x-tika-kodak':
case 'image/x-tika-leaf':
case 'image/x-tika-logitech':
case 'image/x-tika-mamiya':
case 'image/x-tika-minolta':
case 'image/x-tika-nikon':
case 'image/x-tika-olympus':
case 'image/x-tika-panasonic':
case 'image/x-tika-pentax':
case 'image/x-tika-phaseone':
case 'image/x-tika-rawzor':
case 'image/x-tika-red':
case 'image/x-tika-sigma':
case 'image/x-tika-sony':
case 'image/x-portable-pixmap':
$return = 'image';
break;
case 'video/mpeg':
case 'video/mp4':
case 'video/x-ms-wmv':
case 'video/x-ms-wmx':
case 'video/avi':
case 'video/mp2p':
case 'video/mp4':
case 'video/x-ms-asf':
case 'video/quicktime':
case 'video/matroska':
case 'video/x-msvideo':
case 'video/x-ms-video':
case 'video/x-flv':
case 'video/avi':
case 'video/3gpp':
case 'video/x-m4v':
case 'application/vnd.rn-realmedia':
$return = 'video';
break;
case 'audio/aiff':
case 'audio/aiff':
case 'audio/x-mpegurl':
case 'audio/mid':
case 'audio/mid':
case 'audio/mpeg':
case 'audio/ogg':
case 'audio/mp4':
case 'audio/scpls':
case 'audio/vnd.rn-realaudio':
case 'audio/x-pn-realaudio':
case 'audio/wav':
case 'audio/x-wav':
case 'audio/x-ms-wma':
$return = 'audio';
break;
// default et aussi les fichiers ou on ne sais pas faire de thumbnail/preview
case 'text/plain':
case 'application/msword':
case 'application/access':
case 'application/pdf':
case 'application/excel':
case 'application/vnd.ms-powerpoint':
case 'application/vnd.oasis.opendocument.formula':
case 'application/vnd.oasis.opendocument.text-master':
case 'application/vnd.oasis.opendocument.database':
case 'application/vnd.oasis.opendocument.formula':
case 'application/vnd.oasis.opendocument.chart':
case 'application/vnd.oasis.opendocument.graphics':
case 'application/vnd.oasis.opendocument.presentation':
case 'application/vnd.oasis.opendocument.speadsheet':
case 'application/vnd.oasis.opendocument.text':
$return = 'document';
break;
case 'application/x-shockwave-flash':
$return = 'flash';
break;
default:
$return = 'unknown';
break;
}
if (GV_debug)
{
// echo "\n detection doctype : $return\n";
}
return $return;
}
function make1flashsubdef($infile, $sd, $physdpath, $infos)
{
$debug = false;
if ($debug)
{
echo "make 1 flash\n";
}
$return_value = false;
if (!GV_swf_extract && !GV_swf_render)
{
return false;
}
if ($debug)
{
echo " oui swf exctrat\n";
}
$file_extracted = false;
if (GV_swf_extract)
{
$cmd = GV_swf_extract . ' ' . escapeshellarg($infile);
$nullfile = '/dev/null';
$descriptors = array();
$descriptors[1] = array('pipe', 'w');
$descriptors[2] = array('pipe', 'w'); // stderr is a file to write to
$pipes = array();
$process = proc_open($cmd, $descriptors, $pipes);
$err = $stdout = '';
$id = false;
if (is_resource($process))
{
while (!feof($pipes[2]))
$err .= fgets($pipes[2], 1024);
fclose($pipes[2]);
while (!feof($pipes[1]))
$stdout .= fgets($pipes[1], 1024);
fclose($pipes[1]);
proc_close($process);
$lines = explode("\n", $stdout);
foreach ($lines as $l)
{
if (substr(trim($l), 0, 4) == '[-j]')
{
$id = ' -j ' . array_pop(explode('-', array_pop(explode(' ', trim($l)))));
$ext = '.jpg';
break;
}
if (substr(trim($l), 0, 4) == '[-p]')
{
$id = ' -p ' . array_pop(explode('-', array_pop(explode(' ', trim($l)))));
$ext = '.png';
break;
}
}
}
if ($id)
{
if ($debug)
{
echo "jai bien le type de fichier : $id\n";
}
$infile_tmp = GV_RootPath . 'tmp/temp_flash_' . time() . mt_rand(1000, 9999) . $ext;
exec(GV_swf_extract . $id . ' ' . escapeshellarg($infile) . ' -o ' . escapeshellarg($infile_tmp));
if (file_exists($infile_tmp))
$file_extracted = true;
if ($debug)
{
echo "execution fichier temporaire\n";
}
}
}
if (GV_swf_render && !$file_extracted)
{
$infile_tmp = GV_RootPath . 'tmp/temp_flash_' . time() . mt_rand(1000, 9999) . '.png';
$cmd = GV_swf_render . ' -l ' . escapeshellarg($infile) . ' -o ' . escapeshellarg($infile_tmp);
exec($cmd);
if (file_exists($infile_tmp))
$file_extracted = true;
}
if (!$file_extracted)
return false;
if (($subdefs = make1subdef($infile_tmp, $sd, $physdpath, $infos)) != false)
{
unlink($infile_tmp);
return $subdefs;
}
unlink($infile_tmp);
return false;
}
/**
* cree UNE subdef
*/
function make1subdef($infile, $sd, $physdpath, $infos)
{
$debug = false;
$return_value = false;
$system = p4utils::getSystem();
$newname = $infos['recordid'] . '_' . (string) $sd->attributes()->name . '.jpg';
$outfile = $physdpath . $newname;
$sdsize = (int) ($sd->size);
$dpi = (int) ($sd->dpi);
if ($dpi <= 0 || $dpi > 32767)
$dpi = null;
$quality = (int) ($sd->quality);
if ($quality <= 0 || $quality > 100)
$quality = 75;
$strip = (string) $sd->strip;
$strip = $strip == '' || p4field::isyes($strip); // vrai par defaut
$engine = '';
if ($sdsize > 15)
{
$err = '';
// supprimer la precedente subdef pour pouvoir tester plus bas la creation d'un nouveau fichier
@unlink($outfile);
//------------------------------------------------------------
// on essaye SIPS ?
//------------------------------------------------------------
if ($system == 'DARWIN' && !$infos['CMYK'])
{
if ($debug)
echo "\n- Try SIPS\n";
$engine = 'SIPS';
if ($infos['width'] > 0 && $infos['height'] > 0 && $infos['width'] < $sdsize && $infos['height'] < $sdsize)
{
// the doc is smaller than the wanted subdef, so adjust $sdsize
$sdsize = max($infos['width'], $infos['height']);
}
$cmd = 'sips';
$cmd .= ' -s format jpeg';
$cmd .= ' -s formatOptions ' . $quality;
$cmd .= ' -Z ' . $sdsize;
if ($dpi)
$cmd .= ' -s dpiHeight ' . $dpi . ' -s dpiWidth ' . $dpi;
if (isset($infos['Orientation']))
{
switch ($infos['Orientation'])
{
case 3: // 180 pour corriger
$cmd .= ' -r 180';
break;
case 6: // -90 trigo pour corriger
$cmd .= ' -r 90';
break;
case 8: // 90 trigo pour corriger
$cmd .= ' -r 270';
break;
}
}
$cmd .= "'" . $infile . "' --out '" . $outfile . "'";
if ($debug)
echo "\ncmd : " . $cmd . "\n";
$nullfile = '/dev/null';
$descriptors = array();
$descriptors[1] = array('file', $nullfile, 'a+t');
$descriptors[2] = array('pipe', 'w'); // stderr is a file to write to
$pipes = array();
$process = proc_open($cmd, $descriptors, $pipes);
if (is_resource($process))
{
while (!feof($pipes[2]))
$err .= fgets($pipes[2], 1024);
fclose($pipes[2]);
proc_close($process);
if ($err != '')
{
if ($debug)
echo "\n- SIPS_ERR : \n$err\n\n";
// $prop["docs"][0]["msgError"].="\nSIPS\n------\n".$err."\n";
if (file_exists($outfile))
unlink($outfile);
}
}
}
// Try to extract from raw datas
if (isRaw($infos['mime']) && (!file_exists($outfile)) || $err != '')
{
$engine = 'EXIFTOOL';
$tmpFiles = array();
if ($system == 'WINDOWS')
$cmd = 'start /B /WAIT /LOW ' . GV_exiftool;
else
$cmd = GV_exiftool;
$thisFile = $tmpFiles[] = GV_RootPath . 'tmp/' . time() . '-PI';
$cmd .= ' -b -PreviewImage "' . $infile . '" > "' . $thisFile . '"';
exec($cmd);
if ($system == 'WINDOWS')
$cmd = 'start /B /WAIT /LOW ' . GV_exiftool;
else
$cmd = GV_exiftool;
$thisFile = $tmpFiles[] = GV_RootPath . 'tmp/' . time() . '-JP';
$cmd .= ' -b -JpgFromRaw "' . $infile . '" > "' . $thisFile . '"';
exec($cmd);
$refSize = 0;
$tmpFile = false;
foreach ($tmpFiles as $file)
{
if (is_file($file) && filesize($file) > 0)
{
if (filesize($file) > $refSize)
{
$tmpFile = $file;
$refSize = filesize($file);
}
else
unlink($file);
}
else
unlink($file);
}
if (is_file($tmpFile) && filesize($tmpFile) > 0)
{
$sdsize = (int) $sd->size;
$recalc = getimagesize($tmpFile);
if (isset($recalc[0]) && isset($recalc[1]))
{
$infos['width'] = $recalc[0];
$infos['height'] = $recalc[1];
}
if ($infos['width'] > 0 && $infos['height'] > 0 && $infos['width'] < $sdsize && $infos['height'] < $sdsize)
{
$sdsize = max($infos['width'], $infos['height']);
}
if ($system == 'WINDOWS')
$cmd = 'start /B /WAIT /LOW ' . GV_imagick;
else
$cmd = GV_imagick;
$cmd .= ' -colorspace RGB -flatten -alpha Off -quiet';
if ($strip)
$cmd .= ' -strip';
$cmd .= ' -quality ' . $quality . ' -resize ' . $sdsize . 'x' . $sdsize;
if ($dpi)
$cmd .= ' -density ' . $dpi . 'x' . $dpi . ' -units PixelsPerInch';
if ($infos['mime'] == 'application/pdf' || $infos['mime'] == 'application/postscript')
$cmd .= ' -geometry ' . $sdsize . 'x' . $sdsize;
if (isset($infos['Orientation']))
{
switch ($infos['Orientation'])
{
case 3: // 180 pour corriger
$cmd .= ' -rotate 180';
break;
case 6: // -90 trigo pour corriger
$cmd .= ' -rotate 90';
break;
case 8: // 90 trigo pour corriger
$cmd .= ' -rotate -90';
break;
}
}
// attention, au cas ou il y aurait des espaces dans le path, il faut des quotes
// windows n'accepte pas les simple quotes
// pour mac les quotes pour les noms de fichiers sont indispensables car si il y a un espace -> ca plante
if (in_array($infos['mime'], array('image/tiff', 'application/pdf', 'image/psd', 'image/vnd.adobe.photoshop', 'image/photoshop', 'image/ai', 'image/illustrator', 'image/vnd.adobe.illustrator')))
$cmd .= ' "' . $tmpFile . '[0]" "' . $outfile . '"';
else
$cmd .= ' "' . $tmpFile . '" "' . $outfile . '"';
exec($cmd);
unlink($tmpFile);
}
}
//------------------------------------------------------------
// on essaye IMAGEMAGICK ?
//------------------------------------------------------------
if ((!file_exists($outfile) || $err != '' ) && GV_imagick != '')// && !$infos['CMYK']
{
if ($debug)
echo "\n- Try IMAGICK\n";
$sdsize = (int) $sd->size;
$engine = 'IMAGEMAGICK';
if (!isRaw($infos['mime']) && $infos['width'] > 0 && $infos['height'] > 0 && $infos['width'] < $sdsize && $infos['height'] < $sdsize)
{
$sdsize = max($infos['width'], $infos['height']);
}
if ($system == 'WINDOWS')
$cmd = 'start /B /WAIT /LOW ' . GV_imagick;
else
$cmd = GV_imagick;
$cmd .= ' -colorspace RGB -flatten -alpha Off -quiet';
if ($strip)
$cmd .= ' -strip';
$cmd .= ' -quality ' . $quality . ' -resize ' . $sdsize . 'x' . $sdsize;
if ($dpi)
$cmd .= ' -density ' . $dpi . 'x' . $dpi . ' -units PixelsPerInch';
$cmd .= ' -background white';
if ($infos['mime'] == 'application/pdf' || $infos['mime'] == 'application/postscript')
$cmd .= ' -geometry ' . $sdsize . 'x' . $sdsize;
if (isset($infos['Orientation']))
{
switch ($infos['Orientation'])
{
case 3: // 180 pour corriger
$cmd .= ' -rotate 180';
break;
case 6: // -90 trigo pour corriger
$cmd .= ' -rotate 90';
break;
case 8: // 90 trigo pour corriger
$cmd .= ' -rotate -90';
break;
}
}
// attention, au cas ou il y aurait des espaces dans le path, il faut des quotes
// windows n'accepte pas les simple quotes
// pour mac les quotes pour les noms de fichiers sont indispensables car si il y a un espace -> ca plante
$array = array('image/tiff', 'application/pdf', 'image/psd', 'image/vnd.adobe.photoshop', 'image/photoshop', 'image/ai', 'image/illustrator', 'image/vnd.adobe.illustrator');
if (in_array($infos['mime'], $array))
$cmd .= ' "' . $infile . '[0]" "' . $outfile . '"';
else
$cmd .= ' "' . $infile . '" "' . $outfile . '"';
// printf("%s\n", $cmd);
$res = exec($cmd);
if ($debug)
echo "execution commande $cmd\n";
}
//------------------------------------------------------------
// on essaye GD ?
//------------------------------------------------------------
if ((!file_exists($outfile)) || $err != '')
{
if ($debug)
echo "\n- Try GD\n";
$engine = 'GD2';
$imag_original = @imagecreatefromjpeg($infile);
if ($imag_original)
{
$w_doc = imagesx($imag_original);
$h_doc = imagesy($imag_original);
if ($w_doc < $sdsize && $h_doc < $sdsize)
{
// doc is too small, don't resize
$img_mini = imagecreatetruecolor($w_doc, $h_doc);
imagecopy($img_mini, $imag_original, 0, 0, 0, 0, $w_doc, $h_doc);
}
else
{
// cherche le max des 2 valeurs pour creer le coeff de resize
if ($w_doc > $h_doc)
$h_sub = (int) (($h_doc / $w_doc) * ($w_sub = $sdsize));
else
$w_sub = (int) (($w_doc / $h_doc) * ($h_sub = $sdsize));
$img_mini = imagecreatetruecolor($w_sub, $h_sub);
$sdmethod = trim((string) ($sd->method));
if (strtoupper($sdmethod) == 'RESAMPLE')
imagecopyresampled($img_mini, $imag_original, 0, 0, 0, 0, $w_sub, $h_sub, $w_doc, $h_doc);
else
imagecopyresized($img_mini, $imag_original, 0, 0, 0, 0, $w_sub, $h_sub, $w_doc, $h_doc);
}
if (isset($infos['Orientation']))
{
switch ($infos['Orientation'])
{
case 3: // 180e pour corriger
$img_mini = imagerotate($img_mini, 180, 0);
// printf("rot 180<br/>");
break;
case 6: // -90 trigo pour corriger
$img_mini = imagerotate($img_mini, 270, 0);
$z = $w_sub;
$w_sub = $h_sub;
$h_sub = $z;
// printf("rot 270 trigo<br/>");
break;
case 8: // 90 trigo pour corriger
$img_mini = imagerotate($img_mini, 90, 0);
$z = $w_sub;
$w_sub = $h_sub;
$h_sub = $z;
// printf("rot 90 trigo<br/>");
break;
}
}
imagejpeg($img_mini, $outfile, $quality);
imagedestroy($img_mini);
imagedestroy($imag_original);
}
}
if (file_exists($outfile))
{
if (function_exists('chgrp') && GV_filesGroup != null)
$r = chgrp($outfile, GV_filesGroup);
p4::chmod($outfile);
$tempHD = getimagesize($outfile);
$return_value = array();
$return_value['engine'] = $engine;
$return_value['file'] = $newname;
$return_value['width'] = $tempHD[0];
$return_value['height'] = $tempHD[1];
$mimeExt = giveMimeExt($outfile);
$return_value['mime'] = $mimeExt['mime'];
}
else
{
$return_value = array();
$return_value['engine'] = '?';
$return_value['file'] = $newname;
$return_value['width'] = 666;
$return_value['height'] = 666;
$return_value['mime'] = 'image/jpeg';
}
}
return($return_value);
}
function pdf_from_document($infile)
{
$debug = false;
if (!GV_unoconv)
return false;
$tmp_file = GV_RootPath . 'tmp/tmp_doc_' . time() . mt_rand(10000, 99999) . '.pdf';
$cmd = GV_unoconv . ' --format=pdf --stdout ' . escapeshellarg($infile) . ' > ' . escapeshellarg($tmp_file);
if (GV_debug)
{
echo "\nexecution commande : $cmd\n";
}
$nullfile = '/dev/null';
$descriptors = array();
$descriptors[1] = array('pipe', 'w');
$descriptors[2] = array('pipe', 'w'); // stderr is a file to write to
$pipes = array();
$process = proc_open($cmd, $descriptors, $pipes);
$err = $stdout = '';
$id = false;
if (is_resource($process))
{
while (!feof($pipes[2]))
$err .= fgets($pipes[2], 1024);
fclose($pipes[2]);
while (!feof($pipes[1]))
$stdout .= fgets($pipes[1], 1024);
fclose($pipes[1]);
proc_close($process);
}
if (!is_file($tmp_file) || filesize($tmp_file) == 0)
return false;
return $tmp_file;
}
function swf_from_document($infile, $outfile)
{
$infile = pdf_from_document($infile);
if (!$infile)
return false;
return swf_from_pdf($infile, $outfile, true);
}
function swf_from_pdf($infile, $outfile, $delete_infile = false)
{
$debug = false;
if (!GV_pdf2swf)
return false;
$system = p4utils::getSystem();
if ($system == 'WINDOWS')
$cmd = GV_pdf2swf . ' "' . $infile . '" "' . $outfile . '" -T 9 -f';
else
$cmd = GV_pdf2swf . ' "' . $infile . '" "' . $outfile . '" -Q 300 -T 9 -f';
if (GV_debug)
{
echo "\nexecution commande : $cmd\n";
}
$nullfile = '/dev/null';
$descriptors = array();
$descriptors[1] = array('pipe', 'w');
$descriptors[2] = array('pipe', 'w'); // stderr is a file to write to
$pipes = array();
$process = proc_open($cmd, $descriptors, $pipes);
$err = $stdout = '';
$id = false;
if (is_resource($process))
{
while (!feof($pipes[2]))
$err .= fgets($pipes[2], 1024);
fclose($pipes[2]);
while (!feof($pipes[1]))
$stdout .= fgets($pipes[1], 1024);
fclose($pipes[1]);
proc_close($process);
}
if ($delete_infile)
@unlink($infile);
return $outfile;
}
function make1Documentsubdef($infile, $sd, $physdpath, $infos)
{
$debug = false;
if (GV_debug)
{
echo "\nPreparation des sous defintions Document\n";
}
$newname = $infos['recordid'] . '_' . (string) $sd->attributes()->name . '.jpg';
$outfile = $physdpath . $newname;
if ($sd->attributes()->name == 'preview')
{
$newname = $infos['recordid'] . '_' . (string) $sd->attributes()->name . '.swf';
$outfile = $physdpath . $newname;
if ($infos['mime'] == 'application/pdf')
{
if (swf_from_pdf($infile, $outfile))
{
$retour = array();
$retour['width'] = 0;
$retour['height'] = 0;
$retour['mime'] = 'application/x-shockwave-flash';
$retour['file'] = $newname;
return $retour;
}
}
else
{
if (swf_from_document($infile, $outfile))
{
$retour = array();
$retour['width'] = 0;
$retour['height'] = 0;
$retour['mime'] = 'application/x-shockwave-flash';
$retour['file'] = $newname;
return $retour;
}
}
}
else
{
if ($infos['mime'] == 'application/pdf')
{
$tmp_file = $infile;
$delete = false;
}
else
{
$tmp_file = pdf_from_document($infile);
$delete = true;
}
if ($tmp_file)
{
$infos['mime'] = 'application/pdf';
if (($subdefs = make1subdef($tmp_file, $sd, $physdpath, $infos)) != false)
{
if ($delete)
unlink($tmp_file);
return $subdefs;
}
}
}
return false;
}
function make1AudioSubdef($infile, &$sd, $physdpath, &$infos)
{
$debug = false;
$retour = false;
$sdtype = trim(mb_strtolower($sd->mediatype)); //MP3/JPG
$sdname = $sd->attributes()->name;
$sdtypeOK = array('audio', 'image');
if ($debug)
echo "\n::::::::::::::::::::::::::::::::::::::::::::::::::\narrivee dans make1audiosubdef AVEC PARAMS : sdname - $sdname et sdtype - $sdtype \n:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::\n";
if (!in_array($sdtype, $sdtypeOK))
return $retour;
if ($sdtype == 'audio')
{
if ($debug)
echo "\nGENERATING " . $sdname . " " . $sdtype . "....\n";
$newname = $infos['recordid'] . '_' . $sdname . '.mp3';
$dest = $physdpath . $newname;
// $audioEnc = '';
// if(trim($srcAB) != '' && trim($srcAB) !='')
// {
// $okMp3BR = array('44100'=>true, '22050'=>true, '11025'=>true);
// if(!isset($srcAR) || trim($srcAR) == '' || !array_key_exists($srcAR,$okMp3BR))
// $srcAR = '44100';
//
// if($srcAB == '0' || trim($srcAB)=='')
// $srcAB = '0';
//
// $audioEnc = ' -ar ' . $srcAR . ' -ab ' . $srcAB .'k -acodec libmp3lame ';
// }
$ffmpeg = trim(GV_ffmpeg) != '' ? GV_ffmpeg : false;
if ($ffmpeg)
{
$cmd = $ffmpeg . ' -i \'' . $infile . '\' ' . $dest;
if ($debug)
echo "\n\n\n\nEXECUTION COMMANDE :::: " . $cmd . "\n\n\n\n";
$errArr = '';
@exec($cmd, $errArr);
$retour['width'] = 0;
$retour['height'] = 0;
$retour['mime'] = 'audio/mpeg'; //'image/jpeg' ;
$retour['file'] = $newname;
}
}
if ($sdtype == 'image')
{
if ($debug)
echo "\nGENERATING " . $sdname . " " . $sdtype . "....\n";
$newname = $infos['recordid'] . '_' . $sdname . '.jpg';
$dest = $physdpath . $newname;
//On check si y'a pas une image integre au bouzi
$out = null;
$cmd = GV_exiftool . ' -s -t ' . $infile;
exec($cmd, $out);
$found = false;
if ($out)
{
foreach ($out as $outP)
{
$infos = explode("\t", $outP);
if (count($infos) == 2)
{
if ($infos[0] == 'Picture')
{
if ($debug)
echo "\nUne emebedded pic est presente dans l'image, on l'extrait...\n";
$cmd = GV_exiftool . ' -b -Picture ' . $infile . ' > ' . $dest;
exec($cmd);
if (is_file($dest))
{
if (filesize($dest) > 0)
{
$retour['width'] = 0;
$retour['height'] = 0;
$sizes = null;
$sizes = getimagesize($dest);
if ($sizes)
{
$retour['width'] = $sizes[0];
$retour['height'] = $sizes[1];
}
$mimeOut = giveMimeExt($dest);
$retour['mime'] = $mimeOut['mime']; //'image/jpeg' ;
$retour['file'] = $newname;
$found = true;
}
else
{
@unlink($dest);
}
}
}
}
}
}
if (!$found)
{
if (copy(GV_RootPath . 'www/skins/icons/audio.png', $dest))
{
$retour['width'] = 128;
$retour['height'] = 128;
$retour['mime'] = 'image/jpeg';
$retour['file'] = $newname;
}
}
}
if ($debug)
{
echo "\n ce que l'on retourne :";
var_dump($retour);
}
return $retour;
}
function make1VideoSubdef($infile, &$sd, $physdpath, &$infos)
{
$debug = false;
$system = p4utils::getSystem();
$retour = false;
$sdtype = trim(mb_strtolower($sd->mediatype));
$sdname = $sd->attributes()->name;
$sdtypeOK = array('gif', 'video', 'image');
if ($debug)
echo "\n::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::\narrivee dans make1videosubdef AVEC PARAMS : sdname - $sdname et sdtype - $sdtype \n:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::\n";
if (!in_array($sdtype, $sdtypeOK))
{
if ($debug)
echo "nothing avalaible\n";
return $retour;
}
$ffmpeg = false;
$ffmpeg = trim(GV_ffmpeg) != '' ? GV_ffmpeg : false;
$videoprops = getVideoInfos($infile);
if ($debug)
{
echo "voila les videoprops : \n";
var_dump($videoprops);
}
$ratio_supposed = (int) $videoprops['width'] / (int) $videoprops['height'];
$ratio = $ratio_get = (float) $videoprops['video_aspect'];
if ($ratio_get == 0)
{
$ratio = $ratio_supposed;
}
if ($ratio != $ratio_supposed)
{
$videoprops['width'] = $ratio * $videoprops['height'];
if ($debug)
echo "correction des dimensions via aspect ratio\n";
}
if ($debug)
echo "Check de la width\n";
$srcWidth = get_multiple($videoprops['width'], 16);
if ($debug)
echo "Check de la height\n";
$srcHeight = get_multiple($videoprops['height'], 16);
if ($debug)
echo "Check framerate\n";
$srcFPS = $videoprops['frameRate'];
if ($debug)
echo "Check audiobitrate\n";
$srcAB = intval($videoprops['audiobitrate'] / 1000);
if ($debug)
echo "Check audiop sample rate\n";
$srcAR = $videoprops['audiosamplerate'];
//calcul des dimensions de la subdef :
$maxSize = get_multiple($sd->size, 16, 'bottom');
if ($debug)
echo "\nLa source est a " . $srcWidth . "x" . $srcHeight . "....\n";
if ($debug)
echo "\nLa taille max est a " . $maxSize . "....\n";
if ($srcWidth > $maxSize || $srcHeight > $maxSize)
{
//une des dimensions est superieure
if ($srcWidth >= $srcHeight)//paysage
{
$newWidth = (int) $maxSize;
$newHeight = get_multiple(round($newWidth * $srcHeight / $srcWidth), 16);
}
else
{
$newHeight = (int) $maxSize;
$newWidth = get_multiple(round($newHeight * $srcWidth / $srcHeight), 16);
}
}
else
{
$newHeight = get_multiple($srcHeight, 16);
$newWidth = get_multiple($srcWidth, 16);
}
if ($debug)
echo "\nLa sortie est " . $newWidth . "x" . $newHeight . "....\n";
if ($sdtype == 'video' && $ffmpeg)
{
$cwd = getcwd();
chdir(GV_RootPath . 'tmp/');
if ($debug)
echo "\nGENERATING " . $sdname . " " . $sdtype . "....\n";
$fps = 25;
if (isset($sd->fps) && is_numeric((int) $sd->fps))
$fps = (int) $sd->fps;
$bit_rate = 1000;
if (isset($sd->bitrate) && is_numeric((int) $sd->bitrate))
$bit_rate = (int) $sd->bitrate;
$nb_threads = 1;
if (isset($sd->threads) && is_numeric((int) $sd->threads))
$nb_threads = (int) $sd->threads;
$v_codec = 'libx264';
$v_codecs = array(
'x264' => 'libx264',
'h264' => 'libx264',
'libx264' => 'libx264',
'libh264' => 'h264',
'flv' => 'flv',
'flash' => 'flv'
);
if (isset($sd->vcodec))
{
$t_v_codec = (string) $sd->vcodec;
if (array_key_exists($t_v_codec, $v_codecs))
$v_codec = $v_codecs[$t_v_codec];
}
$a_codec = 'libfaac';
$a_codecs = array(
'faac' => 'libfaac',
'libfaac' => 'libfaac',
'mp3' => 'libmp3lame'
);
if (isset($sd->acodec))
{
$t_a_codec = (string) $sd->acodec;
if (array_key_exists($t_a_codec, $a_codecs))
$a_codec = $a_codecs[$t_a_codec];
}
if ($v_codec == 'flv')
$newname = $infos['recordid'] . '_' . $sdname . '.flv';
else
$newname = $infos['recordid'] . '_' . $sdname . '.mp4';
$dest = $physdpath . $newname;
$dest_pass1 = $dest . '-tmp.mp4';
if ($system == 'WINDOWS')
$cmd_part1 = $ffmpeg . ' -y -i \'' . str_replace('/', "\\", $infile) . '\' ';
else
$cmd_part1 = $ffmpeg . ' -y -i \'' . $infile . '\' ';
if (in_array($v_codec, array('libx264', 'h264')))
{
$cmd_part2 = ' -s ' . $newWidth . 'x' . $newHeight . ' -r ' . $fps . ' -vcodec ' . trim($v_codec) . ' -b ' . trim($bit_rate) . 'k -g 25 -bf 3' .
' -threads ' . $nb_threads . ' -refs 6 -b_strategy 1 -coder 1 -qmin 10 -qmax 51 -sc_threshold 40 -flags +loop -cmp +chroma' .
' -me_range 16 -subq 7 -i_qfactor 0.71 -qcomp 0.6 -qdiff 4 -directpred 3 -flags2 +dct8x8+wpred+bpyramid+mixed_refs' .
' -trellis 1 -partitions +parti8x8+parti4x4+partp8x8+partp4x4+partb8x8 -acodec ' . trim($a_codec) . ' -ab 92k ';
$cmd_pass1 = $cmd_part1 . ' -pass 1 ' . $cmd_part2 . ' -an ' . $dest_pass1;
$cmd_pass2 = $cmd_part1 . ' -pass 2 ' . $cmd_part2 . ' -ac 2 -ar 44100 ' . $dest;
if ($debug)
echo "\n\n\n\nEXECUTION COMMANDE :::: " . $cmd_pass1 . "\n\n\n\n";
if (is_file($dest))
unlink($dest);
$errArr = '';
@exec($cmd_pass1, $errArr);
if ($debug)
echo "\n\n\n\nEXECUTION COMMANDE :::: " . $cmd_pass2 . "\n\n\n\n";
$errArr = '';
@exec($cmd_pass2, $errArr);
if (is_file($dest_pass1))
unlink($dest_pass1);
make_mp4_progressive($dest);
}
else
{
$audioEnc = '';
if (trim($srcAB) != '' && trim($srcAB) != '')
{
$okMp3BR = array('44100' => true, '22050' => true, '11025' => true);
if (!isset($srcAR) || trim($srcAR) == '' || !array_key_exists($srcAR, $okMp3BR))
$srcAR = '44100';
if ($srcAB == '0' || trim($srcAB) == '')
$srcAB = '0';
$audioEnc = ' -ar ' . $srcAR . ' -ab ' . $srcAB . 'k -acodec libmp3lame ';
}
$fps = 15;
if (isset($sd->fps) && is_numeric((int) $sd->fps))
$fps = (int) $sd->fps;
if ($system == 'WINDOWS')
$cmd = $ffmpeg . ' -y -i \'' . str_replace('/', "\\", $infile) . '\' ';
else
$cmd = $ffmpeg . ' -y -i \'' . $infile . '\' ';
$cmd .= $audioEnc .
' -f flv -nr 500 -s ' . $newWidth . 'x' . $newHeight . '' .
' -r ' . $fps . //$srcFPS.
' -b 270k -me_range ' . $srcFPS . ' -i_qfactor 0.71 -g 500 ' . $dest;
if ($debug)
echo "\n\n\n\nEXECUTION COMMANDE :::: " . $cmd . "\n\n\n\n";
$errArr = '';
@exec($cmd, $errArr);
}
$retour['width'] = $newWidth;
$retour['height'] = $newHeight;
if ($v_codec == 'flv')
$retour['mime'] = 'video/x-flv'; //'image/jpeg' ;
else
$retour['mime'] = 'video/mp4'; //'image/jpeg' ;
$retour['file'] = $newname;
chdir($cwd);
}
if ($sdtype == 'image')
{
if ($debug)
echo "\nGENERATING " . $sdname . " " . $sdtype . "....\n";
$newname = $infos['recordid'] . '_' . $sdname . '.jpg';
$dest = $physdpath . $newname;
$tmpDir = GV_RootPath . 'tmp/' . 'tmp' . time();
p4::fullmkdir($tmpDir);
$tmpDir = p4string::addEndSlash($tmpDir);
$tmpFile = $tmpDir . $newname . '-tmp.jpg';
$time_tot = $videoprops['duration'];
$time_cut = round($videoprops['duration'] * 0.6);
$time_cut = $time_cut < 1 ? 1 : $time_cut;
if ($system == 'WINDOWS')
$cmd = GV_ffmpeg . ' -i ' . str_replace('/', "\\", $infile) . ' -s ' . $newWidth . 'x' . $newHeight . ' -vframes 1 -ss ' . $time_cut . ' -f image2 ' . $tmpFile;
else
$cmd = GV_ffmpeg . ' -i ' . $infile . ' -s ' . $newWidth . 'x' . $newHeight . ' -vframes 1 -ss ' . $time_cut . ' -f image2 ' . $tmpFile;
$errArr = '';
@exec($cmd, $errArr);
echo "\nCommande executee : $cmd \n";
if (file_exists($tmpFile))
{
$cmd = GV_pathcomposite . ' -gravity SouthEast -quiet -compose over "' . GV_RootPath . 'www/skins/icons/play.png" "' . $tmpFile . '" "' . $dest . '"';
$errArr = '';
exec($cmd, $errArr);
unlink($tmpFile);
echo "\nLE TEMP FILE : $tmpFile --- \n la cmd : $cmd \n";
}
if (is_dir($tmpDir))
@rmdir($tmpDir);
$retour['width'] = $newWidth;
$retour['height'] = $newHeight;
$retour['mime'] = 'image/jpeg'; //'image/jpeg' ;
$retour['file'] = $newname;
}
if ($sdtype == 'gif')
{
if ($debug)
echo "\nGENERATING " . $sdname . " " . $sdtype . "....\n";
//on calcule l'intervalle entre deux images clef et on va determiner combien d'image clef sauter pour chaque extrait
$newname = $infos['recordid'] . '_' . $sdname . '.gif';
$dest = $physdpath . $newname;
$tmpDir = GV_RootPath . 'tmp/' . 'tmp' . time();
p4::fullmkdir($tmpDir);
$tmpDir = p4string::addEndSlash($tmpDir);
if ($system == 'WINDOWS')
$cmd = GV_ffmpeg . ' -s ' . $newWidth . 'x' . $newHeight . ' -i ' . str_replace('/', "\\", $infile) . ' -r 1 -f image2 ' . $tmpDir . 'images%05d.jpg';
else
$cmd = GV_ffmpeg . ' -s ' . $newWidth . 'x' . $newHeight . ' -i ' . $infile . ' -r 1 -f image2 ' . $tmpDir . 'images%05d.jpg';
$errArr = '';
@exec($cmd, $errArr);
$files = array();
if ($hdir = opendir($tmpDir))
{
while ($file = readdir($hdir))
{
if (!in_array($file, array('.', '..')))
{
$files[$file] = $tmpDir . $file;
}
}
}
ksort($files);
$n = count($files);
$inter = round(count($files) / 10);
$i = 0;
foreach ($files as $k => $file)
{
if ($i % $inter !== 0)
{
if (unlink($file))
unset($files[$k]);
}
else
{
if ($srcWidth != $newWidth || $srcHeight != $newHeight)
{
resizeImage($file, $newWidth, $newHeight);
if ($debug)
echo "\nOn resize le GIF KeyFrame a " . $newWidth . " " . $newHeight . "....\n";
}
if (is_numeric($i))
{
$d = answer::format_duration($i);
if ($system == 'WINDOWS')
passthru(GV_imagick . ' -fill white -pointsize 15 -undercolor black -gravity south -draw "text 0,0 \'' . $d . '\'" ' . str_replace('/', "\\", $file) . ' ' . str_replace('/', "\\", $file));
else
passthru(GV_imagick . ' -fill white -pointsize 15 -undercolor black -gravity south -draw "text 0,0 \'' . $d . '\'" ' . $file . ' ' . $file);
}
}
$i++;
}
passthru(GV_imagick . ' -delay 100 -loop 0 ' . $tmpDir . '*.jpg ' . $dest);
foreach ($files as $file)
unlink($file);
if (is_dir($tmpDir))
@rmdir($tmpDir);
$retour['width'] = $newWidth;
$retour['height'] = $newHeight;
$retour['mime'] = 'image/gif'; //'image/jpeg' ;
$retour['file'] = $newname;
}
if ($debug)
{
echo "\n ce que l'on retourne :";
var_dump($retour);
}
return $retour;
}
function make_mp4_progressive($mp4_file)
{
$debug = false;
if ($debug)
echo "\nchecking mp4 box for mp4 progressive video ....\n";
if (defined('GV_mp4box') && is_executable(GV_mp4box))
{
if ($debug)
echo "\nmp4 box OK, doing it\n";
$cmd = GV_mp4box . ' -inter 0.5 ' . escapeshellarg($mp4_file);
$errArr = '';
@exec($cmd, $errArr);
$ret = true;
}
else
{
if ($debug)
echo "\nNO mp4 box OK, PHP way\n";
$tmpFile = $mp4_file . '-tmp.mp4';
$moovrelocator = moov_relocator::getInstance();
$debug = false;
if ($debug)
echo "\nfichier en arrivee : $mp4_file : " . filesize($mp4_file) . " \n";
$ret = $moovrelocator->setInput($mp4_file);
if ($ret === true)
$ret = $moovrelocator->setOutput($tmpFile);
if ($ret === true)
$ret = $moovrelocator->fix();
if ($ret === true)
{
unlink($mp4_file);
rename($tmpFile, $mp4_file);
}
}
if ($debug)
echo "\nfichier en sortie : $mp4_file : " . filesize($mp4_file) . " \n";
return $ret;
}
function get_multiple($value, $multiple, $bound='nearest')
{
$modulo = $value % $multiple;
$ret = 0;
if ($bound == 'nearest')
{
$half_distance = $multiple / 2;
if ($modulo <= $half_distance)
$bound = 'bottom';
else
$bound = 'top';
}
switch ($bound)
{
default:
case 'top':
$ret = $value + $multiple - $modulo;
break;
case 'bottom':
$ret = $value - $modulo;
break;
}
if ($ret < $multiple)
$ret = $multiple;
return (int) $ret;
}
function resizeImage($file, $width, $height)
{
$fullImage = imagecreatefromjpeg($file);
$fullSize = getimagesize($file);
if (!file_exists($file . '_resized'))
{
$tnImage = imagecreatetruecolor($width, $height);
imagecopyresampled($tnImage, $fullImage, 0, 0, 0, 0, $width, $height, $fullSize[0], $fullSize[1]);
imagejpeg($tnImage, $file . '_resized');
imagedestroy($fullImage);
imagedestroy($tnImage);
if (unlink($file))
{
if (rename($file . '_resized', $file))
return true;
}
}
return false;
}
?>