instalar php-pdo-mysql en linux

 sudo apt-get install -y php7.2-pdo-mysql

(seleccione la version de php correspondiente a la de su sistema)

y reinicie el servidor de apache:


service apache2 restart



php 7 psr-4

 en nuestro proyecto creamos una carpeta llamada donde estaran todas nuestras clases, por ejemplo una llamada:

MiApp

adentro de esta irian bajo carpetas las de nuestra aplicacion, crearemos una por ejemplo, una llamada:

Helpers

dentro vamos a crear la clase Prueba.php:

<?php
namespace MiApp\Helpers;

class Prueba{
function __construct(){
echo 'prueba';
}
}

en la raiz del proyecto ahora vamos a crear el archivo composer.json :

{
"name":"mipaquete/isra-app",
"autoload": {
"psr-4": {
"MiApp\\":"MiApp/"
}
},
"description": "blablabla"
}

donde le decimos que

"MiApp\\":"MiApp/"

todo los archivos que estàn en la carpeta MiApp/ 

deben tener el namespace empezando en MiApp\

luego, ejecutamos:

sudo composer dump-autoload

(lo ejecuto como sudo porque va a necesitar permisos para creacion de carpetas)

este comando va a crear la carpeta "vendor" y unos cuantos archivos dentro de èl donde el importante es uno llamado autolad.php


y listo!

por ejemplo si tenemos un archivo index.php en la raiz del proyecto 

podemos instanciar a la clase prueba asi:


<?php
require_once "vendor/autoload.php";

use MiApp\Helpers\Prueba;

new Prueba();

lalalala

nota:
si tuviesemos otra clase en la carpeta MiApp/Helpers y la quisieramos usar;
podriamos agregar una nueva linea de "use..." o referenciarla asi:

use MiApp\Helper\{Test,OtroTest};

PHP 7 nuevo operador de fusion de NULO ??

 el nuevo operador evalua si el valor es null y devuelve algun valor por default que

le querramos dar.


Por ejemplo, si tenemos este codigo

function getValue(int $idx) {
$a = ['uno','dos','tres'];
return $a[$idx];
}

y llamamos al metodo con getValue(100) nos dara el sgt error:

PHP Notice:  Undefined offset

si agregamos la sgt modificacion, y lo volvemos a llamar:

function getValue(int $idx) {
$a = ['uno','dos','tres'];
return $a[$idx]??'indice no existe';
}


nos mostrará 'indice no existe'



ass


linux Eliminar procesos Postman cuando se cuelga

 buscamos los ids de los procesos relacionados:

pidof _Postman

supongamos que nos salen varios IDs, los eliimnamos todos:

sudo kill -9 29539 29538 29499

linux actualizar version php 7.2 y setearla como default

 suponiendo que tenemos alguna otra version de php ya instalada.

ejecutamos el sgt comando:

sudo apt install php7.2

activamos el modulo de php instalado:

sudo a2enmod php7.2

lo seteamos como default:

sudo update-alternatives --set php /usr/bin/php7.2

ahora, si ejecutamos: php -v nos deberia aparecer algo similar a:


PHP 7.2.34-8+ubuntu18.04.1+deb.sury.org+1 (cli) (built: Oct 31 2020 16:57:15) ( NTS )

Copyright (c) 1997-2018 The PHP Group

Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies

    with Zend OPcache v7.2.34-8+ubuntu18.04.1+deb.sury.org+1, Copyright (c) 1999-2018, by Zend Technologies

    with Xdebug v3.0.1, Copyright (c) 2002-2020, by Derick Rethans


finalmente reinicie su servidor apache:

sudo systemctl restart apache2



Slim 3 y Monolog - parte 1

 dentro de la carpeta de nuestro proyecto,

agregar la dependencia de slim

sudo composer require slim/slim:3.*

agregar la dependencia de monolog

sudo composer require monolog/monolog

----------------------------------------------------

nota: podemos levantar el servidor integrado de php, así:

php -S localhost:8000 -t public/

(siempre que los archivos esten en la carpeta public)

------------------------------------------

en el archivo public/index.php


<?php
use \Psr\Http\Message\ServerRequestInterface as Request;
use \Psr\Http\Message\ResponseInterface as Response;
use Utils\NumberConversionUtils;
use Utils\TestUtils;

