Copywriter (Nguyen Duy)

Copywriting.           

Trước khi tìm hiểu về Copywriter, ta tìm hiểu Copywriting là gì, bao gồm bài viết, slogan (khẩu hiệu), tiêu đề, thư, tagline, lời hát quảng cáo, các nội dung trên mạng, các kịch bản phim quảng cáo truyền hình hoặc kịch bản quảng cáo trên đài phát thanh, thông cáo báo chí, bản tin, và rất nhiều tài liệu khác của doanh nghiệp nhằm để quảng cáo trên các phương tiện truyền thông.

Các copywriter có thể đóng góp ý tưởng và ngôn từ của họ cho các ấn phẩm quảng cáo, như các cataloge (tài liệu), bản tin, phim quảng cáo, brochures (một dạng ấn phẩm quảng cáo ), postcards (bưu thiếp), website, email, thư, và các hình thức quảng cáo khác.

Copywriter.

Hiểu theo nghĩa gốc, copy là phần lời nội dung, writer là người viết. Copywriter là người viết nội dung quảng cáo. Là hoạt động sao chép văn bản cho mục đích quảng cáo hoặc tiếp thị cho các doanh nghiệp, cơ quan, mặc hàng.

Copywriter có thể làm được những công việc gì?

- Một copywriter có thể làm việc độc lập hoặc làm việc trong một công ty nào đó, thường là các công ty quảng cáo.

- Viết bài, slogan (tiêu đề), lời hát quảng cáo, các nội dung trên mạng và rất nhiều tài liệu khác.

- Các copywriter có thể đóng góp ý tưởng và ngôn từ của họ cho các bài viết, các nội dung trên mạng, bản tin…

Quy trình làm việc của một copywriter.

- Nhận Brief (bản tóm tắt công việc).

- Thông tin khách hàng, sản phẩm và mục tiêu khách hàng đặt ra cho sản phẩm.

- Làm việc với phát thảo và phát triển ý tưởng.

- Chọn lọc ý tưởng và làm việc.

- Đưa ý tưởng cho khách hàng duyệt và chỉnh sửa trước khi tiến hành.

- Thực hiện và hoàn chỉnh bài viết.

Có 7 dạng copywriter.

- Long Copy / Sale Letter Copywriter. (người viết quảng cáo dài-viết tay)

Là dạng copywriter cổ điển nhất. Viết những bài có nội dung dài cho webside.

Họ là những người đảm bảo việc sắp xếp các câu chữ để cho bài viết mạch lạc và có tính thuyết phục cao từ đầu bài cho đến kết bài.

Điểm Mạnh: Viết tốt, sử dụng từ ngữ phong phú,.

Viết tốt cho: Sale letter, sale page, thông cáo báo chí.

- Creative/ Advertising Copywriter (Sáng tạo/ quảng cáo).

Viết bài khá ít, đôi khi công việc của họ chỉ là câu slogan, điểm mạnh của họ là sự sang tạo chứ không phải viết. Thay vì tập trung vào những bài copy dài, họ dành thời gian để sang tạo nên khái niệm cho các chiến dịch…công việc của họ thú vị nhưng đầy thách thức.

Điểm mạnh: Sáng tạo, nhiều ý tưởng, hiểu tâm lý con người.

Viết tốt cho: Slogan, tagline, Storyboard, Concep.

- Digital Copywriter (kỹ thuật số).

Công việc hàng ngày của họ là sẽ đắn đo giữa câu "Dùng thử miễn phí" với câu "Dùng thử ngay" trên các các nút kêu gọi, thu hút sự chú ý (call-to-action).

Điểm mạnh: Tỉ mỉ, nhẫn nại, sự thuyết phục.

Viết tốt cho: Social Post, Copy điều hướng trên Web, micro copy...

- Technical Copywriter (kỹ thuật viên).

Những người Copywriter dạng này có thể văn phòng không được phong phú như những dạng khác nhưng họ có một yêu cầu bắt buộc là phải hiểu sâu về kĩ thuật, về ngành nghề mà mình viết. Đó là những người chuyên viết giới thiệu sản phẩm, viết review, phân tích ưu điểm, nhược điểm của các sản phẩm mới.

Điểm mạnh: Có kiến thức sâu về chuyên ngành, có tiếng nói.

Viết tốt cho: Bài giới thiệu, review sản phẩm.

- Publisher / Content Copywriter (Nhà xuất bản/ nội dung).

Là những người hiểu về độc giả của họ nhất, biết cách chuyển hóa thông tin quảng cáo làm sao cho độc giả mình dễ tiếp nhận nhất.

Điểm mạnh: Hiểu đối tượng độc giả.

Viết tốt cho: Bài PR, content , forum seeding storyboard.

- SEO Copywriter (Tối ưu hóa máy tìm kiếm).

