WSCOMUN  2.1.2
Web Services Comunes para PHP/GVHidra
AlfrescoClient.php
1 <?php
2 namespace WSCOMUN\GDE;
3 
10 {
12  private $loginURL;
13 
15  private $uploadURL;
16 
18  private $downloadURL;
19 
21  private $user;
22 
24  private $password;
25 
27  private $idApp;
28 
30  private $curlEnabled;
31 
41  public function __construct($user, $password, $loginURL, $uploadURL, $downloadURL)
42  {
43  $this->user = $user;
44  $this->password = $password;
45  $this->loginURL = $loginURL;
46  $this->downloadURL = $downloadURL;
47  $this->uploadURL = $uploadURL;
48 
49  $this->curlEnabled = function_exists('curl_version');
50  }
51 
52 
58  public function getTicket()
59  {
60  $ticket = '';
61  $url = $this->loginURL.'?u='.$this->user.'&pw='.$this->password;
62 
63  try
64  {
65  $xmlString = $this->urlGetContents($url);
66  }
67  catch (\Exception $e)
68  {
69  throw $e;
70  }
71 
72  if ($xmlString === false)
73  {
74  $errorMsg = error_get_last();
75  throw new \Exception(__CLASS__.'::'.__METHOD__.": No puede alcanzarse la URL de login: ".$url." Error: ".print_r($errorMsg, true));
76  }
77  try
78  {
79  $xml = simplexml_load_string($xmlString);
80  }
81  catch (\Exception $e)
82  {
83  $mensaje = "Error en el parseo del XML. ".$e->getMessage();
84  throw new \Exception($mensaje);
85  }
86 
87 
88  if (isset($xml->response))
89  {
90  $errorCode = (integer) $xml->response->status->code;
91  $descError = (string) $xml->response->status->name . '-' . (string) $xml->response->status->description;
92  throw new \Exception("Error del login: ".$descError, $errorCode);
93  }
94 
95  $ticket = (string) $xml[0];
96  return $ticket;
97  }//getTicket
98 
99 
105  public function getDocument($refGDE)
106  {
107  $doc = null;
108  try
109  {
110  $ticket = $this->getTicket();
111  $url = $this->downloadURL.'?alf_ticket='.$ticket.'&referenciaGDE='.$refGDE;
112  $doc = $this->urlGetContents($url);
113  }
114  catch (\Exception $e)
115  {
116  throw $e;
117  }
118 
119  if (empty($doc))//REVIEW ¿Retorno si no existe
120  {
121  $mensaje = "No existe el documento con referencia GDE: $refGDE";
122  throw new \Exception($mensaje);
123  }
124  return ($doc);
125  }//getDocument()
126 
127 
138  public function insertDocument($idApp, $rutaFicheroEnServer, $rutaDestinoAlf = '/', $nombreDoc = '', $descDoc = '')
139  {
140  $vFileParts = pathinfo($rutaFicheroEnServer);
141 
142  $nombreDoc = empty($nombreDoc)?$vFileParts['basename']:$nombreDoc;
143  $descDoc = empty($descDoc)?$vFileParts['basename']:$descDoc;
144 
145  try
146  {
147  if ($this->curlEnabled)
148  {
149  $respuesta = $this->insertDocumentCURL($idApp, $rutaFicheroEnServer, $rutaDestinoAlf, $nombreDoc, $descDoc);
150  }
151  else
152  {
153  $respuesta = $this->insertDocumentHTTPRequest($idApp, $rutaFicheroEnServer, $rutaDestinoAlf, $nombreDoc, $descDoc);
154  }
155  }
156  catch (\Exception $e)
157  {
158  throw $e;
159  }
160 
161  $refGDE = '';
162 
163  //Parseamos la referencia GDE
164  $respuesta = ' '.$respuesta;
165  $ini = strpos($respuesta, 'Referencia GDE: ');
166  if ($ini == 0)
167  {
168  $mensaje = "No se obtuvo referencia GDE";
169  throw new \Exception($mensaje);
170  }
171  $ini += strlen('Referencia GDE: ');
172  $len = stripos($respuesta, '</td></tr>', $ini) - $ini;
173  $refGDE = substr($respuesta, $ini, $len);
174 
175  return $refGDE;
176 
177  }//insertDocument()
178 
179 
180  public function getLoginUrl() {
181  return $this->loginUrl;
182  }
183 
184  public function setLoginUrl($loginUrl) {
185  $this->loginUrl = $loginUrl;
186  }
187 
188  public function getUser() {
189  return $this->user;
190  }
191 
192  public function setUser($user) {
193  $this->user = $user;
194  }
195 
196  public function getPassword() {
197  return password;
198  }
199 
200  public function setPassword($password) {
201  $this->password = $password;
202  }
203 
204  public function getUploadUrl() {
205  return $this->uploadUrl;
206  }
207 
208  public function setUploadUrl($uploadUrl) {
209  $this->uploadUrl = $uploadUrl;
210  }
211 
212  public function getDownloadUrl() {
213  return $this->downloadUrl;
214  }
215 
216  public function setDownloadUrl($downloadUrl) {
217  $this->downloadUrl = downloadUrl;
218  }
219 
220  public function getIdApp() {
221  return $this->idApp;
222  }
223 
224  public function setIdApp($idApp) {
225  $this->idApp = $idApp;
226  }
227 
228 
229 
230 
241  private function insertDocumentCURL($idApp, $rutaFicheroEnServer, $rutaDestinoAlf, $nombreDoc, $descDoc)
242  {
243  try
244  {
245  $ticket = $this->getTicket();
246  if (function_exists('curl_file_create')) // php >= 5.5
247  {
248  $cFile = curl_file_create($rutaFicheroEnServer);
249  }
250  else
251  {
252  //VER: http://php.net/manual/es/function.curl-file-create.php#114538
253  $cFile = '@' . realpath($rutaFicheroEnServer).';filename='.$nombreDoc;
254  }
255 
256  $url = $this->uploadURL.'?alf_ticket='.$ticket;
257  $postFields = array (
258  'idApp' => $idApp,
259  'alf_ticket' => $ticket,
260  'file' => $cFile,
261  'title' => $nombreDoc,
262  'desc' => $descDoc,
263  'rutaDestino' => $rutaDestinoAlf
264  );
265 
266  $curl = curl_init();
267  curl_setopt($curl, CURLOPT_URL,$url);
268  curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
269  curl_setopt($curl, CURLOPT_POST, true);
270  curl_setopt($curl, CURLOPT_POSTFIELDS, $postFields);
271  $response = curl_exec($curl);
272  $status = curl_getinfo($curl, CURLINFO_HTTP_CODE);
273 
274  switch ($status)
275  {
276  case 200:
277  case 202:
278  ; //Todo Ok
279  break;
280 
281  default:
282  $mensaje = "Error: la llamada a URL $url ha fallado con estado $status, respuesta $response, Error CURL: " . curl_error($curl);
283  throw new \Exception($mensaje, $status);
284  break;
285  }
286 
287  curl_close($curl);
288  return $response;
289 
290  }
291  catch (\Exception $e)
292  {
293  throw $e;
294  }
295  }//Fin insertDocumentCURL
296 
297 
308  private function insertDocumentHTTPRequest($idApp, $rutaFicheroEnServer, $rutaDestinoAlf, $nombreDoc, $descDoc)
309  {
310  $ticket = $this->getTicket();//Obtenemos el acceso a Alfresco
311  $url = $this->uploadURL.'?alf_ticket='.$ticket;
312 
313  //Preparamos campos del formulario
314  $postFields = array (
315  'idApp' => $idApp,
316  'title' => $nombreDoc,
317  'desc' => $descDoc,
318  'rutaDestino' => $rutaDestinoAlf,
319  );
320 
321  $vURL = parse_url($url);
322  if (! (($vURL['scheme'] == 'http') || ($vURL['scheme'] == 'https')) )
323  {
324  $mensaje = "Solo se soporta POST hacia HTTP/HTTPS.";
325  throw new \Exception ($mensaje);
326  }
327  $port = (isset($vURL['port']) ? $vURL['port'] : 80);
328 
329  $hostURL = $vURL['host'];
330  $pathURL = $vURL['path'];
331  $queryURL = $vURL['query'];
332 
333  $errno = null; $errstr = '';
334  $fp = fsockopen($hostURL, $port, $errno, $errstr, 60);
335  if(!$fp)
336  {
337  $mensaje ="Error al acceder a $url. $errstr ($errno)";
338  throw new \Exception($mensaje);
339  }
340 
341  $boundary = '--'.uniqid();//Generamos un boundary
342  $crlf = "\r\n";
343  //Request principal
344  $httpRequest = "POST $pathURL?$queryURL HTTP/1.1" . $crlf;
345  $httpRequest.= "Host: $hostURL" . $crlf;
346  $httpRequest.= "User-Agent: " . $_SERVER['HTTP_USER_AGENT'] . $crlf;
347  $httpRequest.= empty($ticket)?"(Authorization: Basic ".base64_encode($this->user.':'.$this->password) . $crlf:'';//Autorización alternativa
348  $httpRequest.= "Content-type: multipart/form-data; boundary=$boundary" . $crlf;
349 
350  //Sub request
351  $body = '';
352 
353  //Para cada elemento del formulario
354  foreach($postFields as $key => $value)
355  {
356  $valueLength = strlen($value);
357  $body .= '--'.$boundary.$crlf
358  .'Content-Disposition: form-data; name="'.$key.'"'.$crlf
359  .'Content-Length: '.$valueLength.$crlf
360  .$crlf.$value.$crlf;
361  }
362 
363  //Anexamos el fichero
364  $mimetype = self::getMimeType(basename($rutaFicheroEnServer));
365  $file_contents = file_get_contents($rutaFicheroEnServer);
366  if($file_contents === false)
367  {
368  $mensaje ="Error al leer el fichero $rutaFicheroEnServer";
369  throw new \Exception($mensaje);
370  }
371  $body .= '--'.$boundary.$crlf
372  .'Content-Disposition: form-data; name="file"; filename="'.$nombreDoc.'"'.$crlf
373  .'Content-Type: '.$mimetype.$crlf
374  .'Content-Transfer-Encoding : base64'.$crlf
375  .'Content-Length: '.strlen($file_contents).$crlf
376  .$crlf.$file_contents.$crlf;
377  $body .= '--'.$boundary.'--';
378  unset($file_contents); $file_contents = null; gc_collect_cycles();//Liberamos memoria
379  $httpRequest.= "Content-length: ". strlen($body) . $crlf;
380  $httpRequest.= "Connection: close\r\n\r\n";
381  $httpRequest .= $body . $crlf.$crlf;
382 
383  //Envío de la request
384  $write = fwrite($fp, $httpRequest);
385  if($write === false)
386  {
387  $mensaje ="Error al enviar la REQUEST";
388  throw new \Exception($mensaje);
389  }
390 
391  //Liberamos memoria
392  unset($httpRequest); $httpRequest = null; gc_collect_cycles();
393 
394  //Leemos la respuesta
395  $response = '';
396  while(!feof($fp))//Mientras no finalice la recepción...
397  {
398  $response .= fgets($fp);
399  }
400  fclose($fp); // Cerramos el socket
401 
402  // Separamos cabecera y contenido
403  $result = explode($crlf.$crlf, $response, 2);
404  $content = isset($result[1]) ? $result[1] : '';
405 
406  return $content;
407 
408  }//Fin insertDocumentHTTPRequest
409 
410 
416  public static function getMimeType($fileName)
417  {
418  $fileExtension = trim(strtolower(array_pop(explode('.',$fileName))));
419  //Vector de tipos MIME
420  $mime_types = array
421  (
422  //texto
423  'txt' => 'text/plain',
424  'htm' => 'text/html',
425  'html' => 'text/html',
426  'php' => 'text/html',
427  'css' => 'text/css',
428  'js' => 'application/javascript',
429  'json' => 'application/json',
430  'xml' => 'application/xml',
431  'csv' => 'text/csv',
432 
433  // imágenes
434  'png' => 'image/png',
435  'jpe' => 'image/jpeg',
436  'jpeg' => 'image/jpeg',
437  'jpg' => 'image/jpeg',
438  'gif' => 'image/gif',
439  'bmp' => 'image/bmp',
440  'ico' => 'image/vnd.microsoft.icon',
441  'tiff' => 'image/tiff',
442  'tif' => 'image/tiff',
443  'svg' => 'image/svg+xml',
444  'svgz' => 'image/svg+xml',
445 
446  // archivos
447  'zip' => 'application/zip',
448  'rar' => 'application/x-rar-compressed',
449  'exe' => 'application/x-msdownload',
450  'msi' => 'application/x-msdownload',
451  'cab' => 'application/vnd.ms-cab-compressed',
452  'tgz' => 'application/tar+gzip',
453  'tar.gz' => 'application/tar+gzip',
454  'tar' => 'application/tar',
455  'gz' => 'application/gzip',
456  '7z' => 'application/x-7z-compressed',
457  's7z' => 'application/x-7z-compressed',
458 
459  // audio/video
460  'mp3' => 'audio/mpeg',
461  'qt' => 'video/quicktime',
462  'mov' => 'video/quicktime',
463  'mpeg' => 'video/mpeg',
464  'avi' => 'video/x-msvideo',
465  'swf' => 'application/x-shockwave-flash',
466  'flv' => 'video/x-flv',
467 
468  // adobe
469  'pdf' => 'application/pdf',
470  'psd' => 'image/vnd.adobe.photoshop',
471  'ai' => 'application/postscript',
472  'eps' => 'application/postscript',
473  'ps' => 'application/postscript',
474 
475  // MSOffice
476  'doc' => 'application/msword',
477  'dot' => 'application/msword',
478  'docx' => 'application/msword',
479  'rtf' => 'application/rtf',
480 
481  'xls' => 'application/vnd.ms-excel',
482  'xlsx' => 'application/vnd.ms-excel',
483  'xlm' => 'application/vnd.ms-excel',
484  'xla' => 'application/vnd.ms-excel',
485  'xlc' => 'application/vnd.ms-excel',
486  'xlt' => 'application/vnd.ms-excel',
487  'xlw' => 'application/vnd.ms-excel',
488 
489  'ppt' => 'application/vnd.ms-powerpoint',
490  'pptx' => 'application/vnd.ms-powerpoint',
491  'pps' => 'application/vnd.ms-powerpoint',
492  'pot' => 'application/vnd.ms-powerpoint',
493 
494  // libreOffice
495  'odc' => 'application/vnd.oasis.opendocument.chart',
496  'otc' => 'application/vnd.oasis.opendocument.chart-template',
497  'odf' => 'application/vnd.oasis.opendocument.formula',
498  'otf' => 'application/vnd.oasis.opendocument.formula-template',
499  'odg' => 'application/vnd.oasis.opendocument.graphics',
500  'otg' => 'application/vnd.oasis.opendocument.graphics-template',
501  'odi' => 'application/vnd.oasis.opendocument.image',
502  'oti' => 'application/vnd.oasis.opendocument.image-template',
503  'odp' => 'application/vnd.oasis.opendocument.presentation',
504  'otp' => 'application/vnd.oasis.opendocument.presentation-template',
505  'ods' => 'application/vnd.oasis.opendocument.spreadsheet',
506  'ots' => 'application/vnd.oasis.opendocument.spreadsheet-template',
507  'odt' => 'application/vnd.oasis.opendocument.text',
508  'otm' => 'application/vnd.oasis.opendocument.text-master',
509  'ott' => 'application/vnd.oasis.opendocument.text-template',
510  'oth' => 'application/vnd.oasis.opendocument.text-web',
511 
512  //VCards...
513  'vcf' => 'text/vcard',
514  'ics' => 'text/calendar',
515  );
516 
517  //Si la extensión se contempla en nuestro vector de tipos...
518  if (array_key_exists($fileExtension, $mime_types))
519  {
520  $tipoMime = $mime_types[$fileExtension];
521  }
522  else //En cualquier otro caso, lo servimos como binario...
523  {
524  $tipoMime = 'application/octet-stream';
525  }
526  return $tipoMime;
527  }//Fin getMimeType
528 
529 
537  public function urlGetContents ($url, $options = null)
538  {
539  $output = null;
540  if ($this->curlEnabled === true)
541  {
542  $ch = curl_init();
543  curl_setopt($ch, CURLOPT_URL, $url);
544  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
545  curl_setopt($ch, CURLOPT_FAILONERROR, TRUE); // To fail silently if the HTTP code returned is greater than or equal to 400.
546  curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE); // To follow any "Location: " header that the server sends as part of the HTTP header.
547  curl_setopt($ch, CURLOPT_AUTOREFERER, TRUE); // To automatically set the Referer: field in requests where it follows a Location: redirect.
548  curl_setopt($ch, CURLOPT_TIMEOUT, 10); // The maximum number of seconds to allow cURL functions to execute.
549  curl_setopt($ch, CURLOPT_MAXREDIRS, 5); // The maximum number of redirects
550  $output = curl_exec($ch);
551 
552  if($output === false)
553  {
554  $errorMsg = 'ERROR CURL: Sin acceso a '.$url.' : ' . curl_error($ch);
555  throw new \Exception(__CLASS__.'::'.__METHOD__.": $errorMsg");
556  }
557  curl_close($ch);
558  }
559  else
560  {
561  $output = file_get_contents($url, false, $options);
562  if ($output === false)
563  {
564  $errorMsg = 'ERROR file_get_content(). Sin acceso a '.$url.' : ' .print_r($errorMsg, true);
565  throw new \Exception(__CLASS__.'::'.__METHOD__.': '.$errorMsg);
566  }
567  }
568  return $output;
569  }//urlGetContents
570 
571 
572 
573 }//End AlfrescoClient
insertDocument($idApp, $rutaFicheroEnServer, $rutaDestinoAlf='/', $nombreDoc='', $descDoc='')
static getMimeType($fileName)
urlGetContents($url, $options=null)
__construct($user, $password, $loginURL, $uploadURL, $downloadURL)