instalar node js en ubuntu

sudo apt-get install nodejs

sudo apt-get install nodejs-legacy

Finalmente, podemos instalar el gestor de paquetes npm con el comando:
sudo apt-get install npm

google map api styling

se puede modificar el mapa que por default nos muestra google,

podemos definir un array con los estilos a aplicar, por ejemplo

var styles = [
          {
            featureType: 'road.highway',
            elementType: 'geometry.stroke',
            stylers: [
              { color: '#efe9e4' },
              { lightness: -40 }
            ]
          },{
            featureType: 'transit.station',
            stylers: [
              { weight: 9 },
              { hue: '#e85113' }
            ]
          }
        ];

y luego asignarselo al map

map = new google.maps.Map(document.getElementById('map'), {
  center: {lat: -34.619108, lng: -58.43131},
  zoom: 15,
  styles: styles,
 
  });

se pueden descargar distintos estilos para mapas desde esta pagina

google map api creando una marca mark

dentro de la function initMap, agregamos el sgt codigo

 <script>
      var map;
      function initMap() {
        map = new google.maps.Map(document.getElementById('map'), {
          center: {lat: -34.619108, lng: -58.43131},
          zoom: 15
        });


        var tienda_de_cafe={lat:-34.619214,lng:-58.434158};
        var marker =new google.maps.Marker(
        {
        position: tienda_de_cafe,
        map:map,
        title: 'La Tienda de Cafe!'
        });
      }
    </script>

cuando pasemos el mouse por arriba del Mark (globo rojo) se mostrara el texto "La Tienda de Cafe!"



podemos ademas agregar information sobre ese punto y que aparezca cuando clickeamos sobre el.

var infoWinfow=new google.maps.InfoWindow(
        {content:'Vení a conocernos, disfrutá de la experiencia que tenemos para brindarte. Y llevate a tu casa el mejor café del mundo. '});

        marker.addListener('click',function(){
        infoWinfow.open(map,this);
        });


Se puede hacer lo mismo para varios puntos a la vez

var locations=[{title:'punto 1',location:{lat:-34.622628,lng:-58.43234}},{title:'punto 2',location:{lat:-34.615105,lng:-58.428648} },{title:'punto 3',location:{lat:-34.615928,lng:-58.430953}}
  ];
        
        var infoWinfowCommon=new google.maps.InfoWindow();
           
  for (var i = locations.length - 1; i >= 0; i--) {
  var marker =new google.maps.Marker(
  {
  position: locations[i].location,
  map:map,
  title: locations[i].title
  });
           
            populateInfoWindow(marker,infoWinfowCommon);
  }

donde:

function populateInfoWindow(marker,infoWindow){
  if(infoWindow.marker!=marker){
      marker.addListener('click',function(){
            infoWindow.marker = marker;
          infoWindow.setContent(marker.title);
      infoWindow.open(map,marker);
      infoWindow.addListener('closeclick',function(){
                     this.marker=null;
      });
        });
  }
 
  }




google map api configuracion proyecto

1) ir a https://console.developers.google.com

2) click en el combo de proyectos en la esquina superior izquierda

3) click en + para crear uno nuevo

4) escribir el nombre de tu proyecto y click en el boton "create"

click en el boton  de "Enable Apis"


(verificar que el combo superior este en tu nuevo proyecto)
5) click en Maps Javascript Api , click en el boton "enable"

*******************

desplegar el menu de la izquierda, ir a APIS

y habilitar:

roads api

maps static api

street view api

places api

geocoding api

directions api

distance matrix api

geolocation api

maps elevation api

timezone api

ir al menu Credentials de cualquiera de las Apis
click en Create Credentials y generar una Credential del tipo Api Key...esta se usara para todas las apis habilitadas en el proyecto

darle un nombre que describa la intencion con la que sera usada, por ejemplo:

maps_api_udacity_course


nuestra primera aplicacion,
por simplicidad lo haremos en una sola pagina web.

en la seccion de head, agregaremos el sgt codigo

<style>
      /* Always set the map height explicitly to define the size of the div
       * element that contains the map. */
      #map {
        height: 100%;
      }
      /* Optional: Makes the sample page fill the window. */
      html, body {
        height: 100%;
        margin: 0;
        padding: 0;
      }
    </style>

<script>
      var map;
      function initMap() {
        map = new google.maps.Map(document.getElementById('map'), {
          center: {lat: -34.619108, lng: -58.43131},
          zoom: 15
        });
      }
    </script>