Copywriter  sẽ làm việc với các keywords hàng ngày và tìm chủ đề xung quanh nó để viết bài. Các bài viết của copywriter dạng này sẽ chú trọng hơn vào phần kĩ thuật SEO như tần suất xuất hiện keywords, đặt keywords ở đâu cho hợp lý... tất cả nhằm tăng thứ hạng SEO cho bài viết nói riêng cũng như Website nói chung.

Điểm mạnh: Hiểu về SEO, biết cách tìm ý tưởng cho nội dung.

Viết tốt cho: Website Content.

- Inhouse/ Brand Copywriter (Nội thất/ nhãn hiệu).

Người làm Inhouse Copywriter chính là "đại diện" về mặt câu chữ của thương hiệu. Cũng có thể hiểu không sai khi nói họ là những "nhà báo thương hiệu" - người chỉ đưa tin về thương hiệu. Họ viết tất cả những gì mà nhãn yêu cầu nội dung trên website...

Điểm mạnh: Hiểu sâu về nhãn hàng, hiểu khách hàng mục tiêu.

Viết tốt: Blog Article, PR, Thông cáo báo chí...

Cách đưa địa điểm doanh nghiệp lên goolge maps

CÁCH ĐƯA ĐỊA ĐIỂM DOANH NGHIỆP LÊN GOOLGE MAPS

Bước 1: Để đưa địa điểm doanh nghiệp lên Google Maps, bạn cần chuẩn bị những yếu tố sau:

_ Logo của công ty.
_ Một vài hình ảnh chung về công ty.
_ Địa chỉ chính xác để bạn có thể nhận được xác minh từ Google.
_ Một tài khoản Goolge Plus

Bước 2: Truy cập vào đường link sau:https://www.google.com/business/placesforbusiness/ rồi ấn nút đăng ký Get on Google.

Bước 3: Đăng nhập vào tài khoản Gmail. Sau đó, bạn sẽ được chuyển sang https://www.google.com/local/business/add

Ở bước này hãy nhập địa chỉ công ty của mình. Khi bạn nhập địa chỉ và không có doanh nghiệp nào trong số này trùng khớp hãy thêm doanh nghiệp của mình

Bước 4: Khi chọn thêm doanh nghiệp, mình sẽ được chuyển đến trang https://www.google.com/local/business/add/info, ở đây chúng ta hãy điền tên công ty, quốc gia, đường phố, tỉnh thành, số điện thoại, danh mục. Mình cần nhập địa chỉ chính xác để có thể nhận mã xác minh từ Google.

Bước 5: Gửi yêu cầu xác minh công ty rồi chờ đợi trong 1, 2 tuần hoặc lâu hơn Google sẽ gửi bưu thiếp về địa chỉ cho mình. (Có một số trường hợp cần gửi yêu cầu xác minh 1, 2 lần)

Bước 6: Xác minh địa chỉ
Sau khi nhận được thư, bạn lấy mã PIN và làm theo hướng dẫn chi tiết trong thư. Đến bước này, Google sẽ báo rằng chúng ta đã hoàn tất và địa chỉ công ty sẽ bắt đầu hiển thị trên Google. (Nhưng bản đồ không hiển thị ngay đâu, bạn vẫn phải chờ đó)

Để chỉnh sửa hồ sơ hiển thị trên Google, mình có thể vào đường link https://www.google.com/business/placesforbusiness/

Không phải khi chúng ta đưa địa điểm doanh nghiệp lên google maps xong rồi ta seach thì sẽ hiện thị doanh nghiệp ta trên trang đầu .Muốn được như vậy chúng ta cần phải dùng đến thủ thuật SEO (Search Engine Optinization) Tối ưu hoá iwebsite với
công cụ tìm kiếm.

Ở đây mình sẻ đề cập đến Local Seo. Đó là một cách làm cho kết quả tìm kiếm của chúng ta trả về có kèm bản đồ của Google Maps, số điện thoại, địa chỉ website của chúng ta và hiệ một số hình ảnh sản phẩm mà bạn cập nhật trong Local Seo.

Chúng ta có thể tham khảo một số công cụ SEO: Google Analytics; Google Trends; Google Webmaster Tool; Google Adword KeyWord Tool.

Để làm cho doanh nghiệp nổi bật hơn bên cạnh những việc đó chúng ta còn phải có hình ảnh về doanh nghiệp, đặc biệt là ảnh 360.  VẬy làm sao để ta đăng ảnh và liên kết ảnh 360 trên Google Maps.

Ảnh 360 khi riêng lẻ ta chỉ xem được cảnh vật xung quanh, nhưng khi ta liên kết lại nó có thể thành một công cụ chỉ đường rất hữu ích trên google map.

Có 2 bước chúng ta phải làm theo quy trình:

- Bước đầu chúng ta phải upload ảnh lên google map theo đúng địa điểm đã check trên map

- Bước hai là sử dụng ứng dụng google street view để kết nối lại.

Việc sử dụng ảnh 360 độ sẽ mộ tả rõ hơn vể địa điểm mà ta đề cập đến. Ta còn có thể nhìn thấy mọi thứ xung quanh địa điển đó. Ảnh 360 độ được sử dụng rất phổ biến hiện nay. Đặc biệt là trên Google Maps, nó có thể vạch cho ta một con đường đến địa điểm ta cần đến.