require '../vendor/autoload.php';

$configuration = [
'settings' => [
'displayErrorDetails' => true,
],
];
$container = new \Slim\Container($configuration);
$app = new \Slim\App($container);


$container['Logger'] = function($c) {

$logger = new Monolog\Logger('my_logger');
$filename = _DIR__ . '/../log/error.log';
$file_handler = new Monolog\Handler\StreamHandler($filename);
$logger->pushHandler($file_handler);
return $logger;
};


$app->get('/hello/{name}', function (Request $request, Response $response, array $args) {
$name = $args['name'];
$response->getBody()->write("Hello, $name");
$this->get('Logger')->addInfo('Something interesting happened');

return $response;
});

$app->run();



SOLID

 defectos que causan daño al sw:

-poner mas codigo/funcionalidad no relacionada en una unica clase

-hacer depender una clase de otra (estrechamente acopladas) el cambio en una afectará a la otra

-meter codigo duplicado

soluciones:

-elegir arquitectura correcta (mvc,etc)

-seguir principios de diseño ...solid

-elegir patrones de diseño

--------------------------------------------

SOLID

-acrónimo: cada letra representa un principio. 

-si se sigue hará de nuestro sw uno escalable en el tiempo.

-tiene una relación con los conceptos de:

alta cohesión y bajo acoplamiento

alta cohesión: la información que almacena una clase debe ser coherente y estar relacionada con la clase.

bajo acoplamiento: tener las clases lo menos ligadas entre si. de tal modo que si se modifica una de ellas, no afecte o afecte poco al resto de clases.


SOLID, principios:

S: responsabilidad única

0: abierto o cerrado

L: sustitución de Liskov

I: segregación de interfaces

D: inversión de dependencia


un buen diseño nos ayuda a hacer más sencillo el mantenimiento del sw, para que cada vez que nos pidan una nueva funcionalidad no tener que estar tocando media aplicación de código antiguo.

reducimos así el costo de mantenimiento de sw.


Principio de Responsabilidad Unica:

-cada modulo de sw debe tener una sola razón para cambiar (no como una navaja suiza)

ejemplo

class Usuario{

public function pagarMisDeudas(){

  if(tieneDineroEnELBanco(id_usuario){

...

}


}

public function tieneDineroEnELBanco(id_usuario){

...

}

}

-----------------------

la responsabilidad de la funcion tieneDineroEnELBanco(id_usuario)

