Archivos de Categoría: Programación - Paginas 3

Laravel funcionando desde la raíz del proyecto

Tengo que subir un proyecto a un servidor «raro» que no me
permite tocar nada de la configuración, por lo que no puedo especificar que tire
de la carpeta public. Es algo más inseguro pero la única opción que he visto es
hacer que tire de la raíz del proyecto.  Para ello he seguido los siguientes pasos:

Renombrar /server.php como index.php y cambiar el código

require_once __DIR__ . '/public/index.php';

por

require_once __DIR__ . '/public/server.php';

Crear un fichero .htaccess en el raíz con el código:


<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -Indexes
</IfModule>
<FilesMatch "\.(json|xml|lock|env|example|gitattributes|gitignore)$">
Order allow,deny
Deny from all
</FilesMatch>
<Files artisan>
Order allow,deny
Deny from all
</Files>
RewriteEngine On
# Redirect Trailing Slashes If Not A Folder...
RewriteRule ^(.*)/$ /$1 [L,R=301]
# Handle Front Controller...
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
# Handle Authorization Header
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
</IfModule>

Borrar el fichero  /public/.htaccess
Renombrar el fichero /public/index.php por /public/server.php

Logicamente hay que evitar subir los fichero composer, webpack, etc y cuando queramos hacer referencia a un asset la nueva ruta será con public, por ejemplo «{{ asset(‘public/js/app.js’) }}»

Función como clase vs función factoría en Javascript

Normalmente suelo crear funciones que utilizo como clases en Javascript, por ejemplo una «clase» contador:

function Contador(init){
    this.num = (init!== undefined)?init:1;
    this.incrementa = function(){ this.num++; }
}

// y la usaríamos de la siguiente forma
var obj = new Contador(5);
obj.incrementa();
console.log(obj.num);

Como se ve, se puede acceder directamente a las propiedades del objeto y no siempre querremos esto. Para eso podemos usar una función factoría que básicamente funciona igual pero nos impide acceder a las propiedades (para acceder a estas tendremos que usar algún método).

function contador(init){
    var _num = (init!== undefined)?init:1;
    return {
        incrementa:function(){ _num++; },
        valor:function(){ return _num; }
    }
}

// y la usaríamos de la siguiente forma
var obj = contador(10);
obj.incrementa();
console.log(obj.valor());

Generando PDFs con Laravel 5

Últimamente me está tocando mucho informe en PDF por lo que especifico aquí los casos más habituales. Lo primero lógicamente es instalar las dependencias con composer:

composer require barryvdh/laravel-dompdf

Y en el fichero config/app.php añadir el provider y su alias:

'providers' => [
    ....
    Barryvdh\DomPDF\ServiceProvider::class,


....

'aliases' => [
    ....
    'PDF' => Barryvdh\DomPDF\Facade::class,

Con esto ya podríamos usarlo en cualquier controlador siempre haciendo referencia a su namespace con:

Use PDF;

La gran ventaja que le veo es que podemos usar las plantillas blade para generar los PDFs con toda la potencia que esto nos da. Por ejemplo si queremos generar un PDF al vuelo directamente en el navegador, podremos hacerlo de la siguiente forma:

$pdf = PDF::loadView('pdfs.plantilla', ['datos'=>$datos]);
return $pdf->stream('fichero.pdf');

Otra opción es que lo descargue en vez de mostrarlo:

$view = view('pdfs.plantilla')->with('datos', $datos)->render();
$pdf = PDF::loadHTML($view);
return $pdf->download('fichero.pdf');

Y por último, podemos generarlo físicamente en el servidor:

$view = view('pdfs.plantilla')->with('datos', $datos)->render();
$pdf = PDF::loadHTML($view);
$pdf->save(storage_path('app/fichero.pdf'));

Eso sí, en la plantilla debe tener ciertas características si queremos meter cabecera y pie de página. Para ello tendremos que usar las etiquetas header y footer:

<html>
<head>
  <style>
    @page { margin-top: 400px; margin-bottom: 100px; margin-left: 50px; margin-right: 50px; }
	  body{color: #767676;background: #fff;font-family: 'Open Sans',sans-serif;font-size: 12px;}
    #header { position: fixed; left: 0px; top: -375px; right: 0px; height: 375px; }
    #footer { position: fixed; left: 0px; bottom: -100px; right: 0px; height: 80px; text-align:center; font-size: 11px;}
    #footer .page:after { content: counter(page, upper-roman); }
	  #content{ }	
  </style>
</head>
<body>
  <header id="header">
    <img src="{{public_path('images/logo.png')}}" width="200"/>
  </header>
  <footer id="footer">
    Este es el pie
  </footer>
  <section id="content">
    Este es el contenido
  </section>
</body>
</html>

Por último, si el PDF tiene varias páginas puede que tengamos que meter la numeración de estas. Para ello tendremos que poner el siguiente código en la plantilla:

<script type="text/php">
    $text = 'Página {PAGE_NUM} de {PAGE_COUNT}';
    $font = Font_Metrics::get_font("sans-serif");
    $pdf->page_text(493, 800, $text, $font, 7);
</script>

Y para que no de error este último código, deberemos habilitar en la configuración de la librería que las plantillas puedan ejecutar php. En teoría lo podemos hacer con:

$pdf->set_options('isPhpEnabled', true);

O

$pdf->setOptions(['isPhpEnabled' => true]);

Pero no he conseguido hacerlo funcionar así que mientras encuentro otra solución he modificado el fichero vendor\barryvdh\laravel-dompdf\config\dompdf.php:

// habilitar PHP en las plantillas
  "DOMPDF_ENABLE_PHP" => true,  
// Que coja los acentos al llamar a la función page_text
  "DOMPDF_ENABLE_HTML5PARSER" => true,