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