 no le pertenece directamenreal Usuario...

pues esa misma logica la vamos a querer usar en otra parte de la aplicacion y terminemos copiando y pegando ese codigo, haciendo luego inmantenible.

entonces, una solución sencilla sería:

class Usuario{

Banco $banco;

public Usuario(Banco banco){

     $this->banco = banco;

}

public function pagarMisDeudas(){

  if($this->banco->tieneDineroEnELBanco(id_usuario){

...

}


}

Principio Abierto Cerrado

un modulo o clase de sw está abierto para extensión cerrado para modificación.


entonces si por ejemplo tenemos

class AreaService{

  public sumarAreas(Rectangulo[] rectangulos){
    //recorremos el arreglo de rectangulos ,
    /por cada rectangulo, segun su base y altura y calculamos el area y lo acumulamos en una variable
   //devolvemos el valor de la variable de acumulacion
  }
}

si ahora tambien ademas de rectangulos tenemos circulos, 
una solución podria ser
hacer una clase Figura de la cual extender Rectangulo y Circulo
entonces
modificamos el metodo
  public sumarAreas(Figura[] figura){
    //recorremos el arreglo de figuras ,
    /por cada figura, segun la instancia de què objeto sea calculamos su area y lo acumulamos en una variable
   //devolvemos el valor de la variable de acumulacion
  }
pero que pasa si se agregan mas tipos de Figura?

entonces tendriamos que modificar el metodo de sumarAreas para poder calcular el area
segun cada uno de los nuevos tipos de figuras.

se viola lo de "cerrado para modificación" del método..
entonces lo que se puede hacer es que el método que calcula el área debe estar implementado en cada una de las clases y ser llamadas  dentro del mètodo de sumarAreas

PRINCIPIO DE LISKOV

asegurarse de que la clase derivada no modifique el comportamiento de la clase padre.


class FileManager{
   writeFiles(File[] file){
      file->write();
   }
}

donde File tiene 2 metodos: read y write

si luego, nos indican que hay Files que no pueden escribirse.

se podria crear FileReadeable para que extiendan de File y reescriba el metodo write
donde el metodo write de FileReadeable lance una exception.

esto viola el principio, ya que el hijo ya no hace lo del padre.


entonces lo que vamos a hacer es crear 2 interfaces

IFileReadeable con el unico metodo read
IFileWritable con el unico metodo write


donde File implementaria ambas interfaces

entonces, FileManager quedaria asi:

class FileManager{
   writeFiles(IFileWriteable[] file){
      file->write();
   }
}


principio de Segregación de Interfaces

es preferible muchas interfaces con pocos metodos
que pocas con muchos.
asi no obligamos a un cliente a implementar metodos que no usa.

por ejemplo
tenemos que una emplresa hay un TeamLead que puede crear una tarea, asignar una tarea y trabajarenunatarea.
entonces podemos crear la interface ILead
con los metodos 
createTask()
assignTask()
WorkOnTask()

y luego creamos la clase TeamLead que implementa ILead

luego nos dicen que hay un Manager con similares capacidades que el TeamLead pero que no puede trabajar en ninguna tarea,
entonces podemos crear una clase Manager que implemente ILead
y en el metodo workOnTask() que lance una excepcion indicando un error.

esta soluciòn viola el principio, pues se està obligando a Manager a implementar un método que no usa.
ahora imaginemos que tambien tenemos un programador que solo puede trabajar en una tarea,

lo que tendriamos que hacer es crear 3 interfaces

IProgrammer con el metodo workOnTask()
IManager con el metodo createTask() y assignTask()

entonces :
La clase TeamLead implementa IProgrammer y IManager
La clase Programmer implementa IProgrammer
La clase Manager implementa IManager

Principio de inversión de dependencias


Los modulos/clases de alto nivel no deberian depender de las de bajo nivel.

supongamos que tenemos
class Logger{
   logMessage(string message){
  }
}
class DBLogger{
  logMessage(string message){
 }
}

y tenemos una 
class ExceptionLoggerManager{
logearEnFile(Exception e){
  log =new FileLoger()
  log->logMessage(e->getMessage())
}
logearEnDB(Exception e){
}
  log = new DBLoger();
  log->logMessage(e->getMessage())

}

class exportarData(){
 try{
}catch(IOException e){
new ExceptionLogerManager->logearEnDb(e);
}catch(Exception e){
new ExceptionLogerManager->logearEnFile(e)
}

}

el problema aca es que cada vez que nos pidan logear en otro lado, la clase ExceptionLogerManager
va a tener que modificarse. Eso pasa porque depende mucho de clase de bajo nivel.

la solucion:
creamos una interface ILoger metodo log(string)
y cada log distinto que la implemente
entonces

la nueva interfaz se pasa como parametro en el constructor de la clase ExcpetionLogerManager

class ExceptionLogerManager{

ILoger _iloger;

ExceptionLogerManager(Iloger iloger)
{
_iloger = iloger;
}

}
 entonces ahora la clase de exportar quedaria asi:

class exportarData(){
 try{
}catch(IOException e){
new ExceptionLogerManager(new DBLOger())->log(e);
}catch(Exception e){
new ExceptionLogerManager(new FIleLOger())->loge(e)
}

}





 

composer de una version especifica

 el comando require instalarà la version que se adapte a tu proyecto

composer require monolog/monolog


pero tambien se le puede indicar una versión especifica:

composer require monolog/monolog:~1.17.0


# Signature:

composer require <vendor>/<name>:<version>

donde, version se puede expresar de distintas manera:

 ^ (caret)  ^1.2.3 es equivalente a >=1.2.3 <2.0.0)

 ~ (tilde)  ~1.2 es equivalente a >=1.2 <2.0.0 

              o  ~1.2.3 es equivalente a >=1.2.3 <1.3.0)

* (wildcard) 1.0.* es equivalente a >=1.0 <1.1.


listar servicios en linux

