I'm still in the process of learning Laravel 5, and am following Laracasts. I've been following the lesson http://ift.tt/1mvRMh6, which I've found very helpful, however I've discovered some slight changes required to the codebase to accommodate the changes to Laravel since the video lesson was recorded. I wonder if my problem is due to some necessary feature or instruction or convention which has superseded the lesson.
When I click the "Profile" link, the page clearly refreshes, but I don't navigate to the Show Profile page.
This is my app/Http/routes.php
<?php
/*
|--------------------------------------------------------------------------
| Application Routes
|--------------------------------------------------------------------------
|
| Here is where you can register all of the routes for an application.
| It's a breeze. Simply tell Laravel the URIs it should respond to
| and give it the controller to call when that URI is requested.
|
*/
/**
* All requests get passed as standard through 'web' middleware classes as definded in app/Http/Kernel.php
*/
/**
* http://fidna.dev/public
*/
Route::get('/', function () {
return view('welcome');
});
/**
* http://ift.tt/290UyeD
*/
Route::get('/about', function () {
$people = ['Taylor', 'Matt', 'Jeffrey'];
return view('pages.about', array('people' => $people));
});
Route::get('/home' ,'IndexController@index');
Route::get('/cards', 'CardsController@index');
Route::get('/cards/{card}', 'CardsController@show');
Route::post('cards/{card}/notes', 'NotesController@store');
Route::get('/notes/{note}/edit', 'NotesController@edit');
/**
* patch() is a synonym for save
* The request type implies update
*/
Route::patch('notes/{note}', 'NotesController@update');
Route::auth();
Route::get('/home', 'HomeController@index');
/**
* Profile
* Watch out, because /{profile} could act as a catch-all
* Therefore, leave this route at the bottom, allowing all the other routes to be processed first
*/
Route::resource('profile', 'ProfilesController', ['only' => ['show', 'edit', 'update']]);
Route::get('/{profile}', ['as' => 'profile', 'uses' => 'ProfilesController@show']);
/**
* This is now implied by the routes command two lines above
*
Route::get('/{profile}/edit', ['as' => 'profile.edit', 'uses' => 'ProfilesController@edit']);
*
*/
My app/Custom/helpers.php (which is registered as autoloadable in composer.json) is as follows:
<?php
function link_to_profile($p_text = 'Profile')
{
/**
* The advantage with this first way is we are no longer hardcoding how we link to a profile
* You'd only have to update the named route and update that if the path to it changed
*/
return link_to_route('profile', $p_text, Auth::user()->name);
return link_to('/' . Auth::user()->name, $p_text);
}
In order to navigate to the Show Profile page, I include link_to_profile() in the view.
The app/Http/Controllers/ProfilesController.php is as follows:
<?php
namespace App\Http\Controllers;
use App\User;
use Illuminate\Http\Request;
use \App\Http\Requests\ProfileForm;
use Input;
class ProfilesController extends Controller
{
/**
* Profile form requests validator class
*
* @var Http\Requests\ProfileForm
*/
protected $_profileForm = null;
public function __construct(ProfileForm $profileForm)
{
$this->_profileForm = $profileForm;
}
/**
* Action to display the specified resource
*
* @param string $username
*
* @return Response
*/
public function show($username)
{
try {
$user = User::with('profile.country')->whereName($username)->firstOrFail();
//dd($user->toArray());
} catch (\Illuminate\Database\Eloquent\ModelNotFoundException $e) {
return redirect('home');
}
return view('profiles.show')->withUser($user);
}
/**
* Show the form for editing the specified resource
*
* @param integer $id
*
* @return Response
*/
public function edit($username)
{
$user = User::with('profile.country')->whereName($username)->firstOrFail();
return view('profiles.edit')->withUser($user);
}
/**
* Edit the profile
*
* @param string $username
*
* @return Response
*/
public function update($username)
{
$user = User::with('profile.country')->whereName($username)->firstOrFail();
/**
* Restricting input data to the values posted from the form
*/
$input = Input::only('address1', 'address2', 'city', 'postcode');
$this->_profileForm->validate($input);
$user->profile->fill($input)->save();
return view('profiles.show')->withUser($user);
}
}
The app/Profile.php (model) is:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Profile extends Model
{
/**
* The only field that can be mass-assigned is the body
* to avoid a Illuminate\Database\Eloquent\MassAssignmentException
*
* @var array
*/
protected $fillable = ['address1', 'address2', 'city', 'postcode'];
public function user()
{
return $this->belongsTo(User::class);
}
/**
* Relating country to profile
*
* @return type
*/
public function country()
{
return $this->belongsTo('App\Country' ,'country_id', 'id');
}
}
The config/app.php is:
<?php
return [
/*
|--------------------------------------------------------------------------
| Application Environment
|--------------------------------------------------------------------------
|
| This value determines the "environment" your application is currently
| running in. This may determine how you prefer to configure various
| services your application utilizes. Set this in your ".env" file.
|
*/
'env' => env('APP_ENV', 'production'),
/*
|--------------------------------------------------------------------------
| Application Debug Mode
|--------------------------------------------------------------------------
|
| When your application is in debug mode, detailed error messages with
| stack traces will be shown on every error that occurs within your
| application. If disabled, a simple generic error page is shown.
|
*/
'debug' => env('APP_DEBUG', false),
/*
|--------------------------------------------------------------------------
| Application URL
|--------------------------------------------------------------------------
|
| This URL is used by the console to properly generate URLs when using
| the Artisan command line tool. You should set this to the root of
| your application so that it is used when running Artisan tasks.
|
*/
'url' => env('APP_URL', 'http://localhost'),
/*
|--------------------------------------------------------------------------
| Application Timezone
|--------------------------------------------------------------------------
|
| Here you may specify the default timezone for your application, which
| will be used by the PHP date and date-time functions. We have gone
| ahead and set this to a sensible default for you out of the box.
|
*/
'timezone' => 'UTC',
/*
|--------------------------------------------------------------------------
| Application Locale Configuration
|--------------------------------------------------------------------------
|
| The application locale determines the default locale that will be used
| by the translation service provider. You are free to set this value
| to any of the locales which will be supported by the application.
|
*/
'locale' => 'en',
/*
|--------------------------------------------------------------------------
| Application Fallback Locale
|--------------------------------------------------------------------------
|
| The fallback locale determines the locale to use when the current one
| is not available. You may change the value to correspond to any of
| the language folders that are provided through your application.
|
*/
'fallback_locale' => 'en',
/*
|--------------------------------------------------------------------------
| Encryption Key
|--------------------------------------------------------------------------
|
| This key is used by the Illuminate encrypter service and should be set
| to a random, 32 character string, otherwise these encrypted strings
| will not be safe. Please do this before deploying an application!
|
*/
'key' => env('APP_KEY'),
'cipher' => 'AES-256-CBC',
/*
|--------------------------------------------------------------------------
| Logging Configuration
|--------------------------------------------------------------------------
|
| Here you may configure the log settings for your application. Out of
| the box, Laravel uses the Monolog PHP logging library. This gives
| you a variety of powerful log handlers / formatters to utilize.
|
| Available Settings: "single", "daily", "syslog", "errorlog"
|
*/
'log' => env('APP_LOG', 'single'),
/*
|--------------------------------------------------------------------------
| Autoloaded Service Providers
|--------------------------------------------------------------------------
|
| The service providers listed here will be automatically loaded on the
| request to your application. Feel free to add your own services to
| this array to grant expanded functionality to your applications.
|
*/
'providers' => [
/*
* Laravel Framework Service Providers...
*/
Illuminate\Auth\AuthServiceProvider::class,
Illuminate\Broadcasting\BroadcastServiceProvider::class,
Illuminate\Bus\BusServiceProvider::class,
Illuminate\Cache\CacheServiceProvider::class,
Illuminate\Foundation\Providers\ConsoleSupportServiceProvider::class,
Illuminate\Cookie\CookieServiceProvider::class,
Illuminate\Database\DatabaseServiceProvider::class,
Illuminate\Encryption\EncryptionServiceProvider::class,
Illuminate\Filesystem\FilesystemServiceProvider::class,
Illuminate\Foundation\Providers\FoundationServiceProvider::class,
Illuminate\Hashing\HashServiceProvider::class,
Illuminate\Mail\MailServiceProvider::class,
Illuminate\Pagination\PaginationServiceProvider::class,
Illuminate\Pipeline\PipelineServiceProvider::class,
Illuminate\Queue\QueueServiceProvider::class,
Illuminate\Redis\RedisServiceProvider::class,
Illuminate\Auth\Passwords\PasswordResetServiceProvider::class,
Illuminate\Session\SessionServiceProvider::class,
Illuminate\Translation\TranslationServiceProvider::class,
Illuminate\Validation\ValidationServiceProvider::class,
Illuminate\View\ViewServiceProvider::class,
/*
* Application Service Providers...
*/
App\Providers\AppServiceProvider::class,
App\Providers\AuthServiceProvider::class,
App\Providers\EventServiceProvider::class,
App\Providers\RouteServiceProvider::class,
/**
* After adding illuminate/html: ~5.0
* @see http://ift.tt/28Ugd4m
*/
Collective\Html\HtmlServiceProvider::class,
],
/*
|--------------------------------------------------------------------------
| Class Aliases
|--------------------------------------------------------------------------
|
| This array of class aliases will be registered when this application
| is started. However, feel free to register as many as you wish as
| the aliases are "lazy" loaded so they don't hinder performance.
|
*/
'aliases' => [
'App' => Illuminate\Support\Facades\App::class,
'Artisan' => Illuminate\Support\Facades\Artisan::class,
'Auth' => Illuminate\Support\Facades\Auth::class,
'Blade' => Illuminate\Support\Facades\Blade::class,
'Cache' => Illuminate\Support\Facades\Cache::class,
'Config' => Illuminate\Support\Facades\Config::class,
'Cookie' => Illuminate\Support\Facades\Cookie::class,
'Crypt' => Illuminate\Support\Facades\Crypt::class,
'DB' => Illuminate\Support\Facades\DB::class,
'Eloquent' => Illuminate\Database\Eloquent\Model::class,
'Event' => Illuminate\Support\Facades\Event::class,
'File' => Illuminate\Support\Facades\File::class,
'Gate' => Illuminate\Support\Facades\Gate::class,
'Hash' => Illuminate\Support\Facades\Hash::class,
'Input' => Illuminate\Support\Facades\Input::class,
'Lang' => Illuminate\Support\Facades\Lang::class,
'Log' => Illuminate\Support\Facades\Log::class,
'Mail' => Illuminate\Support\Facades\Mail::class,
'Password' => Illuminate\Support\Facades\Password::class,
'Queue' => Illuminate\Support\Facades\Queue::class,
'Redirect' => Illuminate\Support\Facades\Redirect::class,
'Redis' => Illuminate\Support\Facades\Redis::class,
'Request' => Illuminate\Support\Facades\Request::class,
'Response' => Illuminate\Support\Facades\Response::class,
'Route' => Illuminate\Support\Facades\Route::class,
'Schema' => Illuminate\Support\Facades\Schema::class,
'Session' => Illuminate\Support\Facades\Session::class,
'Storage' => Illuminate\Support\Facades\Storage::class,
'URL' => Illuminate\Support\Facades\URL::class,
'Validator' => Illuminate\Support\Facades\Validator::class,
'View' => Illuminate\Support\Facades\View::class,
/**
* After adding illuminate/html: ~5.0
* @see http://ift.tt/28Ugd4m
*/
'Form' => 'Collective\Html\FormFacade',
'Html' => 'Collective\Html\HtmlFacade',
],
];
The form request validation app/Http/Requests/ProfileForm.php is
<?php
namespace App\Http\Requests;
use App\Http\Requests\Request;
class ProfileForm extends Request
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'address1' => 'required|max:255',
'address2' => 'max:255',
'city' => 'required|max:255|string',
'postcode' => 'required'
];
}
}
The resources/views/profiles/show.blade.php is:
@extends('layouts/app')
@section('content')
<h1> | <small></small></h1>
<div class="address">
<p>
<br>
<br>
<br>
<br>
</p>
</div>
@if ( Auth::user()->id == $user->id )
@endif
@stop
and the resources/views/profiles/edit.blade.php is:
@extends('layouts/app')
@section('content')
<h1>Edit Profile</h1>
<!-- Update request -->
<!-- Update request -->
<!-- Necessary to circumvent TokenMismatchException which arises from recent improvements to Laravel-->
<!-- This supplies a posted token value -->
{!! csrf_field() !!}
<!-- Necessary to circumvent TokenMismatchException -->
<!-- Address Line 1 field -->
<div class="form-group">
</div>
<!-- Address Line 2 field -->
<div class="form-group">
</div>
<!-- City field -->
<div class="form-group">
</div>
<!-- Postcode field -->
<div class="form-group">
</div>
<!-- Submit button -->
<div class="form-group">
</div>
@stop
The migration files are the vanilla out-of-the box Laravel 5 create_users_table.php and create_password_resets_table.php and a create_profiles_table.php which I created myself and is as follows:
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
/**
* Migration for profiles table
*
* <pre>
* Created with artisan command:
*
* php artisan make:migration:schema create_profiles_table --schema="address1:string, address2:string:nullable, <br>
* city:string, postcode:string, country:integer, location:string:nullable"
* </pre>
*/
class CreateProfilesTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('profiles', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id');
$table->string('address1');
$table->string('address2')->nullable();
$table->string('city');
$table->string('postcode');
$table->integer('country');
$table->string('location')->nullable();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('profiles');
}
}
The MySql create code for the profiles table is:
CREATE TABLE `profiles` (
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`user_id` INT(11) NOT NULL,
`address1` VARCHAR(255) NOT NULL COLLATE 'utf8_unicode_ci',
`address2` VARCHAR(255) NULL DEFAULT NULL COLLATE 'utf8_unicode_ci',
`city` VARCHAR(255) NOT NULL COLLATE 'utf8_unicode_ci',
`postcode` VARCHAR(255) NOT NULL COLLATE 'utf8_unicode_ci',
`country_id` INT(11) NOT NULL,
`location` VARCHAR(255) NULL DEFAULT NULL COLLATE 'utf8_unicode_ci',
`created_at` TIMESTAMP NULL DEFAULT NULL,
`updated_at` TIMESTAMP NULL DEFAULT NULL,
PRIMARY KEY (`id`)
)
COLLATE='utf8_unicode_ci'
ENGINE=InnoDB
AUTO_INCREMENT=2
;
I can login and logout without problem. Everything happens with the profile management and I've isolated the problem as being ProfilesController::__construct(ProfileForm $profileForm). When I remove the argument from the constructor, the ProfilesController executes, however I have no form-request-based validation available any more.
I removed the argument to get me into the Show Profile page, then re-instated it once inside the page to see how it would affect clicking the "Edit Profile" link in the show.blade.php above. The site responds by failing with a "redirected you too many times" error.
I'm running WAMPServer with PHP version 5.5.12 and Apache version 2.4.9
Can anybody help?
via Chebli Mohamed
Aucun commentaire:
Enregistrer un commentaire