<body>

<div id="map"></div>
   <script src="https://maps.googleapis.com/maps/api/js?key=TU_API_KEY&callback=initMap"
    async defer></script>

</body>


el rsultado sera un mapa con un zoom de 15 teniendo como centro las coordenadas dadas.

tip:
para obtener las coordenadas de una determinada direccion usar la siguiente
pagina

https://google-developers.appspot.com/maps/documentation/utils/geocoder






laravel 5.6 Politicas de acceso Policies

vamos a hacer uso de las clases policy de laravel para programar accesos
hacia algunas funcionalidades del sitio

entonces la idea final es que un usuario pueda editar/actualizar sus propios datos
y tambien que un usuario con rol admin pueda hacerlo para cualquiera.

1) crear la clase UserPolicy

php artisan make:policy UserPolicy

este comando creara la clase app/policies/UserPolicy.php

2) registrar la relacion del modelo User con la clase UserPolicy

ir a app/Providers/AuthServiceProvider.php

protected $policies = [
        'App\User' => 'App\Policies\UserPolicy',
    ];

3) en UserPolicy.php crear la function before, que se llamara antes de cualquier otra declarada en la clase. Aqui se evaluara si el usuario logueado es admin y si es verdadero devuelve true, salteando la evaluacion de las otras funciones. De lo contrario, llama a la function correspondiente para que haga la evaluacion de si el usuario logueado es el mismo que se quiere editar/actualizar.



 public function before($user,$ability){
        if($user->hasRoles(['admin'])){
            return true;
        }
    }

    public function edit(User $authUser, User $user){
        return ($authUser->id == $user->id);
    }
    public function update(User $authUser, User $user){
        return ($authUser->id == $user->id);
    }
    public function destroy(User $authUser, User $user){
        return ($authUser->id == $user->id);
    }


4)en UserController exceptuar la validacion para los casos de edit y update

public function __construct(){
       //$this->middleware(['auth','checkRoles:admin,moderador']);
        $this->middleware('auth');
        $this->middleware('checkRoles:admin,moderador',['except'=>['edit','update']]);
    }

5)en UserController llamar desde las functiones de edit y update
a la function authorize para que dispare las validaciones del UserPolicy

public function edit($id)
    {
        $user = User::findOrFail($id);

        $this->authorize($user);

        return view('users.edit',compact('user'));
    }

    public function update(UpdateUserRequest $request, $id)
    {
        $user = User::findOrFail($id);

        $this->authorize($user);
       

        $user->update($request->all())  ;
        return redirect()->route('users.index');

    }



laravel 5.6 accion de editar validar user

vamos a crear una validacion para que al editar no se pueda poner un nombre en blanco ni usar un email que ya exista


php artisan make:request UserUpdateRequest

Vamos a app/Http/Requests/UserUpdateRequest.php

   public function authorize()
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'name' => 'required',
            'email' => 'required'
        ];
    }

y ahora se validara que ambos campos tengan algun valor.

mejoremos la validacion del campo email, le agregaremos que tenga un formato valido de email y que ademas no sea igual a otro email que ya exista en la tabla

    'email' => 'required | email | unique:users,email'

esta ultima validacion tiene el problema de que si no modificamos el email nos va a dar un error pues
va a detectar que el email ya existe...pues compara con el del mismo usuario ..cosa que debemos evitar enviando un tercer parametro con el ID del usuario que se esta actualizando para que no lo tome en cuenta al momento de la evaluacion.

el id lo vamos a obtener de la route

'email' => 'required | email | unique:users,email,'.$this->route('user')

donde user es el nombre del parametro de nuestra route para el update.


     

laravel 5.6 eloquent relaciones many to many

vamos a hacer que un usuario pueda tener varios roles
entonces creamos la tabla (por convencion en singular y en orden alfabetico)

php artisan make:migration create_user_role_table

en este caso no lo hicimos en orden alfabetico, pero no importa, se le debe indicar el nombre de la tabla al momento de definir la relacion

entonces en User.php

    public function roles(){
        return $this->belongsToMany(Role::class,'user_role');
    }

    public function hasRoles(array $roles)
    {
        foreach ($roles as $role) {
            foreach ($this->roles as $userRole) {
              if($userRole->name == $role){
                return true;
              }
            }
        }
        return false;
    }


en la vista views/user/index.blade,php
..
<td>
@foreach($user->roles as $role)
{{$role->display_name}}
@endforeach
</td>
..

linux ubuntu mint actualizar chrome

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