Tất cả các vấn đề trên nó mang lại cho tui một cảm giác thích thú khi chọn đề tài quảng bá doanh nghiệp theo hướng Google Loacl Guides.

Quảng cáo và SEO trên facebook (Nguyễn Duy)

Seo Facebook là gì?

- SEO (Search Engine Optimization) là công việc bạn tối ưu hóa trang web của bạn để thân thiện với Facebook và quan trọng là bảo đảm cung cấp giá trị đến người đọc.

Công việc này nhằm mục đích chính là giúp trang của bạn lên top Google. Có nghĩa khi ai đó tìm một từ khóa nào đó, trang facebook  bạn tối ưu tốt sẽ nằm ở top đầu .

Thủ thuật SEO Facebook.

1. Đặt tên: Đặt tên cho Fanpage hợp lý là một việc làm vô cùng quan trọng vì thế hãy chú ý đến vấn đề này, tốt nhất là đặt tên có chứa từ khóa.

2. Sử dụng các từ khóa trong Fanpage.

- SEO title – tên Fanpage.

- Meta Description = tên Fanpage + các phần tử khác trên trang.

- H1 = tên Fanpage.

3. Đặt backlink cho fanpage trên các trang hiện có.

- Càng có nhiều liên kết trỏ về trang thì trang càng được Google đánh giá cao và dĩ nhiên thứ hạng cũng được tăng đáng kể.

4. SEO trên Facebook Note.

Facebook Note được tận dụng khá nhiều khi sử dụng một cách hợp lý, Facebook Note có thể giúp ích cho Fanpage để gia tăng hiệu quả tổng thể cho SEO.

Từ khóa SEO:

- SEO Title = tiêu đề của bản ghi chú.

- Meta data = Tên fanpage là tên của tiêu đề bản ghi chú.

5. SEO offpage cho fanpage.

- Bất cứ một website nào cũng cần SEO offpage.

6. Kiểm tra phần “Cài đặt”.

- Bạn có thể kiểm soát toàn bộ thông tin của shop bằng cách thay đổi phần Cài đặt, bạn có thể tìm thấy ở cạnh nút Trợ Giúp, góc trên bên phải màn hình.

- Tại đây bạn có thể tìm các thông tin như: Chung, Vai trò trên trang, Đối tượng yêu thích của trang.

- Hãy dành vài phút để kiểm tra từng chức năng một nhằm chắc chắn rằng sản phẩm của bạn “chạm tới tay” người tiêu dùng. Điều này rất cần thiết vì sẽ tối ưu hóa phần SEO.

Chú ý:

Mô tả ngắn:

- Tương tự như thẻ Meta Description, chứa từ khóa, độ dài lớn hơn hoặc bằng 155 ký tự. Mô tả ngắn gọn và xúc tích nội dung của Fanpage.

- Thẻ Meta Description: Còn được gọi thẻ mô tả, là thuật ngữ ám chỉ một đoạn văn bản mô tả về nội dung trong một trang web, giúp cho người sử dụng cũng như Google hiểu được điều bạn muốn nói bên trong trang đó. Là phần nội dung được rút gọn, mang ý nghĩa chi tiết nhất về phần nội dung muốn viết bên trong trang của một website.

- Nên đặt từ khóa ngay dòng đầu tiên của Content.

- Dự đoán từ khóa mà khách hàng sẽ tìm kiếm.

- Từ khóa không nên quá dài.

- Lặp lại từ khóa và phân bổ đề ở đầu bài, giữa bài và cuối bài. Không nên chèn, nhét quá nhiều từ khóa trong Content (phần nội dung trên một trang của website).

- Những hình ảnh liên quan đến từ khóa phải thật rõ ràng. Tập trung vào sản phẩm chính liên quan đến từ khóa cần SEO.

- Các cài đặt trong Facebook cũng rất quan trọng, sau đây là một số chức năng cần biết khi SEO trong facebook.

Cài đặt “chung”:

- Tin nhắn: Cho phép mọi người dùng và Trang liên hệ riêng với bạn. Nếu bỏ chức năng này, thì bạn đã vô tình chặn tất cả tin nhắn từ mọi người.

- Khả năng gắn thẻ: Cho phép người dùng được gắn thẻ ảnh và video do người dùng đăng lên. Chức năng này chỉ phù hợp với các trang facebook bình thường. Đối với các trang kinh doanh, mua bán, tốt nhất nên bỏ chức năng này. Vì một số đối tượng sẽ lợi dụng việc gắn thẻ gắn những nội dung không đúng, mang tính phá hoại.

- Người khác gằn thẻ trang này: Cho phép mọi người và trang khác gắn thẻ trang của bạn. Cho phép mọi người có thể chia sẻ thông tin hữu ích với nhau.

- Giới hạn quốc gia: Người dùng có hai quyền lựa chọn để hiển thị trang của mình.