 ejecutar el comando:

sudo systemctl list-unit-files --type service --all


para listar sólo los servicios habilitados (enabled), osea los que se estan ejecutando actualmente:

sudo systemctl | grep running




composer install y composer update

composer install

Las dependencias de nuestra aplicación con Composer se configuran en el fichero composer.json

La primera vez que ejecutamos composer install en un proyecto, Composer lee ese fichero, 

resuelve las dependencias que hay en él e instala los paquetes en el directorio vendor

segun la version configurada para cada paquete y la configuración de estabilidad especificadas 

en el fichero composer.json.

Luego, Composer crea en el directorio donde se ha ejecutado el comando install el fichero 

composer.lock en el cual anota todos los paquetes instalados y la versión instalada de cada uno de ellos. 

Comando update

El comando composer update lee siempre el fichero composer.json e instala las dependencias de ese fichero. 

Después de instalar los paquetes, crea en el directorio donde se ha ejecutado este comando 

el fichero composer.lock o lo actualiza si ya existe.


NOTA:


Cuando añades un nuevo paquete a tu aplicación, si usas el comando composer require 

(por ejemplo, composer require doctrine/dbal:~2.3), 

Composer añadirá ese paquete al fichero composer.json y lo instalará. 

Por lo que seguirás manteniendo para el resto de paquetes las mismas versiones que tenían instaladas.

como encontrar archivos que contengan un cierto texto en linux

 desde la carpeta donde vas a buscar los archivos ejecutar el sgt comando


grep -iRl "your-text-to-find" ./


donde 

-i - ignore text case

-R - recursively search files in subdirectories.

-l - show file names instead of file contents portions.

abrir un archivo pdf desde la terminal de linux

 use la siguiente sentencia:


evince my_file.pdf


para hacer que luego de abrir el archivo el cursor vuelva al prompt


evince my_file.pdf &

como hacer para que una pagina refresque la version del archivo js que esta usando

 si modificamos un archivo js/index.js que lo usa una pagina html

asi:

<script src="js/index.js"></script>

cuando subamos el cambio la pagina seguirà usando la version del cachè

para obligar a que se vuelva a "bajar" la nueva version debemos hacer algo asi


<script src="js/index.js?v=1"></script>

y si lo volvemos a modificar cambiar esa linea por

<script src="js/index.js?v=2"></script>

y asi sucesivamente por cada actualizacion del archivo js.

Para automatizar esa url con las distintas versiones, la reemplazamos por este codigo:


<script type="text/javascript" language="javascript">  

    var versionUpdate = (new Date()).getTime();  

    var script = document.createElement("script");  

    script.type = "text/javascript";  

    script.src = "js/index.js?v=" + versionUpdate;  

    document.body.appendChild(script);  

</script>  


como instalar certificado ssl de cloudflare en godaddy

 requisito: tener una cuenta en cloudfare

  1. ingresar a tu cuenta de cloudfare
  2. click en "agregar sitio"
  3. escribir el nombre de tu sitio por ejemplo : misitio.com
  4. elegir "plan free"
  5. click en continuar
  6. apareceran 2 nombres de servidores que seran usados en tu cuenta de godaddy.
  7. entrar a tu cuenta de godaddy
  8. en tu cuenta, click en "dns" de tu sitio
  9. en el bloque de "nombre de servidores" hacer click en el boton de "cambiar"
  10. click en "ingresar mis propios nombres de servidores"
  11. copiar en cada casillero (aparecen 2 por default) cada uno de los nombres de servidores de cloudfare
  12. click en "guardar"

esperar unos segundos ..y Listo.

al ingresar a tu sitio te redirigirà a https (esto hay que configurarlo en cloudfare)


vincular una instancia ec2 con un dominio godaddy.com