+ Chỉ hiện thị trang cho người xem tại quốc gia sau: Người dùng trước tiên phải nhập tên quốc gia cần hiển thị trang, thì hệ thống mới hiện thị dấu tích.

+ Ẩn trang này khỏi người xem tại quốc gia sau: Mặc định khi tạo trang sẽ đươc tích sẵn. Bạn có thể chọn quốc gia mà trang bạn không muốn hiển thị. Nếu không có quốc gia nào được liệt kê, trang của bạn sẽ hiển thị cho tất cả mọi người .

 - Giới hạn tuổi: Khi bạn chọn một giới hạn tuổi cho trang của bạn, những người trẻ hơn sẽ không thể xem trang hoặc nội dung Trang của bạn.

- Kiểm duyệt trang: Khi mọi người đưa một từ mà bạn đã chặn vào một bài viết hoặc bình luận trên trang của bạn, bài viết hoặc bình luận đó sẽ không xuất hiện trên trang.

Bạn có thể chặn mức độ tục tĩu khác nhau khỏi xuất hiện trên trang của mình. Facebook sẽ xác định nên chặn gì bằng cách sử dụng các từ và cụm từ bị báo cáo nhiều nhất và bị cộng đồng đánh dấu là xúc phạm.

- Gợi ý trang tương tự: Facebook sẽ gợi ý trang của bạn đến người dùng khi họ truy cập trang khác, ngược lại facebook sẽ giới thiệu trang của người khác khi bạn truy cập.

Bài 3 - Laravel xử lý đăng nhập và phân quyền

Chức năng đăng nhập trong laravel

Chào các bạn, hôm này mình sẽ giới thiệu với các bạn cách tạo trang đăng ký, đăng nhập và phần quyền với Laravel.

Nếu các bạn thực hiện tạo bảng dữ liệu trong mysql bằng cách sử dụng lệnh command "php artisan migrate" thì trong cơ sở dữ liệu của các bạn đã có bảng "users". Nếu trong cơ sở dữ liệu của các bạn chưa có bảng "users" thì các bạn gõ lệnh command trên để laravel sẽ tự động tạo bảng cho các bạn.

Lavarel đã tạo sẵn các file controller cho bảng "users"  trong thư mục "app/Http/Controllers/Auth" nên chúng ta có thể sử dụng các file này để xây dựng chức năng đang nhập.

Trước tiên chúng ta định hướng đường dẫn website mặc định sẽ vào trang đăng nhập cho file web.php trong thư mục routes như sau:

// Sửa đường dẫn trang chủ mặc định
Route::get('/', 'HocsinhController@index');
Route::get('/home', 'HocsinhController@index');

// Đăng ký thành viên
Route::get('register', 'Auth\RegisterController@getRegister');
Route::post('register', 'Auth\RegisterController@postRegister');

// Đăng nhập và xử lý đăng nhập
Route::get('login', [ 'as' => 'login', 'uses' => 'Auth\LoginController@getLogin']);
Route::post('login', [ 'as' => 'login', 'uses' => 'Auth\LoginController@postLogin']);

// Đăng xuất
Route::get('logout', [ 'as' => 'logout', 'uses' => 'Auth\LogoutController@getLogout']);

Tiếp theo, để vào trang học sinh kiểm tra nếu chưa đăng nhập vào hệ thống thì sẽ tự động chuyển ra trang đăng nhập chúng ta thêm đoạn code sau trong file "HocSinhController.php":

public function __construct() {
	$this->middleware('auth');
}

 

Chúng ta sẽ tạo một trang form đăng nhập trong thư mục "resource/views/auth/" file "login.blade.php" với nội dung đoạn code sau:

@extends('templates.master')
@section('title','Trang quản lý')
@section('content')
<?php //Hiển thị thông báo thành công?>
@if ( Session::has('success') )
<div class="alert alert-success alert-dismissible" role="alert">
<strong>{{ Session::get('success') }}</strong>
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">&times;</span>
<span class="sr-only">Close</span>
</button>
</div>
@endif
<?php //Hiển thị thông báo lỗi?>
@if ( Session::has('error') )
<div class="alert alert-danger alert-dismissible" role="alert">
<strong>{{ Session::get('error') }}</strong>
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">&times;</span>
<span class="sr-only">Close</span>
</button>
</div>
@endif
@if ($errors->any())
<div class="alert alert-danger alert-dismissible" role="alert">
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">&times;</span>
<span class="sr-only">Close</span>
</button>
</div>
@endif
<div class="container" style="margin-top: 10%">
<div class="row">
<div class="col-sm-6 col-md-4 col-md-offset-4">
<div class="panel panel-default">
<div class="panel-body">
<form role="form" action="{{ url('/login') }}" method="POST">
{!! csrf_field() !!}
<fieldset>
<div class="row">
<div class="center-block">
<img class="profile-img" src="/public/images/user-icon.png" alt="User">
</div>
</div>
<div class="row">
<div class="col-sm-12 col-md-10 col-md-offset-1 ">
<div class="form-group">
<div class="input-group">
<span class="input-group-addon"><i class="glyphicon glyphicon-user"></i></span>
<input class="form-control" placeholder="Email" name="email" type="text" value="{{ old('email') }}" autofocus>
</div>
</div>
<div class="form-group">
<div class="input-group">
<span class="input-group-addon"><i class="glyphicon glyphicon-lock"></i></span>
<input class="form-control" placeholder="Mật khẩu" name="password" type="password" value="">
</div>
</div>
<div class="form-group">
<input type="submit" class="btn btn-lg btn-primary btn-block" value="Đăng nhập">
</div>
<div class="login-help">
<a href="/{{ url('/register') }}" >Đăng ký</a> - <a href="#" >Quên mật khẩu</a>
</div>
</div>
</div>
</fieldset>
</form>
</div>
</div>
</div>
</div>
</div>
<style>
body{
background: #17568C;
}
.panel{
border-radius: 5px;
}
.panel-heading {
padding: 10px 15px;
}
.panel-title{
text-align: center;
font-size: 15px;
font-weight: bold;
color: #17568C;
}
.panel-footer {
padding: 1px 15px;
color: #A0A0A0;
}
.profile-img {
width: 120px;
height: 120px;
margin: 0 auto 10px;
display: block;
-moz-border-radius: 50%;
-webkit-border-radius: 50%;
border-radius: 50%;
}
</style>
@endsection

 

Trong file web.php chúng ta đã định trang đang nhập bằng cách gọi hàm "getLogin()" trong file "LoginController.php".

Vậy nên chúng ta sẽ viết hàm hiển thị form đăng nhập trong "LoginController.php" của thư mục "app/Http/Controllers/Auth" để gọi đến file form chúng ta đã tạo.

public function getLogin() {
	return view('auth/login');
}

Tiếp theo chúng ta sẽ viết thêm hàm xử lý đăng nhập trong "LoginController.php" của thư mục "app/Http/Controllers/Auth". Chúng ta cần khai báo một số thư viện được sử dụng trong hàm xử lý.

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\Auth;
use Session;

Nội dung hàm xử lý đăng nhập:

public function postLogin(Request $request) {
	// Kiểm tra dữ liệu nhập vào
	$rules = [
		'email' =>'required|email',
		'password' => 'required|min:6'
	];
	$messages = [
		'email.required' => 'Email là trường bắt buộc',
		'email.email' => 'Email không đúng định dạng',
		'password.required' => 'Mật khẩu là trường bắt buộc',
		'password.min' => 'Mật khẩu phải chứa ít nhất 8 ký tự',
	];
	$validator = Validator::make($request->all(), $rules, $messages);
	
	
	if ($validator->fails()) {
		// Điều kiện dữ liệu không hợp lệ sẽ chuyển về trang đăng nhập và thông báo lỗi
		return redirect('login')->withErrors($validator)->withInput();
	} else {
		// Nếu dữ liệu hợp lệ sẽ kiểm tra trong csdl
		$email = $request->input('email');
		$password = $request->input('password');

		if( Auth::attempt(['email' => $email, 'password' =>$password])) {
			// Kiểm tra đúng email và mật khẩu sẽ chuyển trang
			return redirect('hocsinh');
		} else {
			// Kiểm tra không đúng sẽ hiển thị thông báo lỗi
			Session::flash('error', 'Email hoặc mật khẩu không đúng!');
			return redirect('login');
		}
	}
}

Đến đây chức năng đăng nhập đã hoàn thành. Vì cơ sở dữ liệu được tạo không có tài khoản nào nên chúng ta sẽ viết tiếp form đăng ký thành viên.

Chúng ta sẽ viết form đăng ký thành viên trong thư mục "resources/views/auth" tên file là "register.blade.php" với nội dung đoạn code như sau:

@extends('templates.master')
@section('title','Trang quản lý')
@section('content')
<?php //Hiển thị thông báo thành công?>
@if ( Session::has('success') )
<div class="alert alert-success alert-dismissible" role="alert">
<strong>{{ Session::get('success') }}</strong>
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">&times;</span>
<span class="sr-only">Close</span>
</button>
</div>
@endif
<?php //Hiển thị thông báo lỗi?>
@if ( Session::has('error') )
<div class="alert alert-danger alert-dismissible" role="alert">
<strong>{{ Session::get('error') }}</strong>
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">&times;</span>
<span class="sr-only">Close</span>
</button>
</div>
@endif
@if ($errors->any())
<div class="alert alert-danger alert-dismissible" role="alert">
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">&times;</span>
<span class="sr-only">Close</span>
</button>
</div>
@endif
<div class="container" style="margin-top: 10%">
<div class="row">
<div class="col-sm-6 col-md-4 col-md-offset-4">
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">ĐĂNG KÝ THÀNH VIÊN</h4>
</div>
<div class="panel-body">
<form role="form" method="POST" action="{{ url('/register') }}">
{!! csrf_field() !!}
<div class="form-group">
<div class="input-group">
<span class="input-group-addon"><i class="glyphicon glyphicon-user"></i></span>
<input class="form-control" placeholder="Họ và tên" name="name" type="text" value="{{ old('name') }}" autofocus>
</div>
</div>
<div class="form-group">
<div class="input-group">
<span class="input-group-addon"><i class="glyphicon glyphicon-envelope"></i></span>
<input class="form-control" placeholder="Email" name="email" type="text" value="{{ old('email') }}">
</div>
</div>
<div class="form-group">
<div class="input-group">
<span class="input-group-addon"><i class="glyphicon glyphicon-lock"></i></span>
<input class="form-control" placeholder="Mật khẩu" name="password" type="password">
</div>
</div>
<div class="form-group">
<div class="input-group">
<span class="input-group-addon"><i class="glyphicon glyphicon-lock"></i></span>
<input class="form-control" placeholder="Xác nhận mật khẩu" name="password_confirmation" type="password">
</div>
</div>
<div class="form-group">
<button type="submit" class="btn btn-lg btn-primary btn-block">Đăng ký</button>
</div>
<center><a href="/{{ url('/login') }}">Quay về đăng nhập</a></center>
</form>
</div>
</div>
</div>
</div>
</div>
<style>
body{
background: #17568C;
}
.panel{
border-radius: 5px;
}
.panel-heading {
padding: 10px 15px;
}
.panel-title{
text-align: center;
font-size: 15px;
font-weight: bold;
color: #17568C;
}
.panel-footer {
padding: 1px 15px;
color: #A0A0A0;
}
.profile-img {
width: 120px;
height: 120px;
margin: 0 auto 10px;
display: block;
-moz-border-radius: 50%;
-webkit-border-radius: 50%;
border-radius: 50%;
}
</style>
@endsection

Trong file web.php chúng ta đã viết chức năng gọi đến đường dẫn đăng ký thành viên bằng cách gọi đến hàm getRegister() trong file "RegisterController.php" của thư mục "app/Http/Controllers/Auth" nên chúng ta sẽ viết hàm này gọi đến form đăng ký như sau:

public function getRegister() {
	return view('auth/register');
}

Tiếp theo chúng ta sẽ khai báo một số thư viện sau cho hàm hàm xử lý đăng ký như sau:

use Illuminate\Http\Request;
use Session;

Nội dung code hàm xử lý đăng ký trong file "RegisterController.php" sẽ được viết như sau:

public function postRegister(Request $request) {
    // Kiểm tra dữ liệu vào
	$allRequest  = $request->all();	
	$validator = $this->validator($allRequest);

	if ($validator->fails()) {
		// Dữ liệu vào không thỏa điều kiện sẽ thông báo lỗi
		return redirect('register')->withErrors($validator)->withInput();
	} else {   
		// Dữ liệu vào hợp lệ sẽ thực hiện tạo người dùng dưới csdl
		if( $this->create($allRequest)) {
			// Insert thành công sẽ hiển thị thông báo
			Session::flash('success', 'Đăng ký thành viên thành công!');
			return redirect('register');
		} else {
			// Insert thất bại sẽ hiển thị thông báo lỗi
			Session::flash('error', 'Đăng ký thành viên thất bại!');
			return redirect('register');
		}
	}
}

Trong đoạn code trên chúng ta sử dụng hàm kiểm tra dữ liệu nhập vào validator(), các bạn có thể chỉnh nội dung thông báo thành tiếng việt bằng cách thay đổi thành đoạn code sau:

protected function validator(array $data)
{
	return Validator::make($data,
		[
			'name' => 'required|string|max:255',
			'email' => 'required|string|email|max:255|unique:users',
			'password' => 'required|string|min:6|confirmed',
		],
		[
			'name.required' => 'Họ và tên là trường bắt buộc',
			'name.max' => 'Họ và tên không quá 255 ký tự',
			'email.required' => 'Email là trường bắt buộc',
			'email.email' => 'Email không đúng định dạng',
			'email.max' => 'Email không quá 255 ký tự',
			'email.unique' => 'Email đã tồn tại',
			'password.required' => 'Mật khẩu là trường bắt buộc',
			'password.min' => 'Mật khẩu phải chứa ít nhất 8 ký tự',
			'password.confirmed' => 'Xác nhận mật khẩu không đúng',
		]
	);
}

 

Đên đây các bạn có thể tạo một tài khoản và đăng nhập vào hệ thống. Nếu các bạn muốn phân quyền người dụng các bạn có thể thực hiện như sau:

+ Thêm một trường dữ liệu vào bảng "user" có tên là "level" miền giá trị kiểu int(10): Trường này chúng ta quy định 1 là SuperAdmin, 2 là Admin, 3 là thành viên.

+ Sửa lại hàm create() trong file "RegisterController.php" chúng ta thêm giá trị cho trường level như đoạn code sau:

protected function create(array $data)
{
	return User::create([
		'name' => $data['name'],
		'email' => $data['email'],
		'level' => '3',
		'password' => bcrypt($data['password']),
	]);
}

+  Chúng ta thêm level cho "protected $fillable " trong file "User.php" của thư mục "app" như sau:

protected $fillable = [
	'name', 'email', 'password', 'level',
];

Khi đăng ký thành viên thì level sẽ là 3 (thành viên). Chúng ta có thể hiển thị kết quả phân quyền bằng các thêm đoạn code sau trong thẻ <div class="container"></div> của file master.blade.php

@if (Auth::check())
<div>
Bạn đang đăng nhập với quyền 
@if( Auth::user()->level == 1)
	{{ "SuperAdmin" }}
@elseif( Auth::user()->level == 2)
	{{ "Admin" }}
@elseif( Auth::user()->level == 3)
	{{ "Thành viên" }}
@endif
</div>
<div class="pull-right" style="margin-top: 3px;"><a class="btn btn-primary" href="/{{ url('/logout') }}">Đăng xuất</a></div>
@endif

Trong đoạn code trên tôi có thêm nút đăng xuất và trong file web.php cũng đã tạo link đăng xuất gọi đến hàm getLogout() trong file "LogoutController.php".

Chúng ta sẽ tạo file "LogoutController.php" bằng cách gõ lệnh command sau:

php artisan make:controller Auth/LogoutController --resource

Sau khi tạo xong chúng ta vào thư mục mở file "LogoutController.php" và viết nội dung file với nội dung như sau:

<?php

namespace App\Http\Controllers\Auth;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Auth;

class LogoutController extends Controller
{
    public function __construct() {
    	$this->middleware('auth');
    }
		
	public function getLogout() {
		Auth::logout();
		return redirect('login');
	}
}

 

Vậy là chúng ta đã hoàn thành các chức năng đăng ký, đăng nhập, phân quyền và đăng xuất.

Qua bài này, mong là có thể giúp ích cho các bạn trong lập trình php với laravel.

Ngụy kim Hưng

Nạp code không dây với ESP8266

 

Làm thế nào để cập nhật từ xa cho ESP8266 ? Hẳn là các bạn có biết một cách để nạp firmware cho ESP8266 cần có kết nối với máy tính qua cổng USB, vậy nếu bạn thấy quá trình trên phải sử dụng dây nối rườm rà quá, ESP8266 có wifi mà sao không tận dụng kết nối wifi để nạp luôn firmware cho chip mà chưa biết cách thì đây đúng là bài bạn cần rồi đấy.

OTA là gì ?

Cập nhật firmware OTA (Over the Air) là quá trình tải firmware mới vào ESP8266 thông qua mạng wifi thay vì sử dụng cổng Serial truyền thống.

Có 3 cách để cập nhật OTA cho ESP8266:

  • Dùng Arduino IDE: tận dụng Arduino IDE có sẵn, thay lựa chọn Port > COM bằng Port > IP
  • Dùng Web Browser: ESP8266 tạo một webserver để ta có thể chọn đường dẫn firmware mới
  • HTTP Server: Cập nhật firmware cho ESP8266 từ một server

Trong quá trình làm thì mình sẽ sử dụng linh hoạt giữa nạp firmware qua serial (cho lần đầu tiên và các lần có sự cố) và nạp firmware qua OTA. Ngoài ra thì có một số vấn đề về bảo mật khi nạp firmware qua OTA được đề cập trong bài viết chỉ ở mức đơn giản.

Chuẩn bị

Phần cứng

  • Node MCU hoặc ESP8266 phiển bản bất kỳ từ V7 trở lên + USB2UART modul (mình dùng NodeMCU)

Phần mềm

Có một yêu cầu nhỏ nữa là máy tính và ESP8266 phải kết nối tới cùng một mạng (nghĩa là chung wifi)

Cài đặt

Các bạn cài đặt python như bình thường. Mình chỉ có một lưu ý khi cài đặt Python nhớ tick chọn Add python.exe to Path như hình

Chỉ cần thế là xong, chúng ta sẽ đi vào luôn cách nạp OTA qua các ví dụ cụ thể

OTA qua Arduino IDE

Cơ bản

Chương trình OTA cho Arduino có sẵn tại đường dẫn File > Examples > ArduinoOTA > BasicOTA hoặc bạn có thể xem chương trình dưới.

Ở đây chỉ có một lưu ý là bạn phải chỉnh lại ten_wifi và password lại cho phù hợp

1
2
const char* ssid = "ten_wifi";
const char* password = "password";
Chương trình OTA Arduino

Kết quả

Sau khi nạp chương trình xuống và mở debug serial ra bạn sẽ thấy hiện IP address, quay lại chương trình chính điều chỉnh Port từ COM chuyển sang IP và tiếp tục complie nạp lại chương trình trên luôn, mục đích là mình kiểm tra xem nạp qua IP có được hay không

Lưu ý 1:

 