  1. ubicar la ip publica de la instancia ec2 por ejemplo una asi 35.222.11.130
  2. loguearse en godaddy
  3. entrar en tu cuenta
  4. click en el boton DNS del dominio a vincular
  5. de la lista de registros eliminar el que sea de tipo A.
  6. crear un nuevo registro de tipo A

donde host= @

y apunta a=335.222.11.130


y listo.

phpunit anotaciones

si al querer ejecutar phpunit nos da el sgt error:

class DomDocument not found

entonces
falta agregar la extension del dom a la version de php instalada
esto se hace asi:

sudo apt-get install php7.1-xml
-----------------------------------------------------------------------

si al ejecutar phpunit nos da el sgt mensaje:

The Xdebug extension is not loaded No code coverage will be generate


quiere decir que no tenemos instalado el modulo de xdebug, esto lo podemos comprobar ejecutando el sgt comando
php -i | grep xdebug

y viendo que no nos devuelve nada.
entonces:

sudo apt-get install php-xdebug

podemos listar los modulos instalados

php -m

y ahi veremos listado el de xdebug

ejecutar phpunit

desde la carpeta Test en la terminal:

../vendor/bin/phpunit AnimalTest


donde 

<?php

require_once('Animal.php');

use PHPUnit\Framework\TestCase;

class AnimalTest extends PHPUnit_Framework_TestCase {
protected function setUp(){
$this->animal = new Animal('','','',11);
}
public function testSonido(){
$this->assertEquals('Guaau',$this->animal->sonido());
}

}


cambiar entre versiones de php en linux


por ejemplo si queremos poner como default la version de php 7.1
(previamente instalada)

sudo update-alternatives --set php /usr/bin/php7.1
para comprobarlo podemos ver que archivo de configuracion ini lee nuestra terminal asi:
php --ini |grep Loaded


instalar phpunit en un proyecto



crear en la raiz el archivo composer.json y agregar las sgts lineas:

{
    "require-dev": {
        "phpunit/phpunit": "3.7.*"
    }
}

luego, ejecutar 

composer install o update

pero con los sgts parametros

composer install --ignore-platform-reqs

me dio problemas con la version de php 7.4
por lo que switchee a la vversion de php 7.1

si por ejemplo tenemos nuestras clases de tests en una carpeta Test

nos ubicamos ahi y ejecutamos

../vendor/bin/phpunit AnimalTest



donde:

require_once('Animal.php');

use PHPUnit\Framework\TestCase;

class AnimalTest extends PHPUnit_Framework_TestCase {
protected function setUp(){
$this->animal = new Animal('','','',11);
}
public function testSonido(){
$this->assertEquals('Guaau',$this->animal->sonido());
}

}

instalar composer en ubuntu


para almacenar una variable shell
simplemente es escribir en la consola

variable=valor

HASH=(COPIAR EL VALOR DEL HASH que aparece en https://composer.github.io/pubkeys.html

https://www.digitalocean.com/community/tutorials/como-instalar-y-utilizar-composer-en-ubuntu-18-04-es

mint instalar rpm packages

Linux Mint Support only deb package installation, If you have some software in rpm package you can install it in Linux Mint easily.
To install open Terminal (Press Ctrl+Alt+T) and copy the following command in the Terminal:
  • sudo apt-get install alien dpkg-dev debhelper build-essential
Now convert package from RPM format to DEB format, use the following command. Change your packagename in command:
  • sudo alien packagename.rpm
To install the deb package enter following command:
  • sudo dpkg -i packagename.deb

GIT Add an other remote

Add an other remote — recommended

git remote add <remote-name> <url>
So, for example:
$ git remote add different-repo https://github.com/your-username/your-repo
And then, just
$ git push different-repo master

spring boot validaciones


en la llamada agregar @valid

@PostMapping("/users")
public User addUser(@Valid @RequestBody User user) {
userService.save(user);
return user;
}

y en la clase user:

@NotBlank(message = "Please provide an email")
@Column(name="email")
private String email;

notBlank valida que el campo no sea nulo y que contenga al menos un caracter no blanco

la salida por default si se detectase el error seria asi

{
    "timestamp""2020-03-29T22:13:23.653+0000",
    "status"400,
    "error""Bad Request",
    "errors": [
        {
            "codes": [
                "NotBlank.user.email",
                "NotBlank.email",
                "NotBlank.java.lang.String",
                "NotBlank"
            ],
            "arguments": [
                {
                    "codes": [
                        "user.email",
                        "email"
                    ],
                    "arguments"null,
                    "defaultMessage""email",
                    "code""email"
                }
            ],
            "defaultMessage""Please provide an email",
            "objectName""user",
            "field""email",
            "rejectedValue"null,
            "bindingFailure"false,
            "code""NotBlank"
        }
    ],
    "message""Validation failed for object='user'. Error count: 1",

para hacer mas amigable esta salida
creamos la sigt clase:

package com.isra.Example3.error; import java.util.Date; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.context.request.WebRequest; import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler; @ControllerAdvice public class CustomGlobalExceptionHandler extends ResponseEntityExceptionHandler { @Override protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException ex, HttpHeaders headers, HttpStatus status, WebRequest request) { Map<String, Object> body = new LinkedHashMap<>(); body.put("timestamp", new Date()); body.put("status", status.value()); //Get all errors List<String> errors = ex.getBindingResult() .getFieldErrors() .stream() .map(x -> x.getDefaultMessage()) .collect(Collectors.toList()); body.put("errors", errors); return new ResponseEntity<>(body, headers, status); } }


y la salida sera

{
    "timestamp""2020-03-29T22:29:58.799+0000",
    "status"400,
    "errors": [
        "Please provide an email"
    ]
}


tambien podemos validar los parametros de entrada por ejemplo en un get

@Validated public class UserRestController {
...
public ResponseEntity<User> getUser(@Min(1) @PathVariable int id) {
../


y la salida seria

{
    "timestamp""2020-03-29T23:10:02.890+0000",
    "status"500,
    "error""Internal Server Error",
    "message""getUser.id: tiene que ser mayor o igual que 1",
    "trace""javax..........
}

ss
el codigo de error 500 (internal server) no es correcto vamos a override el metodo constraintViolationException de nuestra clase CustomGlobalExceptionHandler



como reload en tiempo de ejecucion sin reiniciar el server spring boot eclipse

agregar en el pom de  proyecto

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>

tener activada la opcion
Project -> build automatically

instalar spring boot en eclipse

https://www.edureka.co/blog/spring-boot-setup-helloworld-microservices-example/

al crear el proyecto en dependencias seleccionar Spring Web
para que se puedan importar las librerias necesarias para reconocer las annotations
de RestController o RequestMapping

error al instalar docker en linux mint

docker se instalo ok
pero si queremos ejecutar por ejemplo
docker ps
nos sale
Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get http://%2Fvar%2Frun%2Fdocker.sock/v1.29/containers/json: dial unix /var/run/docker.sock: connect: permission denied

lo que nos obligaria a ejecutar todo anteponiendole "sudo"

desde donde estes 
hay que ejecutar (reiniciar la pc)
sudo groupadd docker
sudo usermod -aG docker $USER
newgrp docker 

laravel 7 bootstrap


The Bootstrap and Vue scaffolding provided by Laravel is located in the laravel/ui Composer package, which may be installed using Composer:
composer require laravel/ui

Once the laravel/ui package has been installed, you may install the frontend scaffolding using the ui Artisan command:
// Generate basic scaffolding...
php artisan ui bootstrap
After installing the laravel/ui Composer package and generating the frontend scaffolding, Laravel's package.json file will include the bootstrap package to help you get started prototyping your application's frontend using Bootstrap.


Before compiling your CSS, install your project's frontend dependencies using the Node package manager (NPM):
npm install
Once the dependencies have been installed using npm install, you can compile your SASS files to plain CSS using Laravel Mix. The npm run dev command will process the instructions in your webpack.mix.js file. Typically, your compiled CSS will be placed in the public/css directory:
npm run dev

entonces,
ya se puede usar la hoja de stylo desde nuestro archivo de vista base:

en resources/views/base.blade.php

<!DOCTYPE html>
<html lang="en">
<head>
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Laravel 7 & MySQL CRUD Tutorial</title>
  <link href="{{ asset('css/app.css') }}" rel="stylesheet" type="text/css" />
</head>
<body>
  <div class="container">
    @yield('main')
  </div>
  <script src="{{ asset('js/app.js') }}" type="text/js"></script>
</body>
</html>
sadsad

entonces  nuestras paginas que extiende de este archivo por ejemplo las de
resources/views/posts

@extends('base') 
@section('main')
<div class="row">
...
<div/>
@endsection

linux ubuntu mint actualizar chrome

 desde una terminal: $ sudo apt update $ sudo apt install google-chrome-stable