Nếu bạn không thấy hiện IP chỗ Port thì tắt Arduino đi và mở lại IP sẽ xuất hiện.

Để tăng tốc độ nạp chương trình bạn có thể thay đổi tại Tool > Upload speed thành 921600

 

Nếu thành công sẽ có thông báo như sau

Có mật khẩu

Tạm thời bước cập nhật qua firmware cơ bản đã thành công, tuy nhiên có một vấn đề phát sinh là nếu update như vậy thì cứ ai ở trong cùng một mạng, có máy tính và Arduino thì đều có thể điều chỉnh thay đổi và nạp firmware linh tinh xuống dưới ESP, nếu trong trường hợp nhà mình sử dụng có mỗi mình thì không vấn đề, nhưng nếu có ai có ý đồ đen tối muốn phá thì vô cùng nguy hiểm. Thôi thêm vào cái mật khẩu cho chắc ăn. Vậy thêm như thế nào ? Vẫn chương trình cũ, chỉ cần mở comment ra chỗ đoạn code

1
ArduinoOTA.setPassword((const char *)"123");

123 là mật khẩu mặc định, bạn có thể thay bằng mật khẩu riêng của mình

Lưu ý 2: Chương trình Arduino vẫn giữ nguyên, nếu có gặp lỗi không hiện IP chỗ port thì bạn vui lòng khởi động lại

 

Hiện tại ESP chỉ hỗ trợ nạp qua IP chứ chưa hỗ trợ debug hiện serial qua IP nhé, nên nhiều lúc ấn vào Debug bạn nhập pass và sẽ có báo sai liên tục. Vui lòng không dùng debug Serial khi nạp qua OTA.

ESPv1 không đủ bộ nhớ cho OTA, nên nếu làm sẽ có lỗi thiếu bộ nhớ

 

OTA qua WebBrowser

Từ việc up firmware qua Arduino quá bất tiện, nhiều lúc không nhận IP lại phải khởi động lại rất mất công thì có một cách khác để up firmware thông qua WebBrowser. Với cách này thì sẽ có một số ưu điểm trong các trường hợp sau:

  • Thấy Arduino rắc rối quá hoặc là vì lý do nào đó mà không nạp được firmware từ Arduino xuống ESP8266.
  • Khi không có server riêng để update OTA hoặc muốn update từ local.
  • Dùng để cập nhật firmware cho số lượng modul vừa phải.

Với chương trình thì chúng ta cần lưu ý chỉnh lại ten_wifi và password lại cho phù hợp

1
2
const char* ssid = "ten_wifi";
const char* password = "password";

ID và Mật khẩu để login mặc định là admin, admin

1
2
const char* update_username = "admin";
const char* update_password = "admin";
Chương trình OTA WebBrowser

Thực hiện nạp chương trình và debug thông qua COM ta sẽ có thông báo

Mở đường dẫn http://esp8266-webupdate.local/firmware để vào giao diện nạp firmware, hoặc http://dia_chi_ip/firmware , như trường hợp của mình là http://192.168.1.104/firmware

Chọn browse và chọn firmware Blink.ino.bin mình đã đưa ở trên, sau khi nạp xong bạn sẽ thấy kit NodeMCU tự động Blink LED

 

OTA qua HTTP Server

Với chương trình này ta có thể cập nhật và tải firmware từ một server HTTP, yêu cầu cần có là địa chỉ IP hoặc địa chỉ domain chứa firmware

Có 2 đoạn cần lưu ý thay cho đúng

1
2
3
WiFiMulti.addAP("ten_wifi", "password");//Thay ten_wifi và password
// Bạn cần thay abc.xyz bằng địa chỉ web chứa fw của bạn và ABC là fw tương ứng
t_httpUpdate_return ret = ESPhttpUpdate.update("http://abc.xyz/ABC.ino.bin");
Chương trình OTA HTTP Server

Ở đây mình sẽ up firmware blink LED lên server. Sau đó nạp chương trình xuống ESP8266, nếu thành công bạn sẽ thấy LED blink, dưới đây là log chương trình khi nạp firmware từ xa.

Lưu ý 3:

 

Firmware up mới phải khác firmware hiện có trên ESP thì mới thành công, nếu cố ý để 2 firmware giống nhau thì sẽ bị báo FAILED

Cần phải có server riêng với địa chỉ IP/ domain để chứa firmware mới, chỉ update được với server http, chưa sử dụng được với server https

 

Tạm kết

Vậy là mình đã trình bày qua 3 cách để các bạn có thể cập nhật được firmware từ xa, bỏ qua được dây nhợ kết nối rắc rối. Nhưng đây chỉ mới là mức cơ bản, còn lại phụ thuộc vào từng ứng dụng cụ thể mà các bạn có thể áp dụng. Hi vọng nó giúp các bạn trong bước đầu tìm hiểu nhanh chóng, có cơ sở để tiếp tục tìm kiếm và áp dụng thêm.

Chia sẻ: Nguyễn Tuấn Khiêm (Nguồn: hocarm)