Commit 08d781cf authored by tanapoom's avatar tanapoom

project

parent 93130228
Pipeline #976 failed with stages
## Core latex/pdflatex auxiliary files:
*.aux
*.lof
*.log
*.lot
*.fls
*.out
*.toc
*.fmt
*.fot
*.cb
*.cb2
.*.lb
## Intermediate documents:
*.dvi
*.xdv
*-converted-to.*
# these rules might exclude image files for figures etc.
# *.ps
# *.eps
# *.pdf
## Generated if empty string is given at "Please type another file name for output:"
.pdf
## Bibliography auxiliary files (bibtex/biblatex/biber):
*.bbl
*.bcf
*.blg
*-blx.aux
*-blx.bib
*.run.xml
## Build tool auxiliary files:
*.fdb_latexmk
*.synctex
*.synctex(busy)
*.synctex.gz
*.synctex.gz(busy)
*.pdfsync
## Build tool directories for auxiliary files
# latexrun
latex.out/
## Auxiliary and intermediate files from other packages:
# algorithms
*.alg
*.loa
# achemso
acs-*.bib
# amsthm
*.thm
# beamer
*.nav
*.pre
*.snm
*.vrb
# changes
*.soc
# comment
*.cut
# cprotect
*.cpt
# elsarticle (documentclass of Elsevier journals)
*.spl
# endnotes
*.ent
# fixme
*.lox
# feynmf/feynmp
*.mf
*.mp
*.t[1-9]
*.t[1-9][0-9]
*.tfm
#(r)(e)ledmac/(r)(e)ledpar
*.end
*.?end
*.[1-9]
*.[1-9][0-9]
*.[1-9][0-9][0-9]
*.[1-9]R
*.[1-9][0-9]R
*.[1-9][0-9][0-9]R
*.eledsec[1-9]
*.eledsec[1-9]R
*.eledsec[1-9][0-9]
*.eledsec[1-9][0-9]R
*.eledsec[1-9][0-9][0-9]
*.eledsec[1-9][0-9][0-9]R
# glossaries
*.acn
*.acr
*.glg
*.glo
*.gls
*.glsdefs
# gnuplottex
*-gnuplottex-*
# gregoriotex
*.gaux
*.gtex
# htlatex
*.4ct
*.4tc
*.idv
*.lg
*.trc
*.xref
# hyperref
*.brf
# knitr
*-concordance.tex
# TODO Comment the next line if you want to keep your tikz graphics files
*.tikz
*-tikzDictionary
# listings
*.lol
# makeidx
*.idx
*.ilg
*.ind
*.ist
# minitoc
*.maf
*.mlf
*.mlt
*.mtc[0-9]*
*.slf[0-9]*
*.slt[0-9]*
*.stc[0-9]*
# minted
_minted*
*.pyg
# morewrites
*.mw
# nomencl
*.nlg
*.nlo
*.nls
# pax
*.pax
# pdfpcnotes
*.pdfpc
# sagetex
*.sagetex.sage
*.sagetex.py
*.sagetex.scmd
# scrwfile
*.wrt
# sympy
*.sout
*.sympy
sympy-plots-for-*.tex/
# pdfcomment
*.upa
*.upb
# pythontex
*.pytxcode
pythontex-files-*/
# tcolorbox
*.listing
# thmtools
*.loe
# TikZ & PGF
*.dpth
*.md5
*.auxlock
# todonotes
*.tdo
# vhistory
*.hst
*.ver
# easy-todo
*.lod
# xcolor
*.xcp
# xmpincl
*.xmpi
# xindy
*.xdy
# xypic precompiled matrices
*.xyc
# endfloat
*.ttt
*.fff
# Latexian
TSWLatexianTemp*
## Editors:
# WinEdt
*.bak
*.sav
# Texpad
.texpadtmp
# LyX
*.lyx~
# Kile
*.backup
# KBibTeX
*~[0-9]*
# auto folder when using emacs and auctex
./auto/*
*.el
# expex forward references with \gathertags
*-tags.tex
# standalone packages
*.sta
\chapter{บทนำ}
\section{ที่มาและเหตุผล }
คนไทยในปัจจุบันนิยมท่องเที่ยวด้วยตนเองมากขึ้น เห็นได้จากจำนวนบทความที่เขียนเผยแพร่ทางสื่อออนไลน์ เช่น เว็บไซต์พันทิป บล็อกหรือเฟซบุ๊ก เป็นต้น นักท่องเที่ยวเหล่านี้ส่วนใหญ่นิยมไปเที่ยวต่างจังหวัด แต่การเดินทางไปเที่ยวต่างจังหวัด นักท่องเที่ยวบางส่วนอาจยังไม่รู้จักสถานที่ท่องเที่ยวในจังหวัดนั้นมากนัก และยังไม่ค่อยรู้เส้นทาง ทำให้นักท่องเที่ยวประสบปัญหาในการวางแผนว่าควรไปสถานที่ไหนก่อน
ซึ่งในปัจจุบันก็มีแอปพลิเคชันที่ใช้ในการดูเส้นทางอยู่มากมาย เช่น google map แต่แอปพลิเคชั่นเหล่านั้นยังไม่ได้อำนวยความสะดวกให้กับนักท่องเที่ยวเท่าที่ควร เนื่องจากการเรียงลำดับสถานที่ของ google map จะเรียงลำดับตามสถานที่ที่ผู้ใช้งานเพิ่มเข้ามา ซึ่งอาจทำให้มีระยะทางที่มาก
ดังนั้น การพัฒนาซอฟต์แวร์ที่ช่วยอำนวยความสะดวกในการแนะนำสถานที่ท่องเที่ยวและวางแผนการเดินทางให้นักท่องเที่ยวจึงเป็นประโยชน์อย่างมาก
\section{วัตถุประสงค์}
\begin{enumerate}
\item เพื่อแสดงสถานที่ท่องเที่ยวต่างๆ ให้กับนักท่องเที่ยว
\item เพื่อบอกลำดับการเดินทางให้กับนักท่องเที่ยว
\end{enumerate}
\section{ขอบเขตของโครงงาน}
\begin{enumerate}
\item สามารถแสดงตำแหน่งแหล่งท่องเที่ยวได้
\item แสดงสถานที่ท่องเที่ยวในจังหวัดอุบลราชธานี,ยโสธร
\item ผู้ใช้สามารถค้นหาสถานที่ท่องเที่ยวจากจังหวัดที่สนใจได้
\item มีการแสดงเส้นทางจากจุดที่ผู้ใช้อยู่ไปยังจุดหมาย
\item แสดงลำดับการเดินทางให้นักท่องเที่ยวได้
\end{enumerate}
\section{ประโยชน์ที่คาดว่าจะได้รับ}
\begin{enumerate}
\item ทำให้นักท่องเที่ยวรู้เส้นทางการเดินทาง
\item พื่อลดระยะเวลาในการเดินทาง
\end{enumerate}
\section{เครื่องมือที่ใช้ในการพัฒนา (Development tools)}
\subsection{ฮาร์ดเเวร์}
\begin{enumerate}
\item เครื่องคอมพิวเตอร์ส่วนบุคคล (Personal computer)
\begin{itemize}
\item ทำงานบนระบบปฏิบัติการ Windows 10
\item หน่วยประมวลผลกลาง (CPU) ความเร็ว 1.8 GHz
\item หน่วยความจำหลัก 4 กิกะไบต์ (Gigabyte, GB)
\end{itemize}
\end{enumerate}
\subsection{ซอฟต์แวร์ (Software)}
\begin{enumerate}
\item visual studio code เป็น IDE Tools
\item google map api ใช้สำหรับเรียกใช้แผนที่
\item distance matrix api ใช้สำหรับหาระยะทาง
\item Laravel ซึ่งเป็น Frontend Framework สำหรับพัฒนาเว็บไชต์
\end{enumerate}
\newpage
\subsection{แผนการดำเนินการ}
%\begin{landscape}
%\sffamily
\begin{table}[H]
\noindent
\caption{ขั้นตอนการดำเนินงาน}
\begin{ganttchart}[
canvas/.append style={fill=none, draw=black!5, line width=.75pt},
vgrid={*2{draw=black!7, line width=.75pt}},
title label font=\bfseries\footnotesize,
bar label node/.append style={
align=left,
text width=width("7. Functional Testing On")},
bar/.append style={draw=none, fill=black!63}
]{1}{20}
\gantttitle{2562}{10}
\gantttitle{2563}{10}\\
\gantttitle{ส.ค.}{2}
\gantttitle{ก.ย.}{2}
\gantttitle{ต.ค.}{2}
\gantttitle{พ.ย.}{2}
\gantttitle{ธ.ค.}{2}
\gantttitle{ม.ค.}{2}
\gantttitle{ก.พ.}{2}
\gantttitle{มี.ค.}{2}
\gantttitle{เม.ย.}{2}
\gantttitle{พ.ค.}{2} \\
\ganttbar{1.ศึกษาข้อมูล}{1}{10} \\
\ganttbar{2.วิเคราะห์และออกแบบระบบ}{5}{14} \\
\ganttbar{3.เขียนโปรแกรม}{5}{18} \\
\ganttbar{4.ทดสอบและแก้ไขปัญหา}{17}{20} \\
\ganttbar{5.จัดทำเอกสาร}{20}{20} \\
\end{ganttchart}
\label{tab:ganttchart}
\end{table}
%\end{landscape}
%TODO แก้เทมเพลตเอาชื่อตารางไว้ด้านบน
\chapter{ทฤษฎีที่เกี่ยวข้อง}
ในการจัดทำโครงงานคอมพิวเตอร์ในครั้งนี้ ผู้จัดทำโครงงานได้ศึกษาเอกสารและจากเว็บไชต์ต่างๆ ที่เกี่ยวข้องดังต่อไปนี้
\section{ความรู้พื้นฐาน PHP}
\subsection{คุณสมบัติของภาษา PHP}
ภาษา PHP \cite{bib1} ที่ลักษณะเป็นแบบ Server Side Script คือจะอ่านโค้ด และทำงานที่เซิร์ฟเวอร์ จากนั้นจะส่งผลลัพธ์ที่ได้จากการประมวลผลกลับมาที่เครื่องของผู้ใช้ในรูปแบบของ HTML ซึ่งโค้ด PHP จะไม่สามารถมองเห็นได้
PHP สามารถทำงานร่วมกับระบบจัดการฐานข้อมูลที่หลากหลาย เช่น Oracle, MySQL เป็นต้น
\subsection{โครงสร้างของภาษา PHP}
ในภาษา PHP จะใช้เครื่องหมาย semicolon (;) ในการจบการทำงานของแต่ละคำสั่งเช่นเดียวกับภาษา C, C++ หรือ Java ภาษา PHP สามารถเขียนร่วมกับคำสั่ง Tag ของ HTML ได้ ตัวอย่างเช่น
\begin{figure}[H]
{\setstretch{1.0}\begin{lstlisting}
<html>
<head>
</head>
<body>
<?php
echo"Hi";
?>
</body>
</html>
\end{lstlisting}}
\caption{การจบการทำงานในแต่ละคำสั่งของภาษา PHP}
\label{Fig:Php}
\end{figure}
จากตัวอย่างในรูปที่ \ref{Fig:Php} บรรทัดที่ 5 – 7 เป็นส่วนของภาษา PHP ซึ่งเขียนเริ่มต้นด้วย <?php ตามด้วยคำสั่ง และปิดด้วย ?> คำสั่ง echo จะใช้สำหรับแสดงข้อความ ภาษาPHPสามารถเปิดและปิดด้วย Tag ของ PHP ได้หลายครั้งดังตัวอย่างในรูป \ref{Fig:Tagphp}
\begin{figure}[H]
{\setstretch{1.0}\begin{lstlisting}
<html>
<head>
</head>
<body>
<?php
echo"Hi";
?>
<?php
echo"Hi";
?>
</body>
</html>
\end{lstlisting}}
\caption{การสร้างTag PHP}
\label{Fig:Tagphp}
\end{figure}
\subsection{ตัวแปร}
การประกาศตัวแปรในภาษา PHP ไม่ต้องกำหนดประเภทของตัวแปร ซึ่งตัวแปรจะขึ้นต้นด้วยเครื่องหมาย Dollar sign (\$) และตามด้วยชื่อตัวแปร ชื่อตัวแปรไม่สามารถขึ้นต้นด้วยตัวเลขได้
\subsection{Srting}
การประกาศตัวแปร string สามารถทำได้ 2 แบบโดยการใช้ Double quote ("") หรือ Single quote ('') ซึ่งจะให้ผลลัพธ์แตกต่างกัน การใช้ Double quote จะทำให้สามารถแทรกตัวแปรใน string ได้ แต่การประกาศแบบ Single quote จะแสดงผลลัพธ์ของ string ตามที่ได้ประกาศไว้ในตัวแปร
การต่อ string คือการนำ string มาต่อรวมกันและได้ผลลัพธ์ใหม่ ในภาษา PHP จะใช้เครื่องหมาย Dot (.) ในการต่อ string เข้าด้วยกัน ดังตัวอย่างในรูป \ref{Fig:string}
\begin{figure}[H]
{\setstretch{1.0}\begin{lstlisting}
$firstname = "Samu";
$lastname = "Rai";
$fullname = $firstname.$lastname;
\end{lstlisting}}
\caption{การต่อ String}
\label{Fig:string}
\end{figure}
\section{ความรู้พื้นฐาน Laravel Framework}
Laravel Framework \cite{bib2} เป็น PHP Framework สำหรับการพัฒนาเว็บแอปพลิเคชัน ถูกพัฒนาโดย Taylor Otwell และทีมงาน Laravel Framework เป็น open-source framework ทำให้นักพัฒนานำไปใช้ได้อย่างเสรี ทั้งในทางการค้าและไม่ใช่ทางการค้า
\subsection{การติดตั้ง Laravel}
\begin{enumerate}
\item ลง composer เพื่อใช้ในการติดตั้ง Laravel Framework
\item เปิด command line เพื่อติดตั้ง Laravel Framework โดยใช้คำสั่ง composer create-project --prefer-dist laravel/laravel blog
\item หลังจากติดตั้งเรียบร้อยแล้วให้เปิดเข้าไปใน Folder และทำการ Run โดยใช้คำสั่ง php artisan serve
\end{enumerate}
\subsection{โครงสร้างของ Laravel}
\begin{enumerate}
\item app เป็นโฟลเดอร์ที่ใช้เก็บไฟล์จำพวก Model หรือ Controller ที่ใช้ในการประมวลผลและติดต่อกับฐานข้อมูล
\item database เป็นโฟลเดอร์ที่ใช้เก็บไฟล์จำพวก Migrations และ Seeding เพื่อใช้ในการสร้าง Table หรือใส่ข้อมูลในฐานข้อมูลผ่านคำสั่ง “artisan” ของ laravel
\item resources ใช้เก็บโฟลเดอร์ที่ใช้ในส่วนของการแสดงผลต่างๆ
\item routes เป็นส่วนที่ใช้เก็บไฟล์ในการกำหนด Url ของ web
\item storage เป็นส่วนของคลังพื้นที่จัดเก็บข้อมูลตระกูล Session, caches หรือไฟล์ที่ถูกทาง blade engine ทำการ compiled มาแล้ว
\item ไฟล์ .env เป็นไฟล์ที่ใช้ config laravel กับ ฐานข้อมูล
\end{enumerate}
\subsection{view}
View คือส่วนที่ใช้สำหรับแสดงผลของเว็บ โดยใช้ HTML ในการจัดการส่วนนี้ ซึ่งจะถูกเก็บไว้ใน resources/views สามารถใช้ไฟล์ที่เป็นนามสกุล .html .php และ.blade.php ซึ่งการใช้งาน .blade.php จะเป็นการใช้งาน laravel blade template
\subsubsection{blade template}
การใช้งาน blade template \cite{bib5} จะต้องตั้งชื่อไฟล์ที่มีนามสกุลเป็น .blade.php การใช้งาน blade template จะทำให้โค้ดดูอ่านง่ายขึ้น ทำให้นักพัฒนาสะดวกยิ่งขึ้น ใน blade template จะใช้เครื่องหมาย {{ }} ครอบตัวแปร จะเหมือนกับคำสั่ง echo ตัวอย่างเช่น {{\$name}} จะเป็นการเอาค่า \$name ออกมาแสดง
\subsection{Controller}
Controller ทำหน้าที่เป็นส่วนจัดการการทำงานของระบบ โดยการสร้าง Controller จะใช้คำสั่ง php artisan make:controller BlogController ไฟล์ Controller ที่สร้างจะอยู่ที่ app/Http/Controllers ตัวอย่าง Code ใน Controller
\begin{figure}[H]
{\setstretch{1.0}\begin{lstlisting}
<?php
namespace App\Http\Controller;
use Iluminate\Http\Request;
Class BlogController extends Controller{
Public function index(){
echo ‘Hello’;
}
}
\end{lstlisting}}
\caption{Controller}
\label{Fig:controller}
\end{figure}
จากตัวอย่างในรูป \ref{Fig:controller} ถ้าทำการเรียกใช้ BlogController และ function index() จะทำการแสดงผลลัพธ์ว่า Hello โดยการเรียกใช้งานจะกำหนดอยู่ที่ Route
\subsection{Route}
Route เป็นการกำหนดเส้นทางให้กับเว็บว่าให้ไปทำงานที่ controller หรือ แสดงที่ view และยังสามารถส่งพารามิเตอร์ผ่าน Route ได้ ไฟล์ที่ใช้กำหนด Route จะอยู่ใน routes/web.php ตัวอย่างของการกำหนด Route
\begin{figure}[H]
{\setstretch{1.0}\begin{lstlisting}
Route::get('/', function(){
return view('welcome');
})
\end{lstlisting}}
\caption{การกำหนด Route}
\label{Fig:route1}
\end{figure}
จากตัวอย่างในรูป \ref{Fig:route1} หมายความว่าเมื่อเปิดหน้าแรกขึ้นมาจะแสดง view welcome
\begin{figure}[H]
{\setstretch{1.0}\begin{lstlisting}
Route::get('/', 'BlogController@index')
\end{lstlisting}}
\caption{การเรียกใช้งาน Controller ผ่าน Route}
\label{Fig:route2}
\end{figure}
จากตัวอย่างในรูป \ref{Fig:route2}จะเป็นการเรียกใช้ Controller ชื่อ BlogController และ Function index() ให้ทำงาน
\begin{figure}[H]
{\setstretch{1.0}\begin{lstlisting}
Route::get('product/{id}', 'BlogController@test')
\end{lstlisting}}
\caption{การส่งพารามิเตอร์ผ่าน Route}
\label{Fig:route3}
\end{figure}
จากตัวอย่างในรูป \ref{Fig:route3} จะเป็นการส่งพารามิเตอร์ {id} ไปด้วย โดยพารามิเตอร์ต้องคลุมด้วยเครื่องหมาย {} เสมอ
\subsection{Model}
Model จะทำหน้าที่สำหรับดึงข้อมูลจากตารางของฐานข้อมูลมาใช้งาน โดยไม่จำเป็นต้องเขียนคำสั่ง SQL โดยปกติชื่อของ Model จะดึงข้อมูลและจัดเก็บข้อมูลจากตารางชื่อเดียวกัน ยกตัวอย่างการสร้าง Model ชื่อ Product จะใช้คำสั่งดังแสดงในรูปที่ \ref{Fig:model}
\begin{figure}[H]
{\setstretch{1.0}\begin{lstlisting}
php artisan make:model Product
\end{lstlisting}}
\caption{การสร้าง model}
\label{Fig:model}
\end{figure}
การสร้างข้อมูลหรือการดึงข้อมูลจากตาราง ต้องทำการกำหนดการเข้าถึงของ column ในตารางก่อน โดยการกำหนดการเข้าถึงจะใช้ fillable หรือ guarded ตัวอย่างการใช้งาน
\begin{enumerate}
\item Fillable คือการกำหนดชื่อของ column ที่ต้องการอนุญาตให้เข้าถึง protected \$fillable = ['name'];
\item Guarded คือการกำหนดชื่อของ column ที่ไม่อนุญาตให้เข้าถึง protected \$guarded = ['name'];
protected \$guarded = [];
การกำหนด guarded เป็นค่าว่างจะหมายถึง column ทุก column สามารถเข้าถึงได้
\end{enumerate}
การ query ข้อมูลจาก Model สามารถ query ข้อมูลได้ทั้งใน Route และ Controller โดยจะต้องทำการ use Model ก่อน ตัวอย่างการ query ข้อมูลใน Controller
\begin{figure}[H]
{\setstretch{1.0}\begin{lstlisting}
<?php
use App\Flight;
$flights = Flight::all();
foreach ($flights as $flight) {
echo $flight->name;
}
$flights = Flight::where('id', 1)->get();
\end{lstlisting}}
\caption{การ query ข้อมูลจาก Model}
\label{Fig:model2}
\end{figure}
จากตัวอย่างในรูป \ref{Fig:model2} \$flights = Flight::all(); จะเป็นการดึงข้อมูลทั้งหมดมาเก็บไว้ในตัวแปร \$flights ส่วนคำสั่ง \$flights = Flight::where('id', 1)
->get(); จะเป็นการดึงข้อมูลที่มีค่า id เท่ากับ 1 มาเก็บในตัวแปร \$flights
\section{Guzzle}
Guzzle \cite{bib3} เป็น HTTP Client ที่ใช้สำหรับส่ง HTTP requests และเชื่อมต่อกับ Web services เพื่อแลกเปลี่ยนข้อมูลได้ Guzzle ทำงานได้กับ PHP 5.5.0 ขึ้นไป การติดตั้ง Guzzle จะติดตั้งผ่าน composer โดยใช้คำสั่ง composer require guzzlehttp/guzzle
\subsection{การใช้งาน Guzzle}
การใช้งาน Guzzle จะต้องทำการ use ตัว Guzzle ก่อนโดยต้องประกาศไว้ที่ด้านบนจากนั้นทำการ new Client() และส่ง request ผ่าน method request ดังนี้
\begin{figure}[H]
{\setstretch{1.0}\begin{lstlisting}
<?php
namespace App;
use GuzzleHttp\Client;
$client = new Client();
$response = $client->request($method, $url, $options)
\end{lstlisting}}
\caption{การใช้งาน Guzzle}
\label{Fig:guzzle}
\end{figure}
\begin{enumerate}
\item \$method คือ HTTP Method ได้แก่ GET,POST,PUT,DELETE
\item \$url คือ url ที่จะทำการ request
\item \$options เป็น Array สำหรับเก็บ option ต่างๆ เช่น Header และAuthentication เป็นต้น
\end{enumerate}
ตัวอย่างการ GET ค่าจาก URL https://maps.googleapis.com/maps/api
\begin{figure}[H]
{\setstretch{1.0}\begin{lstlisting}
<?php
namespace App;
use GuzzleHttp\Client;
$client = new Client();
$response =
$client->request(‘GET’,’https://maps.googleapis.com/maps/api’);
echo $response->getBody();
\end{lstlisting}}
\caption{ตัวอย่างการใช้งาน Method GET}
\label{Fig:guzzle2}
\end{figure}
การส่ง headers ใน Guzzle จะต้องเขียนใน Array ดังตัวอย่างในรูป \ref{Fig:guzzle3}
\begin{figure}[H]
{\setstretch{1.0}\begin{lstlisting}
<?php
namespace App;
use GuzzleHttp\Client;
$client = new Client();
$response =
$client->request(‘GET’,’https://maps.googleapis.com/maps/api’,
[
‘headers’=>[
‘key’ => ‘f40asd5
]
]
);
echo $response->getBody();
\end{lstlisting}}
\caption{ตัวอย่างการใช้งาน headers}
\label{Fig:guzzle3}
\end{figure}
\section{Distance Matrix API}
Distance Martrix API \cite{bib4} เป็นหนึ่งในบริการ Web Service ของ google map โดย Distance Martrix API มีความสามารถในการคำนวณระยะทางจากสถานที่ต้นทางไปยังสถานที่ปลายทางและสามารถกำหนดปลายทางได้หลายตำแหน่ง ข้อมูลที่ได้รับกลับจาก Web Service จะอยู่ในรูปแบบ JSON หรือ XML ระบบเว็บไซต์หรือแอปพลิเคชันสามารถนำข้อมูลเหล่านี้ไปแสดงผลหรือประยุกต์ใช้ต่อได้ การใช้งาน Distance Matrix API ต้องส่งคำขอเป็น URL string โดยมีแบบฟอร์มดังในรูปที่ \ref{Fig:api}
\begin{figure}[H]
{\setstretch{1.0}\begin{lstlisting}
https://maps.googleapis.com/maps/api/distancematrix/outputFormat?parameters
\end{lstlisting}}
\caption{ตัวอย่าง URL ที่เรียกใช้งาน Distance Matrix API }
\label{Fig:api}
\end{figure}
outputFormat สามารถเลือกค่าได้ดังต่อไปนี้
\begin{enumerate}
\item json ตัวอย่างผลลัพธ์ที่ถูกส่งกลับมา
\begin{figure}[H]
{\setstretch{1.0}\begin{lstlisting}
{
"status": "OK",
"origin_addresses": [
"Vancouver, BC, Canada"
],
"destination_addresses": [
"Victoria, BC, Canada"
],
"rows": [
{
"elements": [
{
"status": "OK",
"duration": {
"value": 24487,
"text": "6 heures 48 minutes"
},
"distance": {
"value": 129324,
"text": "129 km"
}
}
]
}
]
}
\end{lstlisting}}
\caption{ตัวอย่างผลลัพธ์ในรูปแบบ json}
\label{Fig:api2}
\end{figure}
\item xml ตัวอย่างผลลัพธ์ที่ถูกส่งกลับมา
\begin{figure}[H]
{\setstretch{1.0}\begin{lstlisting}
{
"status": "OK",
"origin_addresses": [
"Vancouver, BC, Canada"
],
"destination_addresses": [
"Victoria, BC, Canada"
],
"rows": [
{
"elements": [
{
"status": "OK",
"duration": {
"value": 24487,
"text": "6 heures 48 minutes"
},
"distance": {
"value": 129324,
"text": "129 km"
}
}
]
}
]
}
\end{lstlisting}}
\caption{ตัวอย่างผลลัพธ์ในรูปแบบ xml}
\label{Fig:api3}
\end{figure}
\end{enumerate}
parameters พารามิเตอร์แต่ละตัวจะถูกคั่นด้วยเครื่องหมาย ‘\&’ โดยมีพารามิเตอร์ที่จำเป็นดังต่อไปนี้
\begin{enumerate}
\item origins คือจุดเริ่มต้นสำหรับคำนวณระยะทางโดยสามารถใส่ในรูปแบบของที่อยู่พิกัดละติจูดและลองจิจูด ที่อยู่ หรือรหัสสถานที่ โดยใช้เครื่องหมาย | คั่นกรณีมีหลายตำแหน่ง เช่น
origins=41.43206,-81.38992|-33.86748,151.20699
\item destinations คือจุดปลายทางสำหรับการคำนวณโดยสามารถใส่ในรูปแบบของที่อยู่พิกัดละติจูดและลองจิจูด ที่อยู่ หรือรหัสสถานที่ โดยใช้เครื่องหมาย | คั่นกรณีมีหลายตำแหน่ง เช่น
destinations= San+Francisco|Vancouver+BC
\item key คือรหัส API ที่ได้ทำการขอใช้งานจาก google
\end{enumerate}
\section{การหาลำดับการเดินทาง}
การหาลำดับการเดินทางของระบบท่องเที่ยวอีสาน จะจัดลำดับโดยการเลือกสถานที่ที่อยู่ใกล้กับตำแหน่งปัจจุบันของผู้ใช้งาน ตัวอย่างเช่น ผู้ใช้งานต้องการไป ธาตุก่องข้าวน้อย ศาลเจ้าพ่อหลักเมือง และวิมานพญาแถน ซึ่งจากตำแหน่งปัจจุบันไปธาตุก่องข้าวน้อย 20กม. ตำแหน่งปัจจุบันไปศาลเจ้าพ่อหลักเมือง 13กม. และตำแหน่งปัจจุบันไปวิมานพญาแถน 14กม. ระบบจะทำการเลือกไปศาลเจ้าพ่อหลักเมืองก่อน จากนั้นจะดูว่าจากศาลเจ้าพ่อหลักเมืองใกล้สถานที่ใดก็จะเลือกสถานที่นั้นต่อไป ในตัวอย่างนี้จะทำการเลือกวิมานพญาแถนและธาตุก่องข้าวน้อยตามลำดับ
\begin{figure}[H]
\centering
\includegraphics[width=\textwidth]{Figures/2/1}
\caption{ตัวอย่างลำดับการเดินทางที่ได้จากระบบ}
\label{Fig:result1}
\end{figure}
\begin{figure}[H]
\centering
\includegraphics[width=\textwidth]{Figures/2/2}
\caption{ตัวอย่างลำดับการเดินทางที่เรียงลำดับตามสถานที่ที่เลือก}
\label{Fig:result2}
\end{figure}
\section{เอกสารและงานวิจัยที่เกี่ยวข้อง}
\subsection{Google Maps}
Google Maps เป็นเว็บไซต์ที่สามารถแสดงเส้นทางการเดินทาง โดยผู้ใช้งานสามารถเลือกสถานที่ที่ต้องการไปได้ สามารถเข้าใช้งานได้ทาง https://www.google.co.th/maps
\begin{enumerate}
\begin{figure}[H]
\centering
\includegraphics[width=14cm]{Figures/2/googlemap}
\caption{หน้าแรกของ Google Maps}{ที่มา : https://www.google.co.th/maps}
\label{Fig:googlemap}
\end{figure}
\end{enumerate}
\subsection{Thailand Tourism Directory}
Thailand Tourism Directory เป็นเว็บไซต์ค้นหาสถานที่ท่องเที่ยว ร้านอาหาร ที่พัก ในประเทศไทย สามารถเข้าใช้งาน
ได้ทาง https://thailandtourismdirectory.go.th/th/home
\begin{enumerate}
\begin{figure}[H]
\centering
\includegraphics[width=14cm]{Figures/2/tourism}
\caption{หน้าแรกของ Thailand Tourism Directory}{ที่มา : https://thailandtourismdirectory.go.th/th/home}
\label{Fig:tourism}
\end{figure}
\end{enumerate}
\ No newline at end of file
\chapter{การวิเคราะห์และออกแบบระบบ}
การวิเคราะห์และออกแบบระบบก่อนดำเนินการจริงเป็นอีกหนึ่งขั้นตอนที่มีความสำคัญ เพราะการวิเคราะห์และออกแบบระบบนั้นเป็นการกระทำที่ทำให้ผู้พัฒนาเห็นรายละเอียดส่วนย่อยของงานทั้งหมด เพิ่มประสิทธิภาพในการวางแผน การทำงาน และยังช่วยลดปัญหาที่อาจจะเกิดขึ้นในระหว่างพัฒนา เพื่อให้ระบบมีความสมบูรณ์มากยิ่งขึ้น ในบทนี้จะแบ่งออกเป็น 3 ขั้นตอนเพื่อให้เห็นการดำเนินงานอย่างมีระบบ
\begin{enumerate}[label=3.\arabic*]
\item usecase diagram
\item context diagram
\item data flow diagram level 0
\item Entity Relationship Diagrams
\item Sequence Diagrams
\end{enumerate}
\section{usecase diagram}
\begin{figure}[H]
\centering
\includegraphics[width=\textwidth]{Figures/my3/Untitled Diagram-usecase}
\caption{usecase diagram ของระบบท่องเที่ยวอีสาน}
\label{Fig:usecase}
\end{figure}
\begin{table}[H]
\centering
\caption{อธิบาย Use Case หน้าที่ของระบบ ในภาพที่ \ref{Fig:usecase}}
\label{tab:usecase}
\resizebox{\totalheight}{!}{\textwidth}{%
\begin{tabular}{|c|p{10cm}|}
\hline
\multicolumn{1}{|c|}{\textbf{Use Case}} & \multicolumn{1}{c|}{\textbf{คำอธิบาย}} \\ \hline
ค้นหาสถานที่ท่องเที่ยว & ผู้ใช้งานสามารถค้นหาสถานที่ท่องเที่ยวได้โดยการเลือกจากชื่อจังหวัด \\ \hline
เลือกสถานที่ & ผู้ใช้งานเลือกสถานที่ท่องเที่ยวที่สนใจ \\ \hline
ดูลำดับการเดินทาง & ผู้ใช้งานสามารถดูลำดับการเดินทางไปยังสถานที่ท่องเที่ยวที่เลือกได้ \\ \hline
ดูรายละเอียดของสถานที่ & ผู้ใช้งานสามารถดูรายละเอียดของสถานที่ท่องเที่ยว และตำแหน่งของสถานที่ท่องเที่ยว \\ \hline
เข้าสู่ระบบ & admin ทำการเข้าสู่ระบบก่อน เพื่อที่จะจัดการข้อมูลสถานที่ท่องเที่ยว \\ \hline
เพิ่ม/ลบ จังหวัด & admin สามารถเพิ่มและลบข้อมูลจังหวัด\\ \hline
เพิ่ม/ลบ/แก้ไข & admin สามารถเพิ่ม แก้ไขและลบ ข้อมูลสถานที่ท่องเที่ยว\\ \hline
\end{tabular}%
}
\end{table}
\section{context diagram}
Context diagram เป็น diagram ที่แสดงถึงขอบเขตของระบบงาน โดยไม่แสดงสัญลักษณ์แหล่งจัดเก็บข้อมูล ทำให้สามารถเห็นภาพรวมของระบบ และขอบเขตการวิเคราะห์ระบบ
\begin{figure}[H]
\centering
\includegraphics[width=\textwidth]{Figures/my3/Untitled Diagram-Context }
\caption{context diagram ของระบบท่องเที่ยวอีสาน}
\label{Fig:context}
\end{figure}
จากรูปที่ \ref{Fig:context} มีส่วนที่เกี่ยวข้อง 3 ส่วน คือ ผู้ใช้ทั่วไป ผู้ดูแลระบบ และgoogle map/distance martrix api
\section{data flow diagram level 0}
DFD 0 หรือ data flow diagram level 0 เป็นแผนภาพแสดงการไหลของข้อมูลของระบบ เพื่อแสดงวิธีการไหลของข้อมูลจากกระบวนการหนึ่งไปอีกกระบวนการหนึ่ง
\begin{figure}[H]
\centering
\includegraphics[width=\textwidth]{Figures/my3/Untitled Diagram-DFD 0}
\caption{data flow diagram level 0 ของระบบท่องเที่ยวอีสาน}
\label{Fig:dfd}
\end{figure}
\begin{table}[H]
\centering
\caption{Process description ค้นหาสถานที่ท่องเที่ยว}
\label{my-label1}
\begin{tabular}{|c p{10cm}|}
\hline
Process name : & ค้นหาสถานที่ท่องเที่ยว \\\hline
Input Data Flows : & ชื่อจังหวัด \\\hline
Output Data Flows :& ข้อมูลสถานที่ท่องเที่ยว \\\hline
Data Stored used :& สถานที่ท่องเที่ยว \\\hline
Description :& เป็นกระบวนการค้นหาสถานที่ท่องเที่ยวจากจังหวัดที่ผู้ใช้สนใจ\\
\hline
\end{tabular}
\end{table}
\begin{table}[H]
\centering
\caption{Process description แสดงรายละเอียดสถานที่ท่องเที่ยว}
\label{my-label1}
\begin{tabular}{|c p{10cm}|}
\hline
Process name : & แสดงรายละเอียดสถานที่ท่องเที่ยว \\\hline
Input Data Flows : & ชื่อสถานที่ท่องเที่ยว \\\hline
Output Data Flows :& ข้อมูลสถานที่ท่องเที่ยว \\\hline
Data Stored used :& สถานที่ท่องเที่ยว \\\hline
Description :& เมื่อผู้ใช้คลิกดูรายละเอียดสถานที่ ระบบจะส่ง ID สถานที่ท่องเที่ยวเพื่อไปค้นหาข้อมูลจาก Data Stored ที่มีID สถานที่ท่องเที่ยวเหมือนกัน \\
\hline
\end{tabular}
\end{table}
\begin{table}[H]
\centering
\caption{Process description เลือกสถานที่ท่องเที่ยว}
\label{my-label1}
\begin{tabular}{|c p{10cm}|}
\hline
Process name : & เลือกสถานที่ท่องเที่ยว \\\hline
Input Data Flows : & ชื่อสถานที่ท่องเที่ยว \\\hline
Output Data Flows :& - \\\hline
Data Stored used :& - \\\hline
Description :& เมื่อผู้ใช้ทำการเลือกสถานที่ท่องเที่ยว ระบบจะทำการเก็บ ID สถานที่ท่องเที่ยวที่เลือกไว้ใน Session \\
\hline
\end{tabular}
\end{table}
\begin{table}[H]
\centering
\caption{Process description หาลำดับการเดินทาง}
\label{my-label1}
\begin{tabular}{|c p{10cm}|}
\hline
Process name : & หาลำดับการเดินทาง \\\hline
Input Data Flows : & ID สถานที่ท่องเที่ยวที่เลือก,ระยะทาง \\\hline
Output Data Flows :& ลำดับการเดินทาง,ค่าlattitude,longitude \\\hline
Data Stored used :& สถานที่ท่องเที่ยว \\\hline
Description :& ระบบจะทำการเอาค่า ID สถานที่ท่องเที่ยวจาก Session เพื่อไปดึงข้อมูลละติจูดกับลองจิจูดไปหาระยะทางด้วย Distance Matrix API เพื่อทำการเรียงลำดับการเดินทาง และส่งให้ผู้ใช้ทั่วไป \\
\hline
\end{tabular}
\end{table}
\begin{table}[H]
\centering
\caption{Process description เพิ่ม/แก้ไขข้อมูลสถานที่ท่องเที่ยว}
\label{my-label1}
\begin{tabular}{|c p{10cm}|}
\hline
Process name : & เพิ่ม/แก้ไขข้อมูลสถานที่ท่องเที่ยว \\\hline
Input Data Flows : & ข้อมูลสถานที่ท่องเที่ยว \\\hline
Output Data Flows :& ข้อมูลสถานที่ท่องเที่ยว \\\hline
Data Stored used :& สถานที่ท่องเที่ยว \\\hline
Description :& admin ทำการกรอกข้อมูลสถานที่ท่องเที่ยวและทำการบันทึกข้อมูลลง Data Stored D1\\
\hline
\end{tabular}
\end{table}
\begin{table}[H]
\centering
\caption{Process description เพิ่มข้อมูลจังหวัด}
\label{my-label1}
\begin{tabular}{|c p{10cm}|}
\hline
Process name : & เพิ่มข้อมูลจังหวัด \\\hline
Input Data Flows : & ข้อมูลจังหวัด \\\hline
Output Data Flows :& ข้อมูลจังหวัด \\\hline
Data Stored used :& จังหวัด \\\hline
Description :& admin ทำการกรอกข้อมูลจังหวัด และทำการบันทึกลง Data Stored D2 \\
\hline
\end{tabular}
\end{table}
\begin{table}[H]
\centering
\caption{Process description ลบสถานที่ท่องเที่ยว}
\label{my-label1}
\begin{tabular}{|c p{10cm}|}
\hline
Process name : & ลบข้อมูลสถานที่ท่องเที่ยว \\\hline
Input Data Flows : & ชื่อสถานที่ท่องเที่ยว,ข้อมูลสถานที่ท่องเที่ยว \\\hline
Output Data Flows :& id สถานที่ท่องเที่ยว \\\hline
Data Stored used :& สถานที่ท่องเที่ยว \\\hline
Description :& admin ทำการเลือกสถานที่ท่องเที่ยวที่ต้องการลบ และระบบทำการส่ง id สถานที่ท่องเที่ยวเพื่อดึงข้อมูลจาก Data Stored D1 มาเพื่อทำการลบข้อมูล \\
\hline
\end{tabular}
\end{table}
\begin{table}[H]
\centering
\caption{Process description ลบข้อมูลจังหวัด}
\label{my-label1}
\begin{tabular}{|c p{10cm}|}
\hline
Process name : & ลบข้อมูลจังหวัด \\\hline
Input Data Flows : & ชื่อจังหวัด,ข้อมูลจังหวัด,ข้อมูลสถานที่ท่องเที่ยว \\\hline
Output Data Flows :& idจังหวัด \\\hline
Data Stored used :& สถานที่ท่องเที่ยว,จังหวัด \\\hline
Description :& admin ทำการเลือกจังหวัดที่ต้องการลบ ระบบจะส่งidจังหวัดนั้นเพื่อไปดึงข้อมูลสถานที่ท่องเที่ยวในจังหวัดนั้นจาก Data Stored D1 มาลบ และทำการลบข้อมูลจังหวัดใน Data Stored D2\\
\hline
\end{tabular}
\end{table}
\section{Entity Relationship Diagrams}
Entity Relationship Diagrams คือ แบบจำลองที่ใช้อธิบายโครงสร้างของฐานข้อมูลซึ่งเขียนออกมาในลักษณะของรูปภาพ การอธิบายโครงสร้างและความสัมพันธ์ของข้อมูล ประกอบด้วย
\begin{enumerate}
\item เอนทิตี้ (Entity) เป็นวัตถุ หรือสิ่งของที่เราสนใจในระบบงานนั้น ๆ
\item แอททริบิว (Attribute) เป็นคุณสมบัติของวัตถุที่เราสนใจ
\item ความสัมพันธ์ (Relationship) คือ ความสัมพันธ์ระหว่างเอนทิตี้
\end{enumerate}
Entity Relationship Diagram ของระบบอธิบายได้ตามภาพที่ดังต่อไปนี้
\begin{figure}[H]
\centering
\includegraphics[width=\textwidth]{Figures/my3/Untitled Diagram-ER}
\caption{ Entity Relationship Diagram ของระบบท่องเที่ยวอีสาน}
\label{Fig:erd}
\end{figure}
\subsection{Data dictionary}
\begin{table}[H]
\centering
\caption{ตาราง provinces}
\label{my-label1}
\begin{tabular}{|c|c|c|c|}
\hline
Attribute Name & Description & Data Type & Key Type \\ \hline
provinces\_id & รหัสจังหวัด &int &PK \\\hline
provinces\_name& ชื่อจังหวัด& varchar& \\
\hline
\end{tabular}
\end{table}
\begin{table}[H]
\centering
\caption{ตาราง attractions}
\label{my-label1}
\begin{tabular}{|c|c|c|c|}
\hline
Attribute Name & Description & Data Type & Key Type \\ \hline
provinces\_id & รหัสจังหวัด &int &FK \\\hline
attractions\_id& รหัสสถานที่ท่องเที่ยว& int& PK\\\hline
attractions\_name & ชื่อสถานที่ท่องเที่ยว& varchar& \\\hline
Latitude& ละติจูด& double& \\\hline
longitude &ลองจิจูด& double&\\\hline
description& รายละเอียด &text& \\\hline
image\_url & url รูปภาพ& varchar& \\
\hline
\end{tabular}
\end{table}
\begin{table}[H]
\centering
\caption{ตาราง admin}
\label{my-label1}
\begin{tabular}{|c|c|c|c|}
\hline
Attribute Name & Description & Data Type & Key Type \\ \hline
username&ชื่อผู้ใช้&varchar& \\\hline
password & รหัสผู้ใช้& varchar& \\
\hline
\end{tabular}
\end{table}
\section{Sequence Diagram}
Sequence Diagram เป็น Diagram ที่แสดงขั้นตอนการทำงานของแต่ละ Use Case ระหว่าง Object ต่าง ๆ ที่ส่งข้อความถึงกันและกัน โดย Sequence Diagram จะช่วยให้มองเห็นการทำงานของภาพรวมของระบบ ส่วนประกอบสัญลักษณ์ที่ใช้ในการเขียน Sequence Diagram
แสดงดังตารางที่ \ref{tab:Sequences}
\begin{table}[H]
\centering
\caption{สัญลักษณ์ของ Sequence Diagram}
\label{tab:Sequences}
\begin{tabular}{| c | p{10cm} |}
\hline
\textbf{สัญลักษณ์} & \multicolumn{1}{c|}{\textbf{การใช้งาน}} \\ \hline
\raisebox{-\totalheight}{\includegraphics[width=0.17\textwidth]{Figures/table/Sequence/Sequence1}}
& \setstretch{1.5} {Object ที่ต้องทำหน้าที่ในการส่งหรือรับข้อมูล } \\ \hline
\raisebox{-\totalheight}{\includegraphics[height=0.08\textheight]{Figures/table/Sequence/Sequence2}}
& \setstretch{1.5} {Lifeline หรือเส้นอายุขัย แสดงช่วงเวลาตั้งแต่เริ่มสร้าง object ในคลาสนั้น จนกระทั่ง object นั้นถูกทำลาย สัญลักษณ์แทนด้วยเส้นประ} \\ \hline
\raisebox{-\totalheight}{\includegraphics[height=0.08\textheight]{Figures/table/Sequence/Sequence3}}
& \setstretch{1.5} {Focus of control หรือจุดควบคุม เป็นจุดควบคุมที่ object ใช้ทำการส่งหรือรับข้อความ สัญลักษณ์แทนด้วยสี่เหลี่ยม} \\ \hline
\raisebox{-\totalheight}{\includegraphics[width=0.3\textwidth]{Figures/table/Sequence/Sequence4}}
& \setstretch{1.5} {Message คือ ข้อความที่รับส่งระหว่าง Object สัญลักษณ์แทนด้วยลูกศรและประกอบด้วย 2 ส่วน คือ ข้อมูล (Data) และฟังก์ชัน (Function)} \\ \hline
\raisebox{-\totalheight}{\includegraphics[width=0.3\textwidth]{Figures/table/Sequence/Sequence5}}
& \setstretch{1.5} {Return Message เป็นข้อมูลที่ส่งกลับหลังจากทำงานเสร็จ} \\ \hline
\raisebox{-\totalheight}{\includegraphics[height=0.08\textheight]{Figures/3/selfcall}}
& \setstretch{1.5} {Self call เป็นการเรียกฟังชันก์การทำงานภายในตัวเอง} \\ \hline
\raisebox{-\totalheight}{\includegraphics[height=0.1\textheight,width=0.3\textwidth]{Figures/3/frame}}
& \setstretch{1.5} {สร้างกรอบการทำงานของโปรแกรม เพื่อให้รู้ขอบเขตของการทำงานเช่น ลูป(loop)} \\ \hline
\end{tabular}
\end{table}
\begin{figure}[H]
\centering
\includegraphics[width=\textwidth,angle=90,scale=1.5]{Figures/my3/Untitled Diagram-sq ล็อตอิน}
\caption{Sequence Diagram เข้าสู่ระบบ}
\label{Fig:sqlogin}
\end{figure}
จากภาพที่ \ref{Fig:sqlogin} สามารถอธิบายแผนภาพ Sequence Diagram เข้าสู่ระบบ ได้ดังนี้ เมื่อ
ผู้ใช้กรอก username,password ระบบจะเรียกใช้เมธอด login() ที่ loginController ระบบจะดึงข้อมูลจาก model User เพื่อมาตรวจสอบว่า username,password ถูกต้องหรือไม่ ถ้าถูกต้องจะไปแสดงหน้า admin.blade.php ถ้าไม่ถูกต้องจะกลับไปแสดงหน้า login พร้อมแจ้งเตือนการเข้าสู่ระบบไม่สำเร็จ
\begin{figure}[H]
\centering
\includegraphics[width=\textwidth,angle=90,scale=1.5]{Figures/my3/Untitled Diagram-sq ค้นหาท่องเที่ยว}
\caption{Sequence Diagram ค้นหาสถานที่ท่องเที่ยว}
\label{Fig:sqsearch}
\end{figure}
จากภาพที่ \ref{Fig:sqsearch} สามารถอธิบายแผนภาพ Sequence Diagram ค้นหาสถานที่ท่องเที่ยว ได้ดังนี้ หน้าsearch.blade.php จะทำการดึงข้อมูลจังหวัดจากโมเดล Province มาเพื่อให้ผู้ใช้งานทำการเลือกจังหวัด เมื่อผู้ใช้งานเลือกจังหวัด จะส่งค่าที่เลือกไปยัง controller getplace จากนั้น getplace จะไปดึงข้อมูลสถานที่ท่องเที่ยวจาก model Attraction และส่งข้อมูลสถานที่ท่องเที่ยวไปยังหน้า getview.blade.php เพื่อแสดงข้อมูลสถานที่ท่องเที่ยว
\begin{figure}[H]
\centering
\includegraphics[width=\textwidth]{Figures/my3/Untitled Diagram-sq รายละเอียด}
\caption{Sequence Diagram ดูรายละเอียด}
\label{Fig:sqdetail}
\end{figure}
จากภาพที่ \ref{Fig:sqdetail} สามารถอธิบายแผนภาพ Sequence Diagram ดูรายละเอียด ได้ดังนี้ เมื่อผู้ใช้งานทำการเลือกสถานที่ท่องเที่ยวที่หน้า getview.blade.php ระบบจะทำการส่ง idสถานที่ท่องเที่ยวไปยังcontroller detail จากนั้น controller detail จะทำการไปดึงข้อมูลสถานที่ท่องเที่ยวจาก model Attraction และส่งข้อมูลไปยังหน้า viewdetail.blade.php เพื่อแสดงรายละเอียดของสถานที่ท่องเที่ยวให้ผู้ใช้งาน
\begin{figure}[H]
\centering
\includegraphics[width=\textwidth]{Figures/my3/Untitled Diagram-sq เลือก}
\caption{Sequence Diagram เลือกสถานที่ท่องเที่ยว}
\label{Fig:sqselect}
\end{figure}
จากภาพที่ \ref{Fig:sqselect} สามารถอธิบายแผนภาพ Sequence Diagram เลือกสถานที่ท่องเที่ยว ได้ดังนี้ เมื่อผู้ใช้งานทำการเลือกสถานที่ท่องเที่ยวที่หน้า getview.blade.php ระบบจะทำการส่ง idสถานที่ท่องเที่ยวไปยังcontroller addplace และเรียกใช้งานเมธอด add() จากนั้นจะทำการบันทึก idสถานที่ท่องเที่ยวที่เลือก และส่งแจ้งเตือนการเลือกสำเร็จกลับให้ผู้ใช้งาน
\begin{figure}[H]
\centering
\includegraphics[width=\textwidth]{Figures/my3/Untitled Diagram-sq ดูลำดับการเดินทาง}
\caption{Sequence Diagram ดูลำดับการเดินทาง}
\label{Fig:sqresult}
\end{figure}
จากภาพที่ \ref{Fig:sqresult} สามารถอธิบายแผนภาพ Sequence Diagram ดูลำดับการเดินทาง ได้ดังนี้ เมื่อผู้ใช้งานทำการกดปุ่มค้นหาเส้นทางที่หน้า selectview.blade.php ระบบจะส่งค่า lat,lng ของตำแหน่งปัจจุบันของผู้ใช้งานไปยัง ResultController จากนั้นจะเรียกใช้งานเมธอด geturl() โดยเมธอดนี้จะทำหน้าที่สร้าง url เพื่อส่งไปหาค่าระยะทาง และเรียกใช้เมธอด getdistance() เมธอดนี้มีหน้าที่ส่ง url เพื่อหาระยะทางจาก distance matrix api จากนั้นจะทำการเรียงลำดับการเดินทาง เมื่อเรียงลำดับการเดินทางเสร็จแล้ว จะทำการดึงข้อมูลสถานที่ท่องเที่ยวจาก model Attraction และส่งไปแสดงหน้า result.blade.php เพื่อแสดงลำดับการเดินทางให้ผู้ใช้งาน
\begin{figure}[H]
\centering
\includegraphics[width=\textwidth]{Figures/my3/Untitled Diagram-sq เพิ่มจังหวัด}
\caption{Sequence Diagram เพิ่มจังหวัด}
\label{Fig:sqaddp}
\end{figure}
จากภาพที่ \ref{Fig:sqaddp} สามารถอธิบายแผนภาพ Sequence Diagram เพิ่มจังหวัด ได้ดังนี้ เมื่อผู้ใช้กรอกข้อมูลที่หน้า insert.blade.php ระบบจะส่งข้อมูลที่กรอกไปยัง adminController และเรียกใช้งานเมธอด insertProvince() จากนั้นจะทำการบันทึกข้อมูลที่กรอกลงฐานข้อมูลและส่งแจ้งเตือนการบันทึกไปยังผู้ใช้
\begin{figure}[H]
\centering
\includegraphics[width=\textwidth]{Figures/my3/Untitled Diagram-sq เพิ่มท่องเที่ยว}
\caption{Sequence Diagram เพิ่มสถานที่ท่องเที่ยว}
\label{Fig:sqadda}
\end{figure}
จากภาพที่ \ref{Fig:sqadda} สามารถอธิบายแผนภาพ Sequence Diagram เพิ่มสถานที่ท่องเที่ยว ได้ดังนี้ เมื่อผู้ใช้กรอกข้อมูลที่หน้า insert.blade.php ระบบจะส่งข้อมูลที่กรอกไปยัง adminController และเรียกใช้งานเมธอด insertAttraction() จากนั้นจะทำการบันทึกข้อมูลที่กรอกลงฐานข้อมูลและส่งแจ้งเตือนการบันทึกไปยังผู้ใช้
\begin{figure}[H]
\centering
\includegraphics[width=\textwidth]{Figures/my3/Untitled Diagram-sq ลบจังหวัด}
\caption{Sequence Diagram ลบจังหวัด}
\label{Fig:sqdelp}
\end{figure}
จากภาพที่ \ref{Fig:sqdelp} สามารถอธิบายแผนภาพ Sequence Diagram ลบจังหวัด ได้ดังนี้ เมื่อผู้ใช้กดปุ่มลบที่หน้า admin.blade.php ระบบจะส่ง idจังหวัดไปยัง adminController และเรียกใช้งานเมธอด deleteProvince ระบบจะทำการดึงข้อมูลสถานที่ท่องเที่ยวที่มี idจังหวัดที่ต้องการลบจาก model Attraction และทำการลบสถานที่ท่องเที่ยวนั้นออก จากนั้นจะทำการดึงข้อมูลจังหวัดที่ต้องการลบและทำการลบ และส่งแจ้งเตือนการลบไปยังผู้ใช้งาน
\begin{figure}[H]
\centering
\includegraphics[width=\textwidth]{Figures/my3/Untitled Diagram-sq ลบสถานที่ท่องเที่ยว}
\caption{Sequence Diagram ลบสถานที่ท่องเที่ยว}
\label{Fig:sqdela}
\end{figure}
จากภาพที่ \ref{Fig:sqdela} สามารถอธิบายแผนภาพ Sequence Diagram ลบสถานที่ท่องเที่ยว ได้ดังนี้ เมื่อผู้ใช้กดปุ่มลบที่หน้า adminsearch.blade.php ระบบจะส่ง idสถานที่ท่องเที่ยวไปยัง adminController และเรียกใช้งานเมธอด deleteAttraction ระบบจะทำการดึงข้อมูลสถานที่ท่องเที่ยวที่มี idสถานที่ท่องเที่ยวที่ต้องการลบจาก model Attraction และทำการลบสถานที่ท่องเที่ยวนั้นออก จากนั้นจะทำการส่งแจ้งเตือนการลบไปยังผู้ใช้งาน
\begin{figure}[H]
\centering
\includegraphics[width=\textwidth]{Figures/my3/Untitled Diagram-sq แก้ไขท่องเที่ยว}
\caption{Sequence Diagram แก้ไขสถานที่ท่องเที่ยว}
\label{Fig:squpdate}
\end{figure}
จากภาพที่ \ref{Fig:squpdate} สามารถอธิบายแผนภาพ Sequence Diagram แก้ไขสถานที่ท่องเที่ยว ได้ดังนี้ เมื่อผู้ใช้กดปุ่มแก้ไขที่หน้า adminsearch.blade.php ระบบจะส่ง idสถานที่ท่องเที่ยวไปยัง adminController และเรียกใช้งานเมธอด edit() ระบบจะทำการดึงข้อมูลสถานที่ท่องเที่ยวที่มี idสถานที่ท่องเที่ยวเหมือนกันจาก model Attraction และส่งข้อมูลไปแสดงหน้า update.blade.php จากนั้นผู้ใช้จะทำการกรอกข้อมูลที่ต้องการแก้ไขที่หน้า update.blade.php เมื่อกดปุ่ม submit ระบบจะส่งข้อมูลที่กรอกมายัง adminController และเรียกใช้งานเมธอด update() โดยเมธอดนี้มีหน้าที่อัพเดทข้อมูล และทำการส่งแจ้งเตือนการแก้ไขสำเร็จให้ผู้ใช้
\ No newline at end of file
\chapter{การพัฒนาระบบ}
หลังจากที่ได้มีการเตรียมความพร้อมสำหรับการพัฒนาในด้านต่าง ไม่ว่าจะเป็นที่มาและความสำคัญของปัญหา เทคโนโลยีที่มีความเหมาะสมกับระบบ และการออกแบบระบบการทำงานรวมไปถึงโครงสร้างของข้อมูล ในบทนี้จะเป็นการพูดถึงการสร้างระบบที่ได้มีการออกแบบไว้ โดย
การพัฒนาระบบท่องเที่ยวอีสาน ถูกพัฒนาขึ้นด้วย Laravel Framework มีรายละเอียดดังนี้
\section{โครงสร้างของ loginController}
\begin{figure}[H]
{\setstretch{1.0}\begin{lstlisting}
$user = $request->input('username');
$pass = $request->input('password');
$admin = User::where('username', 'admin')->first()->toArray();
if ($user == $admin["username"] && $pass == $admin["password"]) {
session()->put('login', true);
return Redirect::to('/admin');
} else {
session()->flash('loginFail', 'fail');
return Redirect::to('/adminlogin');
}
\end{lstlisting}}
\caption{function login}
\label{Fig:functionLogin}
\end{figure}
จากภาพที่ \ref{Fig:functionLogin} สามารถอธิบายการทำงานได้ดังนี้
\begin{itemize}[label={--}]
\item บรรทัดที่ 1 เป็นการรับค่าอินพุตจาก username มาเก็บในตัวแปร user
\item บรรทัดที่ 2 เป็นการรับค่าอินพุตจาก password มาเก็บในตัวแปร pass
\item บรรทัดที่ 3 เป็นดึงข้อมูล admin มาเก็บในตัวแปร admin
\item บรรทัดที่ 4-6 เป็นการตรวจสอบการ login และอัพเดทสถานการณ์ login
\item บรรทัดที่ 7-9 เป็นการอัพเดทสถานะเข้าสู่ระบบไม่สำเร็จ
\end{itemize}
\begin{figure}[H]
{\setstretch{1.0}\begin{lstlisting}
if (Session::has('login')) {
return Redirect::to('admin');
} else
return view('login');
\end{lstlisting}}
\caption{function checklogin}
\label{Fig:functionCheckLogin}
\end{figure}
จากภาพที่ \ref{Fig:functionCheckLogin} สามารถอธิบายการทำงานได้ดังนี้
\begin{itemize}[label={--}]
\item บรรทัดที่ 1-2 เป็นการตรวจสอบการ login ถ้ามีการloginแล้วให้ทำการไปหน้า admin
\item บรรทัดที่ 3-4 เป็นการตรวจสอบถ้ายังไม่มีการ login ให้ไปหน้า login
\end{itemize}
\begin{figure}[H]
{\setstretch{1.0}\begin{lstlisting}
$request->session()->forget('login');
return Redirect::to('/');
\end{lstlisting}}
\caption{function logout}
\label{Fig:functionLogout}
\end{figure}
จากภาพที่ \ref{Fig:functionLogout} สามารถอธิบายการทำงานได้ดังนี้
\begin{itemize}[label={--}]
\item บรรทัดที่ 1-2 เป็นการลบสถานะการ login และกลับไปหน้าแรก
\end{itemize}
\section{โครงสร้างของหน้า login}
\begin{figure}[H]
{\setstretch{1.0}\begin{lstlisting}
<div class="card text-white bg-dark mb-3" style="width: 25rem;">
<center>
<div class="card-header">
Login
</div>
</center>
<div class="card-body">
@if(Session::has('loginFail'))
<div class="alert alert-danger alert-dismissible fade show" role="alert">
username หรือ password ไม่ถูกต้อง
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
@else
@endif
<form action="{{route('loginController.login')}}" method="post">
{{csrf_field()}}
<div class="form-col">
<div class="form-group">
<label for="username" class="card-text">Username:</label><br>
<input type="text" name="username" id="username" class="form-control" required>
</div>
<div class="form-group">
<label for="password" class="card-text">Password:</label><br>
<input type="password" name="password" id="password" class="form-control">
</div>
<input type="submit" name="submit" class="btn btn-info btn-md" value="submit">
</div>
</form>
</div>
</div>
\end{lstlisting}}
\caption{ไฟล์ login.blade.php}
\label{Fig:login}
\end{figure}
จากภาพที่ \ref{Fig:login} โครงสร้างของไฟล์ login.blade.php สามารถอธิบายการทำงานได้ดังนี้
\begin{itemize}[label={--}]
\item บรรทัดที่ 1 เป็นการสร้างการ์ด
\item บรรทัดที่ 3 -5 เป็นการกำหนดส่วนหัวของการ์ด
\item บรรทัดที่ 8 -16 เป็นการแสดงข้อความกรณีเข้าสู่ระบบไม่สำเร็จ
\item บรรทัดที่ 17 -30 เป็นการสร้างฟอร์มกรอกข้อมูล
\item บรรทัดที่ 20 -23 เป็นการสร้างช่องสำหรับกรอก username
\item บรรทัดที่ 24 -27 เป็นการสร้างช่องกรอก password
\item บรรทัดที่ 28 เป็นการสร้างปุ่ม submit
\end{itemize}
\section{โครงสร้างหน้า admin}
\begin{figure}[H]
{\setstretch{1.0}\begin{lstlisting}
<script>
$(document).ready(function() {
$('.delete').on('submit', function() {
if (confirm("ยืนยันการลบ ?")) {
return true;
} else {
return false;
}
});
});
</script>
\end{lstlisting}}
\caption{การยืนยันการลบข้อมูล}
\label{Fig:admin1}
\end{figure}
จากภาพที่ \ref{Fig:admin1} สามารถอธิบายการทำงานได้ดังนี้
\begin{itemize}[label={--}]
\item บรรทัดที่ 3 เป็นการตรวจสอบว่ามีการกดปุ่มหรือไม่
\item บรรทัดที่ 4-5 กรณียืนยันการลบจะ return true เพื่อทำงานลบ
\item บรรทัดที่ 6-7 กรณีไม่ยืนยันการลบจะ return false
\end{itemize}
\begin{figure}[H]
{\setstretch{1.0}\begin{lstlisting}
@if(Session::has('success'))
<div class="alert alert-success alert-dismissible fade show" role="alert">
ลบข้อมูลแล้ว
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
@endif
<div class="card">
<table style="width:100%" class="table">
<tr>
<th scope="col">รหัสจังหวัด</th>
<th scope="col">ชื่อจังหวัด</th>
<th></th>
</tr>
@foreach ($provinces as $province)
<tr>
<td>{{$province["provinces_id"]}}</td>
<td>{{$province["provinces_name"]}}</td>
<form class="delete" action="{{ route('adminController.deleteProvince') }}" method="post">
{{csrf_field()}}
<input type="hidden" name="province_id" value={{$province["provinces_id"]}}>
<td><input type="submit" class="btn btn-danger" value="ลบ"></td>
</form>
<form action="{{ route('adminController.search') }}" method="get">
<input type="hidden" name="province_id" value={{$province["provinces_id"]}}>
<td><input type="submit" class="btn btn-primary" value="ค้นหา"></td>
</form>
</tr>
@endforeach
</table>
</div>
\end{lstlisting}}
\caption{โครงสร้างหน้า admin}
\label{Fig:admin2}
\end{figure}
จากภาพที่ \ref{Fig:admin2} สามารถอธิบายการทำงานได้ดังนี้
\begin{itemize}[label={--}]
\item บรรทัดที่ 1-8 เป็นการแสดงแจ้งเตือนการลบสำเร็จ
\item บรรทัดที่ 10-31 เป็นการสร้างตาราง
\item บรรทัดที่ 16-30 เป็นการแสดงรายชื่อจังหวัด
\item บรรทัดที่ 20-24 เป็นการสร้างปุ่มลบ
\item บรรทัดที่ 25-28 เป็นการสร้างปุ่มค้นหา
\end{itemize}
\section{โครงสร้างของ adminController}
\begin{figure}[H]
{\setstretch{1.0}\begin{lstlisting}
$province = new Province([
'provinces_id' => $request->input('province_id'),
'provinces_name' => $request->input('province_name')
]);
$province->timestamps = false;
$province->save();
session()->flash('inserted', 'success');
return Redirect::to('/admin/insert');
\end{lstlisting}}
\caption{function insertProvince}
\label{Fig:adminControllerInsertProvince}
\end{figure}
จากภาพที่ \ref{Fig:adminControllerInsertProvince} สามารถอธิบายการทำงานได้ดังนี้
\begin{itemize}[label={--}]
\item บรรทัดที่ 1-4 เป็นการรับค่าที่อินพุตเข้ามา
\item บรรทัดที่ 5 เป็นคำสั่งกำหนดว่าไม่ทำการบันทึกเวลาการเพิ่มข้อมูล
\item บรรทัดที่ 6 เป็นการบันทึกข้อมูล
\item บรรทัดที่ 7-8 เป็นการส่งแจ้งเตือนการเพิ่มสำเร็จ
\end{itemize}
\begin{figure}[H]
{\setstretch{1.0}\begin{lstlisting}
$attraction_id = $request->input('attraction_id');
$attractions = Attraction::where('attractions_id', $attraction_id)->get()->toArray();
return view('update')->with('attractions', $attractions);
\end{lstlisting}}
\caption{function edit}
\label{Fig:adminControllerEdit}
\end{figure}
จากภาพที่ \ref{Fig:adminControllerEdit} สามารถอธิบายการทำงานได้ดังนี้
\begin{itemize}[label={--}]
\item บรรทัดที่ 1 เป็นการรับค่าจากอินพุต
\item บรรทัดที่ 2 เป็นการดึงข้อมูลสถานที่ท่องเที่ยวที่มี id เท่ากับค่าอินพุต
\item บรรทัดที่ 3 เป็นการส่งค่าที่ได้ไปแสดงหน้าอัพเดท
\end{itemize}
\begin{figure}[H]
{\setstretch{1.0}\begin{lstlisting}
$province_id = $request->input('province_id');
$attractions = Attraction::where('provinces_id', $province_id)->get()->toArray();
return view('adminsearch')
->with('attractions', $attractions);
\end{lstlisting}}
\caption{function search}
\label{Fig:adminControllerSearch}
\end{figure}
จากภาพที่ \ref{Fig:adminControllerSearch} สามารถอธิบายการทำงานได้ดังนี้
\begin{itemize}[label={--}]
\item บรรทัดที่ 1 เป็นการรับค่าจากอินพุต
\item บรรทัดที่ 2 เป็นการดึงข้อมูลสถานที่ท่องเที่ยวที่มี id เท่ากับค่าอินพุต
\item บรรทัดที่ 3 เป็นการส่งค่าที่ได้ไปแสดงหน้า adminsearch
\end{itemize}
\begin{figure}[H]
{\setstretch{1.0}\begin{lstlisting}
$attraction_id = $request->input('attraction_id');
$data = Attraction::where('attractions_id',$attraction_id)->get()->toArray();
$data_img = $data[0]['image_url'];
$pics = explode("|",$data_img);
foreach ($pics as $pic) {
if(file_exists(public_path('upload/'.$pic))){
unlink(public_path('upload/'.$pic));
}}
$attraction = Attraction::where('attractions_id', $attraction_id);
$attraction->delete();
session()->flash('success', 'success');
return Redirect::back();
\end{lstlisting}}
\caption{function deleteAttraction}
\label{Fig:adminControllerDeleteAttraction}
\end{figure}
จากภาพที่ \ref{Fig:adminControllerDeleteAttraction} สามารถอธิบายการทำงานได้ดังนี้
\begin{itemize}[label={--}]
\item บรรทัดที่ 1 เป็นการรับค่าจากอินพุต
\item บรรทัดที่ 2-3 เป็นการดึงข้อรูปภาพของสถานที่
\item บรรทัดที่ 4 เป็นการแยก string
\item บรรทัดที่ 5-8 เป็นการลบรูปภาพ
\item บรรทัดที่ 9-10 เป็นการลบข้อมูลในฐานข้อมูล
\end{itemize}
\begin{figure}[H]
{\setstretch{1.0}\begin{lstlisting}
$this->validate($request,[
'image' => 'required',
'image.*' => 'image|mimes:jpeg,png,jpg|max:2048'
]);
$attraction_id = $request->input('attractions_id');
$data = Attraction::where('attractions_id',$attraction_id)->get()->toArray();
$data_img = $data[0]['image_url'];
$pics = explode("|",$data_img);
foreach ($pics as $pic) {
if(file_exists(public_path('upload/'.$pic))){
unlink(public_path('upload/'.$pic));
}
}
if ($request->hasFile('image')) {
$files = $request->file('image');
foreach($files as $file){
$filename=$file->getClientOriginalName();
$file->move('upload',$filename);
$images[]=$filename;
}
$data=implode("|",$images);
}
Attraction::where('attractions_id', $attraction_id)
->update([
'attractions_name' => $request->input('attractions_name'),
'Latitude' => $request->input('lat'),
'longitude' => $request->input('lng'),
'description' => $request->input('description'),
'image_url' => $data
]);
session()->flash('success', 'success');
return Redirect::back();
\end{lstlisting}}
\caption{function update}
\label{Fig:adminControllerUpdate}
\end{figure}
จากภาพที่ \ref{Fig:adminControllerUpdate} สามารถอธิบายการทำงานได้ดังนี้
\begin{itemize}[label={--}]
\item บรรทัดที่ 1-4 เป็นการตรวจสอบไฟล์ที่อินพุตเข้ามา
\item บรรทัดที่ 5 เป็นการรับค่าจากอินพุต
\item บรรทัดที่ 6 เป็นการดึงข้อมูลสถานที่ท่องเที่ยวจากฐานข้อมูล
\item บรรทัดที่ 7 เป็นการดึงรูปภาพจากฐานข้อมูล
\item บรรทัดที่ 8 เป็นการแยก string
\item บรรทัดที่ 9-13 เป็นการลบรูปภาพใน folder upload
\item บรรทัดที่ 14-21 เป็นการเพิ่มรูปภาพใน folder upload
\item บรรทัดที่ 23-30 เป็นการอัพเดทข้อมูลลงฐานข้อมูล
\end{itemize}
\begin{figure}[H]
{\setstretch{1.0}\begin{lstlisting}
$province_id = $request->input('province_id');
$attraction = Attraction::where('provinces_id', $province_id)->get()->toArray();
for ($i=0; $i < count($attraction); $i++) {
$data = $attraction[$i];
$data_img = $data['image_url'];
$pics = explode("|",$data_img);
foreach ($pics as $pic) {
if(file_exists(public_path('upload/'.$pic))){
unlink(public_path('upload/'.$pic));
}
}
}
$attractions = Attraction::where('provinces_id', $province_id);
$attractions->delete();
$province = Province::where('provinces_id', $province_id);
$province->delete();
session()->flash('success', 'success');
return Redirect::to('/admin');
\end{lstlisting}}
\caption{function deleteProvince}
\label{Fig:adminControllerDeleteProvince}
\end{figure}
จากภาพที่ \ref{Fig:adminControllerDeleteProvince} สามารถอธิบายการทำงานได้ดังนี้
\begin{itemize}[label={--}]
\item บรรทัดที่ 1 เป็นการรับค่า province\_id จากอินพุต
\item บรรทัดที่ 2 เป็นการดึงข้อมูลสถานที่ท่องเที่ยวจากฐานข้อมูล
\item บรรทัดที่ 3-12 เป็นการลบข้อมูลรูปภาพใน folder upload
\item บรรทัดที่ 13-14 เป็นการลบข้อมูลสถานที่ท่องเที่ยวออกจากฐานข้อมูล
\item บรรทัดที่ 15-16 เป็นการลบข้อมูลจังหวัดอกจากฐานข้อมูล
\item บรรทัดที่ 17-18 เป็นการส่งแจ้งเตือนการลบสำเร็จพร้อมกลับไปยังหน้า admin
\end{itemize}
\begin{figure}[H]
{\setstretch{1.0}\begin{lstlisting}
$this->validate($request,[
'image' => 'required',
'image.*' => 'image|mimes:jpeg,png,jpg,gif,svg|max:2048'
]);
if ($request->hasFile('image')) {
$files = $request->file('image');
foreach($files as $file){
$filename=$file->getClientOriginalName();
$file->move('upload',$filename);
$images[]=$filename;
}
$data=implode("|",$images);
}
$attraction = new Attraction([
'provinces_id' => $request->input('province_id'),
'attractions_name' => $request->input('attractions_name'),
'Latitude' => $request->input('lat'),
'longitude' => $request->input('lng'),
'description' => $request->input('description'),
'image_url' => $data
]);
$attraction->timestamps = false;
$attraction->save();
session()->flash('inserted', 'success');
return Redirect::to('/admin/insert');
\end{lstlisting}}
\caption{function insertAttraction}
\label{Fig:adminControllerInsertAttraction}
\end{figure}
จากภาพที่ \ref{Fig:adminControllerInsertAttraction} สามารถอธิบายการทำงานได้ดังนี้
\begin{itemize}[label={--}]
\item บรรทัดที่ 1-4 เป็นการตรวจสอบไฟล์ที่อินพุตเข้ามา
\item บรรทัดที่ 5-13 เป็นการเพิ่มรูปภาพลงใน folder upload
\item บรรทัดที่ 14-21 เป็นการกำหนดค่าที่จะบันทึกลงในฐานข้อมูล
\item บรรทัดที่ 22 เป็นการกำหนดค่าไม่บันทึกเวลาลงข้อมูล
\item บรรทัดที่ 23 เป็นการบันทึกข้อมูล
\item บรรทัดที่ 24-25 เป็นการส่งแจ้งเตือนการบันทึกสำเร็จ
\end{itemize}
\section{โครงสร้างของหน้า adminsearch}
\begin{figure}[H]
{\setstretch{1.0}\begin{lstlisting}
<nav class="navbar navbar-dark bg-dark">
<a href="/" class="navbar-brand">Travel</a>
<form class="form-inline">
<div class="dropdown">
<button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Admin
</button>
<div class="dropdown-menu" aria-labelledby="dropdownMenuButton">
<a href="/admin" class="dropdown-item">หน้าแรก</a>
<a class="dropdown-item" href="/admin/insert">เพิ่มข้อมูล</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="/admin/logout">Log out</a>
</div>
</div>
</form>
</nav>
@if(Session::has('success'))
<div class="alert alert-success alert-dismissible fade show" role="alert">
success
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
@endif
\end{lstlisting}}
\caption{การสร้าง navbar หน้า adminsearch}
\label{Fig:adminsearch}
\end{figure}
จากภาพที่ \ref{Fig:adminsearch} สามารถอธิบายการทำงานได้ดังนี้
\begin{itemize}[label={--}]
\item บรรทัดที่ 1-16 เป็นการสร้าง navbar
\item บรรทัดที่ 2 เป็นการสร้างลิงค์ไปหน้าค้นหาสถานที่ท่องเที่ยว
\item บรรทัดที่ 4-14 เป็นการ dropdown
\item บรรทัดที่ 17-24 เป็นการตรวจสอบสถานะการลบ ถ้าลบสำเร็จจะทำการแสดงข้อความ success
\end{itemize}
\begin{figure}[H]
{\setstretch{1.0}\begin{lstlisting}
<div class="card">
@if($attractions!=null)
<table style="width:100%" class="table">
<tr>
<th scope="col">รหัสสถานที่ท่องเที่ยว</th>
<th scope="col">ชื่อสถานที่ท่องเที่ยว</th>
<th></th>
</tr>
@foreach ($attractions as $attraction)
<tr>
<td>{{$attraction["attractions_id"]}}</td>
<td>{{$attraction["attractions_name"]}}</td>
<form action="{{route('adminController.deleteAttraction')}}" method="post">
{{csrf_field()}}
<input type="hidden" name="attraction_id" value={{$attraction["attractions_id"]}}>
<td><input type="submit" class="btn btn-danger" value="ลบ"></td>
</form>
<form action="{{route('adminController.edit')}}" method="get">
<input type="hidden" name="attraction_id" value={{$attraction["attractions_id"]}}>
<td><input type="submit" class="btn btn-warning" value="แก้ไข"></td>
</form>
</tr>
@endforeach
</table>
@else
<p>ไม่มีข้อมูล</p>
@endif
</div>
\end{lstlisting}}
\caption{adminsearch.blade.php}
\label{Fig:adminsearch}
\end{figure}
จากภาพที่ \ref{Fig:adminsearch} สามารถอธิบายการทำงานได้ดังนี้
\begin{itemize}[label={--}]
\item บรรทัดที่ 2 เป็นการตรวจสอบว่ามีข้อมูลหรือไม่ ถ้าไม่มีข้อมูลจะทำงานบรรทัดที่ 27
\item บรรทัดที่ 3-25 เป็นการสร้างตาราง
\item บรรทัดที่ 9-24 เป็นการวนลูปเพื่อแสดงชื่อสถานที่ท่องเที่ยวลงในตาราง
\item บรรทัดที่ 13-17 เป็นการสร้างปุ่มลบข้อมูลสถานที่ท่องเที่ยว
\item บรรทัดที่ 18-22 เป็นการสร้างปุ่มแก้ไขข้อมูลสถานที่ท่องเที่ยว
\item บรรทัดที่ 27 เป็นการแสดงข้อความไม่มีข้อมูล
\end{itemize}
\section{โครงสร้างของหน้า getview}
\begin{figure}[H]
{\setstretch{1.0}\begin{lstlisting}
<div class="row">
@foreach($places as $place)
<div class="card text-white bg-secondary mb-3" style="width: 18rem;">
<?php
$pic= explode("|",$place['image_url']);
?>
<img class="card-img-top" src="../upload/{{$pic[0]}}" alt="Card image cap">
<div class="card-body">
<h5 class="card-title">{{$place["attractions_name"]}}</h5>
<div class="row">
<a href="/detail_/{{$place["attractions_id"]}}" class="btn btn-primary">รายละเอียด</a>
<form action="{{ route('addplace.add') }}" method="get">
<!--{{csrf_field()}}-->
<input type= "hidden" name= "id" value="{{$place["attractions_id"]}}">
<input onclick="success()" type= "submit" class="btn btn-primary" value= "เลือก">
</form>
</div>
</div>
</div>
@endforeach
</div>
\end{lstlisting}}
\caption{getview.blade.php}
\label{Fig:getview}
\end{figure}
จากภาพที่ \ref{Fig:getview} สามารถอธิบายการทำงานได้ดังนี้
\begin{itemize}[label={--}]
\item บรรทัดที่ 2-20 เป็นการวนลูปเพื่อนำข้อมูลมาแสดง
\item บรรทัดที่ 4-6 เป็นการแยก string
\item บรรทัดที่ 7 เป็นการแสดงรูปภาพ
\item บรรทัดที่ 5 เป็นการแสดงชื่อสถานที่ท่องเที่ยว
\item บรรทัดที่ 11 เป็นการสร้างปุ่มรายละเอียด
\item บรรทัดที่ 12-16 เป็นการสร้างปุ่มเลือก
\end{itemize}
\section{โครงสร้างของหน้า insert}
\begin{figure}[H]
{\setstretch{1.0}\begin{lstlisting}
<script type="text/javascript">
function setForm(value) {
if (value == 'form1') {
document.getElementById('form1').style = 'display:block;';
document.getElementById('form2').style = 'display:none;';
} else {
document.getElementById('form2').style = 'display:block;';
document.getElementById('form1').style = 'display:none;';
}
}
</script>
\end{lstlisting}}
\caption{การสลับ form กรอกข้อมูล}
\label{Fig:insert}
\end{figure}
จากภาพที่ \ref{Fig:insert} สามารถอธิบายการทำงานได้ดังนี้
\begin{itemize}[label={--}]
\item บรรทัดที่ 3-5 เป็นการตรวจสอบถ้าค่าเท่ากับ form1 ให้แสดงform1
\item บรรทัดที่ 6-8 เป็นการแสดง form2
\end{itemize}
\begin{figure}[H]
{\setstretch{1.0}\begin{lstlisting}
<div class="card-header">
<label>เพิ่มข้อมูล</label>
<select class="custom-select" onchange="setForm(this.value)" style="width: 25rem;">
<option value="form1">สถานที่ท่องเที่ยว</option>
<option value="form2">จังหวัด</option>
</select>
</div>
\end{lstlisting}}
\caption{การสร้างเมนู select หน้า insert}
\label{Fig:insert2}
\end{figure}
จากภาพที่ \ref{Fig:insert2} สามารถอธิบายการทำงานได้ดังนี้
\begin{itemize}[label={--}]
\item บรรทัดที่ 2 เป็นการแสดงข้อความ เพิ่มข้อมูล
\item บรรทัดที่ 3-7 เป็นการสร้างปุ่ม select
\end{itemize}
\begin{figure}[H]
{\setstretch{1.0}\begin{lstlisting}
<div id="form2" style="display: none">
<form action="{{route('adminController.insertProvince')}}" method="post">
{{csrf_field()}}
<div class="col-md-4 mb-3">
<label>รหัสจังหวัด</label>
<input type="number" class="form-control" name="province_id" required></div>
<div class="col-md-4 mb-3">
<label>ชื่อจังหวัด</label>
<input type="text" class="form-control" name="province_name" required></div>
<input type="submit" name="submit" class="btn btn-info btn-md" value="submit"></form></div>
\end{lstlisting}}
\caption{form2 หน้า insert}
\label{Fig:insert3}
\end{figure}
จากภาพที่ \ref{Fig:insert3} สามารถอธิบายการทำงานได้ดังนี้
\begin{itemize}[label={--}]
\item บรรทัดที่ 4-6 เป็นการสร้างช่องกรอกข้อมูลรหัสจังหวัด
\item บรรทัดที่ 7-9 เป็นการสร้างช่องกรอกข้อมูลชื่อจังหวัด
\item บรรทัดที่ 10 เป็นการสร้างปุ่ม submit
\end{itemize}
\begin{figure}[H]
{\setstretch{1.0}\begin{lstlisting}
<div id="form1">
<form action="{{route('adminController.insertAttraction')}}" method="post" enctype="multipart/form-data">
{{csrf_field()}}
<div class="form-col">
<div class="col-md-4 mb-3">
<label>จังหวัด</label>
<select name="province_id" class="form-control">
@foreach ($provinces as $province)
<option value={{$province["provinces_id"]}}>{{$province["provinces_name"]}}</option>
@endforeach
</select>
</div>
<div class="col-md-4 mb-3">
<label>ชื่อสถานที่ท่องเที่ยว</label>
<input type="text" class="form-control" name="attractions_name" required>
</div>
<div class="col-md-4 mb-3">
<label>Latitude</label>
<input type="number" step="any" class="form-control" name="lat" required>
</div>
<div class="col-md-4 mb-3">
<label>Longtitud</label>
<input type="number" step="any" class="form-control" name="lng" required>
</div>
<div class="col-md-4 mb-3">
<label>รายละเอียด</label>
<textarea class="form-control " name="description" required></textarea>
</div>
<div class="col-md-4 mb-3">
<label>รูปภาพ</label>
<input type="file" name="image[]" multiple="multiple" required multiple>
</div>
<input type="submit" name="submit" class="btn btn-info btn-md" value="submit">
</div>
</form>
</div>
\end{lstlisting}}
\caption{form1 หน้า insert}
\label{Fig:insert4}
\end{figure}
จากภาพที่ \ref{Fig:insert4} สามารถอธิบายการทำงานได้ดังนี้
\begin{itemize}[label={--}]
\item บรรทัดที่ 5-12 เป็นการสร้างเมนู select
\item บรรทัดที่ 8-10 เป็นการสร้าง option แสดงชื่อจังหวัด
\item บรรทัดที่ 14-16 เป็นการสร้างช่องกรอกข้อมูลชื่อสถานที่ท่องเที่ยว
\item บรรทัดที่ 17-20 เป็นการสร้างช่องกรอกข้อมูลละติจูด
\item บรรทัดที่ 21-24 เป็นการสร้างช่องกรอกข้อมูลลองจิจูด
\item บรรทัดที่ 25-28 เป็นการสร้างช่องกรอกข้อมูลรายละเอียด
\item บรรทัดที่ 29-32 เป็นการสร้างที่เพิ่มรูปภาพ
\item บรรทัดที่ 33 เป็นการสร้างปุ่ม submit
\end{itemize}
\section{โครงสร้างของหน้า result}
\begin{figure}[H]
{\setstretch{1.0}\begin{lstlisting}
<div class="card">
<div class="card-header">
ลำดับการเดินทาง
</div>
<ul class="list-group list-group-flush">
<?php
$p=array('B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K');
$i=0;
?>
<li class="list-group-item">A ตำแหน่งปัจจุบัน</li>
@foreach($dataresults as $data)
<li class="list-group-item">{{$p[$i]}} {{$data["attractions_name"]}}</li>
<?php $i++; ?>
@endforeach
</ul>
</div>
\end{lstlisting}}
\caption{การแสดงลำดับการเดินทาง}
\label{Fig:result}
\end{figure}
จากภาพที่ \ref{Fig:result} สามารถอธิบายการทำงานได้ดังนี้
\begin{itemize}[label={--}]
\item บรรทัดที่ 6-9 เป็นการสร้าง array เพื่อนำไปใช้ในการบอกตำแหน่งของสถานที่ท่องเที่ยว
\item บรรทัดที่ 11-14 เป็นการวนลูปเพื่อแสดงข้อมูลลำดับการเดินทาง
\end{itemize}
\begin{figure}[H]
{\setstretch{1.0}\begin{lstlisting}
function initMap() {
var directionsService = new google.maps.DirectionsService();
var directionsRenderer = new google.maps.DirectionsRenderer();
var map = new google.maps.Map(document.getElementById('map'), {
center: {lat: 13.684164, lng: 100.709522},
zoom: 6
});
directionsRenderer.setMap(map);
navigator.geolocation.getCurrentPosition(function(position) {
var pos = {lat: position.coords.latitude,lng: position.coords.longitude};
map.setCenter(pos);
map.setZoom(15);
DisplayRoute(directionsService, directionsRenderer,pos);
});
}
\end{lstlisting}}
\caption{initMap}
\label{Fig:result2}
\end{figure}
จากภาพที่ \ref{Fig:result2} สามารถอธิบายการทำงานได้ดังนี้
\begin{itemize}[label={--}]
\item บรรทัดที่ 2-3 เป็นการเรียกใช้งานการค้นหาเส้นทางและการแสดงผลเส้นทาง
\item บรรทัดที่ 4-6 เป็นการกำหนดค่าให้แผนที่
\item บรรทัดที่ 8 เป็นการสร้างแผนที่ ที่กำหนดค่าเอาไว้
\item บรรทัดที่ 9-12 เป็นการหาค่า lat,lng ของตำแหน่งปัจจุบันของผู้ใช้
\item บรรทัดที่ 14 เป็นการเรียกใช้งาน DisplayRoute
\end{itemize}
\begin{figure}[H]
{\setstretch{1.0}\begin{lstlisting}
function DisplayRoute(directionsService, directionsRenderer,pos) {
var waypts = [];
<?php
for ($i=0; $i <= count($dataresults)-2; $i++) {
echo "waypts.push({";
echo "location: {lat:".$dataresults[$i]["Latitude"].",lng:".$dataresults[$i]["longitude"]."},";
echo "stopover: true";
echo "});";
}
?>
var posdes = {lat: <?php echo $dataresults[count($dataresults)-1]["Latitude"]; ?>,lng: <?php echo $dataresults[count($dataresults)-1]["longitude"]; ?>};
directionsService.route(
{
origin: pos,
destination: posdes,
waypoints: waypts,
travelMode: 'DRIVING'
},
function(response, status) {
if (status === 'OK') {
directionsRenderer.setDirections(response);
} else {
window.alert('Directions request failed due to ' + status);
}
});
}
\end{lstlisting}}
\caption{DisplayRoute}
\label{Fig:result3}
\end{figure}
จากภาพที่ \ref{Fig:result3} สามารถอธิบายการทำงานได้ดังนี้
\begin{itemize}[label={--}]
\item บรรทัดที่ 3-10 เป็นการนำผลลัพธ์เก็บไว้ใน waypts
\item บรรทัดที่ 11 เป็นการนำผลลัพธ์ตำแหน่งสุดท้ายเก็บไว้ในตัวแปร posdes
\item บรรทัดที่ 12-25 เป็นการกำหนดค่าเพื่อใช้ในการแสดงเส้นทาง
\end{itemize}
\section{โครงสร้างหน้า search}
\begin{figure}[H]
{\setstretch{1.0}\begin{lstlisting}
<?php
use App\Province;
$provinces = Province::all();
?>
<center>
<div class="container">
<form action="{{ route('getplace.getdata') }}" method="get">
<div class="form-group">
<select name="province" class="form-control">
@foreach ($provinces as $province)
<option value={{$province["provinces_id"]}} >{{$province["provinces_name"]}}</option>
@endforeach
</select>
</div>
<input type= "submit" class="btn btn-primary" value= "ค้นหา">
</form>
</div>
</center>
<a class="btn btn-secondary" href="/adminlogin">admin</a>
\end{lstlisting}}
\caption{search.blade.php}
\label{Fig:search}
\end{figure}
จากภาพที่ \ref{Fig:search} สามารถอธิบายการทำงานได้ดังนี้
\begin{itemize}[label={--}]
\item บรรทัดที่ 1-4 เป็นการดึงข้อมูลจังหวัดจากฐานข้อมูลมาเก็บในตัวแปร provinces
\item บรรทัดที่ 7-17 เป็นการสร้าง form เพื่อส่งค่าที่ผู้ใช้เลือก
\item บรรทัดที่ 9-14 เป็นการสร้างเมนู select
\item บรรทัดที่ 10-13 เป็นการกำหนดค่า option
\item บรรทัดที่ 16 เป็นการสร้างปุ่มค้นหา
\end{itemize}
\section{โครงสร้างหน้า selectview}
\begin{figure}[H]
{\setstretch{1.0}\begin{lstlisting}
<nav class="navbar navbar-dark bg-dark">
<a href="/" class="navbar-brand">Travel</a>
<div class="form-inline">
<a class="btn btn-danger" href="/delAllSelect">ลบที่เลือกทั้งหมด</a>
<form action="{{ route('ResultController.getresult') }}" method="post">
{{csrf_field()}}
<input type= "hidden" name= "lat" id= "lat" >
<input type= "hidden" name= "lng" id= "lng" >
<input type= "submit" class="btn btn-primary" value= "ค้นหาเส้นทาง">
</form>
</div>
</nav>
<div class="row">
@foreach($selecteds as $selected)
<div class="card text-white bg-secondary mb-3" style="width: 18rem;">
<img class="card-img-top" src="{{$selected['image_url']}}" alt="Card image cap">
<div class="card-body">
<h5 class="card-title">{{$selected["attractions_name"]}}</h5>
</div>
<div class="card-body">
<form action="{{ route('addplace.del') }}" method="get">
<input type= "hidden" name= "id" value="{{$selected["attractions_id"]}}">
<input type= "submit" class="btn btn-danger" value= "ลบ">
</form>
</div>
</div>
@endforeach
</div>
\end{lstlisting}}
\caption{การแสดงสถานที่ท่องเที่ยวที่เลือก}
\label{Fig:selectview}
\end{figure}
จากภาพที่ \ref{Fig:selectview} สามารถอธิบายการทำงานได้ดังนี้
\begin{itemize}[label={--}]
\item บรรทัดที่ 1-12 เป็นการสร้าง navbar
\item บรรทัดที่ 4 เป็นการสร้างปุ่ม ลบที่เลือกทั้งหมด
\item บรรทัดที่ 5-10 เป็นการสร้าง form ส่งข้อมูล lat,lng
\item บรรทัดที่ 14-27 เป็นการแสดงสถานที่ท่องเที่ยวที่ผู้ใช้เลือก
\item บรรทัดที่ 16 เป็นการแสดงรูปภาพ
\item บรรทัดที่ 18 เป็นการแสดงชื่อสถานที่ท่องเที่ยวที่เลือก
\item บรรทัดที่ 21-24 เป็นการสร้างปุ่มลบ
\end{itemize}
\begin{figure}[H]
{\setstretch{1.0}\begin{lstlisting}
<script>
var lat = document.getElementById("lat");
var lng = document.getElementById("lng");
function getCurrent() {
navigator.geolocation.getCurrentPosition(function(position) {
lat.value = position.coords.latitude;
lng.value = position.coords.longitude;
});
}
</script>
<script async defer
src="https://maps.googleapis.com/maps/api/js?key=AIzaSyAQLj-_PEe0qXFXtqhs_EdE-ZmC5zoReMs&callback=getCurrent">
</script>
\end{lstlisting}}
\caption{การหาค่า lat,lng ของตำแหน่งผู้ใช้งาน}
\label{Fig:selectview}
\end{figure}
จากภาพที่ \ref{Fig:selectview} สามารถอธิบายการทำงานได้ดังนี้
\begin{itemize}[label={--}]
\item บรรทัดที่ 2-3 เป็นการสร้างตัวแปร
\item บรรทัดที่ 4-9 เป็นการหาค่า lat,lng ของตำแหน่งผู้ใช้งาน
\item บรรทัดที่ 11-13 เป็นการเรียกใช้งานบริการของ google
\end{itemize}
\section{โครงสร้างของหน้า update}
\begin{figure}[H]
{\setstretch{1.0}\begin{lstlisting}
<div class="card">
<div class="card-body">
<form action="{{route('adminController.update')}}" method="post" enctype="multipart/form-data">
{{csrf_field()}}
<div class="form-col">
<input type="hidden" name="attractions_id" value="{{$attraction['attractions_id']}}">
<div class="col-md-4 mb-3">
<label>ชื่อสถานที่ท่องเที่ยว</label>
<input type="text" class="form-control" name="attractions_name" placeholder="{{$attraction['attractions_name']}}" value="{{$attraction['attractions_name']}}" required>
</div>
<div class="col-md-4 mb-3">
<label>Latitude</label>
<input type="number" step="any" class="form-control" name="lat" placeholder="{{$attraction['Latitude']}}" value="{{$attraction['Latitude']}}" required>
</div>
<div class="col-md-4 mb-3">
<label>Longtitud</label>
<input type="number" step="any" class="form-control" name="lng" placeholder="{{$attraction['longitude']}}" value="{{$attraction['longitude']}}" required>
</div>
<div class="col-md-4 mb-3">
<label>รายละเอียด</label>
<textarea class="form-control " name="description" required>{{$attraction['description']}}</textarea>
</div>
<div class="col-md-4 mb-3">
<label>รูปภาพ</label>
<input type="file" name="image[]" multiple="multiple" required multiple>
</div>
<input type="submit" name="submit" class="btn btn-info btn-md" value="submit">
</div>
</form>
</div>
</div>
\end{lstlisting}}
\caption{โครงสร้างของหน้า update}
\label{Fig:update}
\end{figure}
จากภาพที่ \ref{Fig:update} สามารถอธิบายการทำงานได้ดังนี้
\begin{itemize}[label={--}]
\item บรรทัดที่ 7-10 เป็นการสร้างช่องกรอกข้อมูลชื่อสถานที่ท่องเที่ยว
\item บรรทัดที่ 11-14 เป็นการสร้างช่องกรอกข้อมูลละติจูด
\item บรรทัดที่ 15-18 เป็นการสร้างช่องกรอกข้อมูลลองจิจูด
\item บรรทัดที่ 19-22 เป็นการสร้างช่องกรอกข้อมูลรายละเอียด
\item บรรทัดที่ 23-26 เป็นการสร้างที่เพิ่มรูปภาพ
\item บรรทัดที่ 27 เป็นการสร้างปุ่ม submit
\end{itemize}
\begin{figure}[H]
{\setstretch{1.0}\begin{lstlisting}
@if (count($errors) > 0)
<div class="alert alert-danger">
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
\end{lstlisting}}
\caption{การแสดงผล error}
\label{Fig:update2}
\end{figure}
จากภาพที่ \ref{Fig:update2} สามารถอธิบายการทำงานได้ดังนี้
\begin{itemize}[label={--}]
\item บรรทัดที่ 1 เป็นการตรวจสอบถ้ามี error มากกว่า 0 ให้ทำงานบรรทัดที่ 2-8
\item บรรทัดที่ 4-6 เป็นการวนลูปเพื่อแสดงผล error
\end{itemize}
\section{โครงสร้างหน้า viewdetail}
\begin{figure}[H]
{\setstretch{1.0}\begin{lstlisting}
<?php
$pics= explode("|",$detail['image_url']);
?>
<center>
<div class="card">
<div class="card-body">
<div id="carouselExampleControls" class="carousel slide" data-ride="carousel">
<div class="carousel-inner">
<?php
for ($i=0; $i < count($pics) ; $i++) {
if ($i==0) {
echo "<div class='carousel-item active'>";
echo "<img class='d-block w-100' src='../upload/$pics[$i]' >";
echo "</div>";
}else {
echo "<div class='carousel-item'>";
echo "<img class='d-block w-100' src='../upload/$pics[$i]' >";
echo "</div>";
}
} ?>
</div>
<a class="carousel-control-prev" href="#carouselExampleControls" role="button" data-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
<span class="sr-only">Previous</span>
</a>
<a class="carousel-control-next" href="#carouselExampleControls" role="button" data-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
<span class="sr-only">Next</span>
</a>
</div>
</div>
</div>
</center>
\end{lstlisting}}
\caption{โครงสร้างหน้า viewdetail}
\label{Fig:viewdetail1}
\end{figure}
จากภาพที่ \ref{Fig:viewdetail1} สามารถอธิบายการทำงานได้ดังนี้
\begin{itemize}[label={--}]
\item บรรทัดที่ 1-3 เป็นการแยก string
\item บรรทัดที่ 9-20 เป็นการแสดงรูปภาพ
\item บรรทัดที่ 22-25 เป็นการสร้างปุ่มดูรูปภาพก่อนหน้า
\item บรรทัดที่ 26-29 เป็นการสร้างปุ่มดูรูปภาพต่อไป
\end{itemize}
\begin{figure}[H]
{\setstretch{1.0}\begin{lstlisting}
<h3 class="text-left">{{$detail['attractions_name']}}</h3>
<div class="row">
<div id="map"></div>
<script>
function initMap() {
var uluru = {lat: {{$detail["Latitude"]}}, lng:{{$detail["longitude"]}} };
var map = new google.maps.Map(
document.getElementById('map'), {
zoom: 16,
center: uluru
});
var marker = new google.maps.Marker({position: uluru, map: map});
}
</script>
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyAQLj-_PEe0qXFXtqhs_EdE-ZmC5zoReMs&callback=initMap"
async defer></script>
<div class="card">
<h3>รายละเอียด</h3>
<p>{{$detail["description"]}}</p>
</div>
</div>
\end{lstlisting}}
\caption{โครงสร้างหน้า viewdetail}
\label{Fig:viewdetail2}
\end{figure}
จากภาพที่ \ref{Fig:viewdetail2} สามารถอธิบายการทำงานได้ดังนี้
\begin{itemize}[label={--}]
\item บรรทัดที่ 1 เป็นการแสดงชื่อสถานที่ท่องเที่ยว
\item บรรทัดที่ 5-13 เป็นการแสดงตำแหน่งของสถานที่ท่องเที่ยวในแผนที่
\item บรรทัดที่ 15-16 เป็นการเรียกใช้งานบริการของ google
\item บรรทัดที่ 17-20 เป็นการแสดงรายละเอียดของสถานที่ท่องเที่ยว
\end{itemize}
\begin{figure}[H]
{\setstretch{1.0}\begin{lstlisting}
<div class="card" id="cardlocation">
<div id="fb-root"></div>
<script async defer crossorigin="anonymous" src="https://connect.facebook.net/th_TH/sdk.js#xfbml=1&version=v6.0"></script>
<center><div class="fb-comments" data-href={{Request::url()}} data-width="1000" data-numposts="5"></div></center>
</div>
\end{lstlisting}}
\caption{โครงสร้างหน้า viewdetail}
\label{Fig:viewdetail3}
\end{figure}
จากภาพที่ \ref{Fig:viewdetail3} สามารถอธิบายการทำงานได้ดังนี้
\begin{itemize}[label={--}]
\item บรรทัดที่ 3 เป็นการเรียกใช้งาน Comments Plugin
\item บรรทัดที่ 4 เป็นการตั้งค่า Comments Plugin
\end{itemize}
\section{โครงสร้างของ detail}
\begin{figure}[H]
{\setstretch{1.0}\begin{lstlisting}
function showdetail($id){
$details = Attraction::where('attractions_id',$id)->get()->toArray();
return view('viewdetail')->with('details',$details);
}
\end{lstlisting}}
\caption{function showdetail}
\label{Fig:detail}
\end{figure}
จากภาพที่ \ref{Fig:detail} สามารถอธิบายการทำงานได้ดังนี้
\begin{itemize}[label={--}]
\item บรรทัดที่ 2 เป็นการนำข้อมูลสถานที่ท่องเที่ยวที่มีค่า attractions\_id เท่ากับ id เก็บในตัวแปร
\item บรรทัดที่ 3 เป็นการแสดงหน้า viewdetail พร้อมส่งค่า details ไปด้วย
\end{itemize}
\section{โครงสร้างของ getplace}
\begin{figure}[H]
{\setstretch{1.0}\begin{lstlisting}
function getdata(Request $request){
$item=$request->input('province');
$places = Attraction::where('provinces_id',$item)->get()->toArray();
return view('getview')
->with('places',$places);
}
\end{lstlisting}}
\caption{function getdata}
\label{Fig:getplace}
\end{figure}
จากภาพที่ \ref{Fig:getplace} สามารถอธิบายการทำงานได้ดังนี้
\begin{itemize}[label={--}]
\item บรรทัดที่ 2 เป็นการนำค่าอินพุตจาก province มาเก็บในตัวแปร item
\item บรรทัดที่ 3 เเป็นการนำข้อมูลสถานที่ท่องเที่ยวที่มีค่า attractions\_id เท่ากับ item เก็บในตัวแปร
\item บรรทัดที่ 4 เป็นการแสดงหน้า getview พร้อมส่งค่า places ไปด้วย
\end{itemize}
\section{โครงสร้างของ addplace}
\begin{figure}[H]
{\setstretch{1.0}\begin{lstlisting}
$id=$request->input('id');
$addPlace = Session::has('attraction_id') ? Session::get('attraction_id') : null;
if ($addPlace==null) {
$addPlace= array();
array_push($addPlace,$id);
$request->session()->put('attraction_id',$addPlace);
}else {
$have=false;
for ($i=0; $i < count($addPlace) ; $i++) {
if ($addPlace[$i]==$id) {
$have=true;
break;
}
}
if($have==false){
array_push($addPlace,$id);
$request->session()->put('attraction_id',$addPlace);
}
}
return Redirect::back();
\end{lstlisting}}
\caption{function add}
\label{Fig:funcadd}
\end{figure}
จากภาพที่ \ref{Fig:funcadd} สามารถอธิบายการทำงานได้ดังนี้
\begin{itemize}[label={--}]
\item บรรทัดที่ 1 เป็นการนำค่า id เก็บไว้ในตัวแปร
\item บรรทัดที่ 2 เป็นการตรวจสอบว่ามี session attraction\_id หรือไม่ ถ้ามีนำค่าไปเก็บในตัวแปร addPlace ถ้าไม่มีเก็บเป็นค่า null
\item บรรทัดที่ 3 เป็นการตรวจสอบว่า addPlace มีค่าเท่ากับ null หรือไม่ ถ้ามีจะทำงานบรรทัดที่ 5-7 ถ้าไม่ใช่จะทำงานบรรทัดที่ 9-13
\item บรรทัดที่ 4 เป็นการสร้าง array
\item บรรทัดที่ 5 เป็นการเพิ่มค่า id ลงใน addPlace
\item บรรทัดที่ 6 เป็นการสร้าง session attraction_id ที่มีค่าเท่ากับ addPlace
\item บรรทัดที่ 8 เป็นการประกาศตัวแปร have มีค่าเท่ากับ false
\item บรรทัดที่ 19-14 เป็นการวนลูปเพื่อนตรวจสอบว่ามีค่าซ้ำกันหรือไม่
\item บรรทัดที่ 15-17 เป็นการตรวจสอบดูว่าถ้าไม่มีค่าซ้ำจะทำการเพิ่มค่า id ในตัวแปร addPlace และใส่ค่าใน attraction_id ใหม่
\end{itemize}
\begin{figure}[H]
{\setstretch{1.0}\begin{lstlisting}
function showselect(){
if (Session::has('attraction_id')) {
$selecteds = array();
$getselects = Session::get('attraction_id');
foreach($getselects as $getselect){
$place = Attraction::where('attractions_id',$getselect )->get()->toArray();
$selecteds=array_merge($selecteds,$place);
}
return view('selectview')->with('selecteds',$selecteds);
}else {
return view('selectview');
}
}
\end{lstlisting}}
\caption{function showselect}
\label{Fig:funcshowselect}
\end{figure}
จากภาพที่ \ref{Fig:funcshowselect} สามารถอธิบายการทำงานได้ดังนี้
\begin{itemize}[label={--}]
\item บรรทัดที่ 2 เป็นการตรวจสอบว่ามี session attraction\_id หรือไม่ ถ้ามีจะทำงานบรรทัดที่ 3-9 ถ้าไม่มีจะทำงานบรรทัดที่ 11
\item บรรทัดที่ 3 เป็นการสร้าง array ชื่อ selecteds
\item บรรทัดที่ 4 เป็นการนำค่าจาก session attraction\_id เก็บไว้ในตัวแปร getselect
\item บรรทัดที่ 5-9 เป็นการวนลูปเพื่อนำค่า id จาก getselect มาดึงข้อมูลสถานที่ท่องเที่ยวเก็บไว้ในตัวแปร place และเพิ่มลงใน array selecteds
\item บรรทัดที่ 9 เป็นการ return ไปหน้า selectview พร้อมกับส่งค่า selecteds ด้วย
\item บรรทัดที่ 11 เป็นการ return ไปหน้า selectview
\end{itemize}
\begin{figure}[H]
{\setstretch{1.0}\begin{lstlisting}
function del(Request $request){
$id=$request->input('id');
$getselects = Session::get('attraction_id');
$newgetselects=array();
foreach($getselects as $getselect){
if($getselect!=$id){
array_push($newgetselects,$getselect);
$request->session()->put('attraction_id',$newgetselects);
}
}
if ($newgetselects==null) {
$request->session()->forget('attraction_id');
}
return Redirect::to('selectview');
//return redirect('del','/search');
//return view('selectview')->with('selecteds',$selecteds);
}
\end{lstlisting}}
\caption{function del}
\label{Fig:funcdel}
\end{figure}
จากภาพที่ \ref{Fig:funcdel} สามารถอธิบายการทำงานได้ดังนี้
\begin{itemize}[label={--}]
\item บรรทัดที่ 2 เป็นการนำค่า id เก็บในตัวแปร id
\item บรรทัดที่ 3 เป็นการนำค่าจาก session attraction\_id เก็บไว้ในตัวแปร getselects
\item บรรทัดที่ 4 เป็นการสร้าง array ชื่อ newgetselects
\item บรรทัดที่ 5-10 เป็นการวนลูปเพื่อตรวจสอบว่าค่า getselects เท่ากับค่า id หรือไม่ ถ้าไม่เท่ากันจะทำนำข้อมูลจาก getselect เพิ่มลง newgetselects และทำการเปลี่ยนค่า session attraction\_id ให้มีค่าเท่ากับ newgetselects
\item บรรทัดที่ 11-13 เป็นการตรวจสอบว่า newgetselects เท่ากับ null หรือไม่ ถ้าใช่จะทำการลบ session attraction\_id
\end{itemize}
\begin{figure}[H]
{\setstretch{1.0}\begin{lstlisting}
function delAllSelect(Request $request){
$request->session()->forget('attraction_id');
return Redirect::to('/');
}
\end{lstlisting}}
\caption{function delAllSelect}
\label{Fig:funcdelall}
\end{figure}
จากภาพที่ \ref{Fig:funcdelall} สามารถอธิบายการทำงานได้ดังนี้
\begin{itemize}[label={--}]
\item บรรทัดที่ 2 เป็นการลบ session ชื่อ attraction_id
\item บรรทัดที่ 3 เป็นการ redirect ไปที่ ‘/
\end{itemize}
\section{โครงสร้างของ ResultController}
\begin{figure}[H]
{\setstretch{1.0}\begin{lstlisting}
public function geturl($lat,$lng,$getselects){
$url = "https://maps.googleapis.com/maps/api/distancematrix/json?origins=".$lat.",".$lng."&destinations=";
$i=1;
foreach ($getselects as $getselect) {
$place = Attraction::where('attractions_id',$getselect )->get()->toArray();
foreach ($place as $p) {
$deslat=$p["Latitude"];
$deslng=$p["longitude"];
$url .= $deslat.",".$deslng;
}
if($i!=count($getselects)){
$i++;
$url .= "|";
}else {
$url .= "&key=AIzaSyAQLj-_PEe0qXFXtqhs_EdE-ZmC5zoReMs";
}
}
return $url;
}
\end{lstlisting}}
\caption{function geturl}
\label{Fig:funcgeturl}
\end{figure}
จากภาพที่ \ref{Fig:funcgeturl} สามารถอธิบายการทำงานได้ดังนี้
\begin{itemize}[label={--}]
\item บรรทัดที่ 2 เป็นการต่อสติงเพื่อใส่ค่าต้นทาง
\item บรรทัดที่4-17 เป็นการต่อสติงค่าปลายทาง
\item บรรทัดที่ 5 เปแนการดึงข้อสถานที่ท่องเที่ยวจาก database มาเก็บไว้ในตัวแปร place
\item บรรทัดที่ 18 ทำการ return ค่า url
\end{itemize}
\begin{figure}[H]
{\setstretch{1.0}\begin{lstlisting}
function getresult(Request $request){
$getselects = Session::get('attraction_id');
$lat=$request->input('lat');
$lng=$request->input('lng');
$url= $this->geturl($lat,$lng,$getselects);
$getselects = $this->getdistance($url,$getselects);
while (count($getselects)>1) {
$place = Attraction::where('attractions_id',end($this->results) )->get()->toArray();
foreach ($place as $p) {
$lat=$p["Latitude"];
$lng=$p["longitude"];
}
$url=$this->geturl($lat,$lng,$getselects);
$getselects = $this->getdistance($url,$getselects);
}
if(count($getselects)==1){
foreach ($getselects as $getselect) {
array_push($this->results,$getselect);
}
}
Session::put('result', 'have');
$dataresults=array();
foreach($this->results as $result){
$dataresult = Attraction::where('attractions_id',$result )->get()->toArray();
$dataresults=array_merge($dataresults,$dataresult);
}
return view('result')->with('dataresults',$dataresults);
}
\end{lstlisting}}
\caption{function getresult}
\label{Fig:funcgetresult}
\end{figure}
จากภาพที่ \ref{Fig:funcgetresult} สามารถอธิบายการทำงานได้ดังนี้
\begin{itemize}[label={--}]
\item บรรทัดที่ 2 เป็นการนำค่าจาก session attraction_id เก็บไว้ในตัวแปร getselects
\item บรรทัดที่ 3-4 เป็นการเอาค่าละติจูดและลองจิจูดมาเก็บในตัวแปร
\item บรรทัดที่ 5 เป็นการเรียกใช้งานฟังก์ชัน geturl
\item บรรทัดที่ 6 เป็นการเรียกใช้งานฟังก์ชัน getdistance
\item บรรทัดที่ 7-15 เป็นการวนลูปเพื่อเรียกใช้งานฟังก์ชัน geturl และ getdistance
\item บรรทัดที่ 6-20 เป็นการเพิ่มข้อมูลใน getselects ใส่ใน result
\item บรรทัดที่ 23-26 เป็นการนำค่าจาก result ไปดึงข้อมูลจาก database มาเก็บใน dataresult
\item บรรทัดที่ 27 เป็นการ return ไปหน้า result พร้อมส่งค่า dataresult ด้วย
\end{itemize}
\begin{figure}[H]
{\setstretch{1.0}\begin{lstlisting}
public function getdistance($url,$getselects){
$mindistance = null;
$index=null;
$client = new \GuzzleHttp\Client();
$response = $client->request('GET', $url);
$data = $response->getBody();
$get_rows = json_decode($data, true);
$get_elements = $get_rows["rows"];
$get_distance = $get_elements[0];
$get_value = $get_distance["elements"];
for ($i=0; $i < count($get_value); $i++) {
$text = $get_value[$i]["distance"]["text"];
$split= explode(" ",$text);
$distance = floatval($split[0]);
if($mindistance==null){
$mindistance = $distance;
$index=$i;
}else {
if ($mindistance>=$distance) {
$mindistance = $distance;
$index=$i;
}
}
}
$i=0;
foreach ($getselects as $getselect) {
if($i==$index){
$index=array_search($getselect, $getselects);
array_push($this->results,$getselects[$index]);
unset($getselects[$index]);
}
$i++;
}
return $getselects;
}
\end{lstlisting}}
\caption{function getdistance}
\label{Fig:getdistance}
\end{figure}
จากภาพที่ \ref{Fig:getdistance} สามารถอธิบายการทำงานได้ดังนี้
\begin{itemize}[label={--}]
\item บรรทัดที่ 4-5 เป็นการส่ง request เพื่อหาระยะทาง
\item บรรทัดที่ 6-10 เป็นการนำผลลัพธ์ระยะทางมาเก็บในตัวแปร
\item บรรทัดที่ 11-24 เป็นการหาปลายทางที่ใกล้ที่สุด
\item บรรทัดที่ 12 เป็นการนำค่าระยะทางที่เป็น string เก็บในตัวแปร \$text
\item บรรทัดที่ 13 เป็นการแยก string
\item บรรทัดที่ 14 เป็นการแปลงตัวอักษรเป็นตัวเลข
\item บรรทัดที่ 15-23 เป็นการเก็บค่าระยะทางที่สั้นที่สุดในตัวแปร mindistance
\item บรรทัดที่ 26-33 เป็นการเพิ่มปลายทางที่ใกล้ที่สุดใส่ในตัวแปร result
\end{itemize}
\ No newline at end of file
\chapter{การทดสอบระบบ}
การทดสอบการทำงานของระบบ โดยทำการทดสอบในลักษณะ Black-box Testing ซึ่งเป็นการทดสอบแบบที่ไม่สนใจการทำงานภายในของโปรแกรมว่าทำงานอย่างไร แต่จะเน้นไปที่ Input และ Result ซึ่งการทดสอบได้ผลดังนี้
\section{ทดสอบหน้า login}
\begin{table}[H]
\centering
\caption{ผลการทดสอบหน้า login}
\label{my-label1}
\begin{tabular}{ | p{4.5cm} | p{4.5cm} | p{4.5cm} | }
\hline
{\setstretch{1.0} }
{\multicolumn{1}{c}{\centering การทำงาน}} &
{\multicolumn{1}{c}{\centering เงื่อนไขการทดสอบ}} & {\multicolumn{1}{c}{\centering ผลการทดสอบ}} \\ \hline
\setstretch{1.0}{หน้า login}
& \setstretch{1.0}{กดที่ช่องกรอกข้อมูล}
& \setstretch{1.0}{ระบบแสดงตัวกระพริบ (cursor) เพื่อชี้ให้รู้ตำแหน่งของการพิมพ์อักขระ} \\
\cline{2-3}
& \setstretch{1.0}{พิมพ์อักขระ}
& \setstretch{1.0}{ระบบแสดงผลอักระที่ถูกพิมพ์} \\
\cline{2-3}
& \setstretch{1.0}{กดปุ่ม submit กรณียังไม่ได้กรอก username,password}
& \setstretch{1.0}{ระบบแสดงข้อความโปรดกรอกข้อมูล} \\
\cline{2-3}
& \setstretch{1.0}{กดปุ่ม summit กรณี username,password ไม่ถูกต้อง}
& \setstretch{1.0}{แสดงข้อความ username หรือ password ไม่ถูกต้อง} \\
\cline{2-3}
& \setstretch{1.0}{กดปุ่ม summit กรณี username,password ถูกต้อง}
& \setstretch{1.0}{ระบบแสดงหน้า admin} \\
\hline
\end{tabular}
\end{table}
\section{ทดสอบหน้า admin}
\begin{table}[H]
\centering
\caption{ผลการทดสอบหน้า admin}
\label{my-label1}
\begin{tabular}{ | p{4.5cm} | p{4.5cm} | p{4.5cm} | }
\hline
{\setstretch{1.0} }
{\multicolumn{1}{c}{\centering การทำงาน}} &
{\multicolumn{1}{c}{\centering เงื่อนไขการทดสอบ}} & {\multicolumn{1}{c}{\centering ผลการทดสอบ}} \\ \hline
\setstretch{1.0}{หน้า admin}
& \setstretch{1.0}{กดปุ่ม travel}
& \setstretch{1.0}{กลับไปหน้าค้นหาสถานที่ท่องเที่ยว} \\
\cline{2-3}
& \setstretch{1.0}{กดปุ่ม admin}
& \setstretch{1.0}{แสดงตัวเลือก หน้าแรก,เพิ่มข้อมู,logout} \\
\cline{2-3}
& \setstretch{1.0}{กดปุ่มลบ}
& \setstretch{1.0}{ระบบแสดงให้ยืนยันการลบ} \\
\cline{2-3}
& \setstretch{1.0}{กดปุ่ม ค้นหา}
& \setstretch{1.0}{แสดงรายชื่อสถานที่ท่องเที่ยวทั้งหมดในจังหวัดที่ค้นหา} \\
\cline{2-3}
& \setstretch{1.0}{กดตัวเลือก หน้าแรก}
& \setstretch{1.0}{ระบบแสดงหน้า admin} \\
\cline{2-3}
& \setstretch{1.0}{กดตัวเลือก เพิ่มข้อมูล}
& \setstretch{1.0}{ระบบแสดงหน้าเพิ่มข้อมูล} \\
\cline{2-3}
& \setstretch{1.0}{กดตัวเลือก log out}
& \setstretch{1.0}{ระบบทำงานออกจากระบบ พร้อมกลับไปหน้าค้นหาสถานที่ท่องเที่ยว} \\
\hline
\end{tabular}
\end{table}
\section{ทดสอบหน้า adminsearch}
\begin{table}[H]
\centering
\caption{ผลการทดสอบหน้า adminsearch}
\label{my-label1}
\begin{tabular}{ | p{4.5cm} | p{4.5cm} | p{4.5cm} | }
\hline
{\setstretch{1.0} }
{\multicolumn{1}{c}{\centering การทำงาน}} &
{\multicolumn{1}{c}{\centering เงื่อนไขการทดสอบ}} & {\multicolumn{1}{c}{\centering ผลการทดสอบ}} \\ \hline
\setstretch{1.0}{หน้า adminsearch}
& \setstretch{1.0}{กดปุ่มลบ}
& \setstretch{1.0}{ระบบทำการลบสถานที่ท่องเที่ยวที่เลือก} \\
\cline{2-3}
& \setstretch{1.0}{กดปุ่มแก้ไข}
& \setstretch{1.0}{ระบบแสดงหน้าอัพเดทข้อมูล} \\
\cline{2-3}
& \setstretch{1.0}{กดตัวเลือก หน้าแรก}
& \setstretch{1.0}{ระบบแสดงหน้า admin} \\
\cline{2-3}
& \setstretch{1.0}{กดตัวเลือก เพิ่มข้อมูล}
& \setstretch{1.0}{ระบบแสดงหน้าเพิ่มข้อมูล} \\
\cline{2-3}
& \setstretch{1.0}{กดตัวเลือก log out}
& \setstretch{1.0}{ระบบทำงานออกจากระบบ พร้อมกลับไปหน้าค้นหาสถานที่ท่องเที่ยว} \\
\cline{2-3}
& \setstretch{1.0}{กดปุ่ม travel}
& \setstretch{1.0}{กลับไปหน้าค้นหาสถานที่ท่องเที่ยว} \\
\cline{2-3}
& \setstretch{1.0}{กดปุ่ม admin}
& \setstretch{1.0}{แสดงตัวเลือก หน้าแรก,เพิ่มข้อมู,logout} \\
\hline
\end{tabular}
\end{table}
\section{ทดสอบหน้าแสดงรายละเอียดสถานที่ท่องเที่ยว}
\begin{table}[H]
\centering
\caption{ผลการทดสอบหน้าแสดงรายละเอียดสถานที่ท่องเที่ยว}
\label{my-label1}
\begin{tabular}{ | p{4.5cm} | p{4.5cm} | p{4.5cm} | }
\hline
{\setstretch{1.0} }
{\multicolumn{1}{c}{\centering การทำงาน}} &
{\multicolumn{1}{c}{\centering เงื่อนไขการทดสอบ}} & {\multicolumn{1}{c}{\centering ผลการทดสอบ}} \\ \hline
\setstretch{1.0}{หน้าแสดงรายละเอียดสถานที่ท่องเที่ยว}
& \setstretch{1.0}{กดปุ่มเลือกจังหวัด}
& \setstretch{1.0}{แจ้งเตือนว่าเลือกสำเร็จ} \\ \cline{2-3}
& \setstretch{1.0}{กดปุ่ม travel}
& \setstretch{1.0}{กลับไปหน้าค้นหาสถานที่ท่องเที่ยว} \\ \hline
\end{tabular}
\end{table}
\section{ทดสอบหน้าเพิ่มข้อมูล}
\begin{table}[H]
\centering
\caption{ผลการทดสอบหน้าเพิ่มข้อมูล}
\label{my-label1}
\begin{tabular}{ | p{4.5cm} | p{4.5cm} | p{4.5cm} | }
\hline
{\setstretch{1.0} }
{\multicolumn{1}{c}{\centering การทำงาน}} &
{\multicolumn{1}{c}{\centering เงื่อนไขการทดสอบ}} & {\multicolumn{1}{c}{\centering ผลการทดสอบ}} \\ \hline
\setstretch{1.0}{หน้าเพิ่มข้อมูล}
& \setstretch{1.0}{กดที่ช่องกรอกข้อมูล}
& \setstretch{1.0}{ระบบแสดงตัวกระพริบ (cursor) เพื่อชี้ให้รู้ตำแหน่งของการพิมพ์อักขระ} \\
\cline{2-3}
& \setstretch{1.0}{พิมพ์อักขระ}
& \setstretch{1.0}{ระบบแสดงผลอักระที่ถูกพิมพ์} \\
\cline{2-3}
& \setstretch{1.0}{กดปุ่ม admin}
& \setstretch{1.0}{แสดงตัวเลือก หน้าแรก,เพิ่มข้อมู,logout} \\
\cline{2-3}
& \setstretch{1.0}{กดตัวเลือก หน้าแรก}
& \setstretch{1.0}{ระบบแสดงหน้า admin} \\
\cline{2-3}
& \setstretch{1.0}{กดตัวเลือก เพิ่มข้อมูล}
& \setstretch{1.0}{ระบบแสดงหน้าเพิ่มข้อมูล} \\
\cline{2-3}
& \setstretch{1.0}{กดตัวเลือก log out}
& \setstretch{1.0}{ระบบทำงานออกจากระบบ พร้อมกลับไปหน้าค้นหาสถานที่ท่องเที่ยว} \\
\cline{2-3}
& \setstretch{1.0}{กดปุ่ม travel}
& \setstretch{1.0}{กลับไปหน้าค้นหาสถานที่ท่องเที่ยว} \\
\cline{2-3}
& \setstretch{1.0}{กดปุ่ม submit}
& \setstretch{1.0}{ระบบทำการแจ้งเตือน success} \\
\cline{2-3}
& \setstretch{1.0}{ไม่กรอกข้อมูล}
& \setstretch{1.0}{ระบแจ้งเตือนให้กรอกข้อมูล} \\
\hline
\end{tabular}
\end{table}
\section{ทดสอบหน้าแสดงลำดับการเดินทาง}
\begin{table}[H]
\centering
\caption{ผลการทดสอบหน้าแสดงลำดับการเดินทาง}
\label{my-label1}
\begin{tabular}{ | p{4.5cm} | p{4.5cm} | p{4.5cm} | }
\hline
{\setstretch{1.0} }
{\multicolumn{1}{c}{\centering การทำงาน}} &
{\multicolumn{1}{c}{\centering เงื่อนไขการทดสอบ}} & {\multicolumn{1}{c}{\centering ผลการทดสอบ}} \\ \hline
\setstretch{1.0}{หน้าแสดงสถานที่ท่องเที่ยวที่เลือก}
& \setstretch{1.0}{กดปุ่มลบที่เลือกทั้งหมด}
& \setstretch{1.0}{ลบสถานที่ท่องเที่ยวที่เลือกทั้งหมด พร้อมกลับไปหน้าค้นหาสถานที่ท่องเที่ยว} \\
\hline
\end{tabular}
\end{table}
\section{ทดสอบหน้าค้นหาสถานที่ท่องเที่ยว}
\begin{table}[H]
\centering
\caption{ผลการทดสอบหน้าค้นหาสถานที่ท่องเที่ยว}
\label{my-label1}
\begin{tabular}{ | p{4.5cm} | p{4.5cm} | p{4.5cm} | }
\hline
{\setstretch{1.0} }
{\multicolumn{1}{c}{\centering การทำงาน}} &
{\multicolumn{1}{c}{\centering เงื่อนไขการทดสอบ}} & {\multicolumn{1}{c}{\centering ผลการทดสอบ}} \\ \hline
\setstretch{1.0}{หน้าค้นหาสถานที่ท่องเที่ยว}
& \setstretch{1.0}{กดเลือกจังหวัด}
& \setstretch{1.0}{แสดงชื่อจังหวัดที่เลือก} \\ \cline{2-3}
& \setstretch{1.0}{กดค้นหา}
& \setstretch{1.0}{แสดงสถานที่ท่องในจังหวัดที่เลือก} \\
\cline{2-3}
& \setstretch{1.0}{กดปุ่ม admin}
& \setstretch{1.0}{แสดงหน้า login} \\ \hline
\end{tabular}
\end{table}
\section{ทดสอบหน้าแสดงสถานที่ท่องเที่ยวที่เลือก}
\begin{table}[H]
\centering
\caption{ผลการทดสอบหน้าแสดงสถานที่ท่องเที่ยวที่เลือก}
\label{my-label1}
\begin{tabular}{ | p{4.5cm} | p{4.5cm} | p{4.5cm} | }
\hline
{\setstretch{1.0} }
{\multicolumn{1}{c}{\centering การทำงาน}} &
{\multicolumn{1}{c}{\centering เงื่อนไขการทดสอบ}} & {\multicolumn{1}{c}{\centering ผลการทดสอบ}} \\ \hline
\setstretch{1.0}{หน้าแสดงสถานที่ท่องเที่ยวที่เลือก}
& \setstretch{1.0}{กดปุ่มลบที่เลือกทั้งหมด}
& \setstretch{1.0}{ลบสถานที่ที่เลือกทั้งหมดพร้อมกลับไปหน้าค้นหาสถานที่ท่องเที่ยว} \\ \cline{2-3}
& \setstretch{1.0}{กดปุ่ม travel}
& \setstretch{1.0}{กลับไปหน้าค้นหาสถานที่ท่องเที่ยว} \\
\cline{2-3}
& \setstretch{1.0}{กดปุ่มลบ}
& \setstretch{1.0}{ลบสถานที่ที่ทำการลบ} \\
\cline{2-3}
& \setstretch{1.0}{กดปุ่มค้นหาเส้นทาง}
& \setstretch{1.0}{แสดงหน้าลำดับการเดินทาง พร้อมเส้นทาง} \\
\hline
\end{tabular}
\end{table}
\section{ทดสอบหน้าอัพเดทข้อมูล}
\begin{table}[H]
\centering
\caption{ผลการทดสอบหน้าอัพเดทข้อมูล}
\label{my-label1}
\begin{tabular}{ | p{4.5cm} | p{4.5cm} | p{4.5cm} | }
\hline
{\setstretch{1.0} }
{\multicolumn{1}{c}{\centering การทำงาน}} &
{\multicolumn{1}{c}{\centering เงื่อนไขการทดสอบ}} & {\multicolumn{1}{c}{\centering ผลการทดสอบ}} \\ \hline
\setstretch{1.0}{หน้าอัพเดทข้อมูล}
& \setstretch{1.0}{กดที่ช่องกรอกข้อมูล}
& \setstretch{1.0}{ระบบแสดงข้อมูลเดิม} \\
\cline{2-3}
& \setstretch{1.0}{พิมพ์อักขระ}
& \setstretch{1.0}{ระบบแสดงผลอักระที่ถูกพิมพ์} \\
\cline{2-3}
& \setstretch{1.0}{กดปุ่ม admin}
& \setstretch{1.0}{แสดงตัวเลือก หน้าแรก,เพิ่มข้อมู,logout} \\
\cline{2-3}
& \setstretch{1.0}{กดตัวเลือก หน้าแรก}
& \setstretch{1.0}{ระบบแสดงหน้า admin} \\
\cline{2-3}
& \setstretch{1.0}{กดตัวเลือก เพิ่มข้อมูล}
& \setstretch{1.0}{ระบบแสดงหน้าเพิ่มข้อมูล} \\
\cline{2-3}
& \setstretch{1.0}{กดตัวเลือก log out}
& \setstretch{1.0}{ระบบทำงานออกจากระบบ พร้อมกลับไปหน้าค้นหาสถานที่ท่องเที่ยว} \\
\cline{2-3}
& \setstretch{1.0}{กดปุ่ม travel}
& \setstretch{1.0}{กลับไปหน้าค้นหาสถานที่ท่องเที่ยว} \\
\cline{2-3}
& \setstretch{1.0}{กดปุ่ม submit}
& \setstretch{1.0}{ระบบทำการแจ้งเตือน success} \\
\hline
\end{tabular}
\end{table}
\section{ทดสอบหน้าแสดงรายละเอียดสถานที่ท่องเที่ยว}
\begin{table}[H]
\centering
\caption{ผลการทดสอบหน้าแสดงรายละเอียดสถานที่ท่องเที่ยว}
\label{my-label1}
\begin{tabular}{ | p{4.5cm} | p{4.5cm} | p{4.5cm} | }
\hline
{\setstretch{1.0} }
{\multicolumn{1}{c}{\centering การทำงาน}} &
{\multicolumn{1}{c}{\centering เงื่อนไขการทดสอบ}} & {\multicolumn{1}{c}{\centering ผลการทดสอบ}} \\ \hline
\setstretch{1.0}{หน้าแสดงรายละเอียดสถานที่ท่องเที่ยว}
& \setstretch{1.0}{กดปุ่มเลือกจังหวัด}
& \setstretch{1.0}{แจ้งเตือนว่าเลือกสำเร็จ} \\ \cline{2-3}
& \setstretch{1.0}{กดปุ่ม travel}
& \setstretch{1.0}{กลับไปหน้าค้นหาสถานที่ท่องเที่ยว} \\ \hline
\end{tabular}
\end{table}
\chapter{สรุปและข้อเสนอแนะ}
ในการพัฒนาระบบท่องเที่ยวอีสาน พบว่าระบบสามารถทำงานได้
ตามที่วิเคราะห์และออกแบบไว้แต่ก็พบปัญหาและอุปสรรคระหว่างการพัฒนา ในบทนี้ผู้พัฒนาจึง
ขอสรุปความสามารถของระบบ ชี้แจงปัญหาและอุปสรรค พร้อมเสนอแนวทางในการพัฒนาระบบ
เช็คชื่อดัวยคิวอาร์โค้ดต่อตามลำดับ
\section{สรุปความสามารถของระบบ}
ระบบท่องเที่ยวอีสานสามารถสรุปความสามารถที่ระบบทำได้ดังนี้
\begin{enumerate}
\item ผู้ใช้งานทั่วไป
\begin{itemize}
\item ดูรายละเอียดสถานที่ท่องเที่ยว
\item เลือกสถานที่ท่องเที่ยว
\item ค้นหาสถานที่ท่องเที่ยว
\item ดูลำดับการเดินทาง
\end{itemize}
\item ผู้ดูแลระบบ
\begin{itemize}
\item เข้าสู่ระบบได้
\item เพิ่มข้อมูลสถานที่ท่องเที่ยว
\item ลบข้อมูลสถานที่ท่องเที่ยว
\item แก้ไขข้อมูลสถานที่ท่องเที่ยว
\item เพิ่มข้อมูลจังหวัด
\item ลบข้อมูลจังหวัด
\end{itemize}
\end{enumerate}
\section{ปัญหาและอุปสรรคในการพัฒนา}
\begin{enumerate}
\item เมื่อผู้ใช้กดค้นหาเส้นทางแต่ผู้ใช้ไม่อนุญาตไม่ทราบตำแหน่งปัจจุบันจะไม่สามารถหาลำดับการเดินทางได้ \\
แนวทางการแก้ไข : ทำการใช้ตำแหน่งสถานที่ท่องเที่ยวที่เลือกลำดับแรก เป็นจุดเริ่มต้นในการหาลำดับการเดินทาง
\end{enumerate}
\section{แนวทางการพัฒนาต่อ}
\begin{enumerate}
\item ออกแบบเว็บให้ดูน่าสนใจมากขึ้น
\item สามารถค้นหาสถานที่ท่องเที่ยวได้ทั้งประเทศไทย
\item สามารถแสดงเวลาที่ใช้ในการเดินทาง
\end{enumerate}
% Default language option is [thaithesis]. The other possible option is [engthesis].
% Default format option is [ugrad]. Other possible options are [master,doctor].
\documentclass[a4paper,thaithesis]{ubu}
% List all required packages here
% ทุก package รวมไว้ที่เดียว
\usepackage{coding}
%%------------------------------------------------------------
%%- SETTING THESIS PARAMETERS -
%%------------------------------------------------------------
%%----------------- ชื่อโครงงาน -----------%%
%% หัวข้อโครงงาน {ไทย} {English}
\thesistitle
{ท่องเที่ยวอีสาน}
{TravelEsan}
%%----------------- ผู้พัฒนาโครงงาน -----------%%
%% คำนำหน้า {ไทย} {English}
\authortitle
{นาย}
{Mr.}
%% ชื่อสกุล {ไทย} {English}
\thesisauthor
{ธนภูมิ สุปันนุช}
{Thanaphum Supannut}
%%---------------- ผู้ร่วมพัฒนาโครงงาน (ถ้ามี) -----------%%
%% คำนำหน้า {ไทย} {English}
\coauthortitle
%% ชื่อสกุล {ไทย} {English}
\thesiscoauthor
%%---------------- อาจารย์ที่ปรึกษาโครงงาน ----------%%
\advisor
{อาจารย์ วาสนา เหง้าเกษ}
{อาจารย์ วาสนา เหง้าเกษ}
{Wasana Ngaogate, Lecturer/Ph.D.}
{Wasana Ngaogate, Lecturer/Ph.D.}
%%---------------- อาจารย์ที่ปรึกษาโครงงาน (ถ้ามี) ----------%%
%\coadvisor
%{อาจารย์ ดร.ชื่อร่วม สกุล}
%{ดร. ชื่อร่วม สกุล}
%{Cofirstname Lastname, Ph.D.}
%{COFIRTNAME LASTNAME, Ph.D.}
%%---------------- ข้อมูลสถาบัน ----------%%
%% คณะ {ไทย} {English}
\faculty
{วิทยาศาสตร์}
{Science}
%% ภาควิชา {ไทย} {English}
\department
{คณิตศาสตร์ สถิติ และคอมพิวเตอร์}
{Mathematics Statistics and Computer}
%%---------------- ข้อมูลหลักสูตรและรายวิชา ----------%%
%% ชื่อหลักสูตร
\fieldofstudy
{วิทยาการคอมพิวเตอร์}
{Computer Science}
%% ชื่อปริญญา
\degree
{วิทยาศาสตรบัณฑิต}
{Bachelor of Science}
%% ปีการศึกษาที่ทำโครงงาน
\academicyear{2562}
%% รหัสประจำตัวนักศึกษา
\authorid{5711403250}
%% รหัสวิชา
\subjID{1104494}
%% ชื่อวิชา
\subjName
{โครงงานวิทยาศาสตร์}
{Senior Project}
%%---------------- หัวหน้าภาควิชา ----------%%
\deanname
{ผศ.ดร. สุพจน์ สีบุตร}
{ Asst. Prof. Supot Seebut, Ph.D.}
%%---------------- รายชื่อคณะกรรมการสอบโครงงาน -------%%
\committee
{
\CommitteeBlockAdvisor
\CommitteeBlockCoAdvisor
\CommitteeBlock{กรรมการ}{ดร.สุภาวดี หิรัญพงศ์สิน}
\CommitteeBlock{กรรมการ}{ดร.วาโย ปุยะติ}
}
%%-------------------------------------------------------------------------------
%%- DOCUMENT -
%%-------------------------------------------------------------------------------
\begin{document}
% หน้าปกภาษาไทย - Thai Cover
\makethaicover
\newpage
% หน้าปกภาษาอังกฤษ - English Cover
%\makeenglishcover
%\newpage
% หน้ารายชื่อคณะกรรมการสอบ - Committee page
%\makecommittee
\ThaiCommittee
\newpage
% หน้ากิตติกรรมประกาศจากไฟล์ acknowledgement.tex
\include{acknowledgement}
\newpage
% หน้าบทคัดย่อภาษาไทยจากไฟล์ abstractthai.tex
\include{abstractthai}
\newpage
% หน้าบทคัดย่อภาษาอังกฤษจากไฟล์ abstractenglish.tex
\include{abstractenglish}
\newpage
% คำสั่งสร้างรายการสารบัญ
\tableofcontents
\newpage
% คำสั่งสร้างรายการตาราง
\listoftables
\newpage
% คำสั่งสร้างรายการภาพอ้างอิง
\listoffigures
\newpage
% คำสั่งรวมไฟล์ต่างๆในโครงการ แยกรายบท
\include{1-introduction}
\include{2-background}
\include{3-design}
\include{4-implementation}
\include{5-testing}
\include{6-conclusion}
% คำสั่งรวมแหล่งอ้างอิง
\ULforem %%%
\setlength{\bibhang}{1.5cm}
\bibliographystyle{chulanat}
\bibliography{references} % ใช้แหล่งอ้างอิงจากไฟล์ชื่อ references.bib
\normalem
% รายการภาคผนวก - Appendix Section
\numappendices{3} % จำนวนภาคผนวก
\startappendix
\include{appendix1-setup}
%\include{appendix2-installation}
\include{appendix3-manual}
%% ข้อมูลผู้ดำเนินโครงการจากไฟล์ biography.tex - Biography Section
\include{biography}
\end{document}
<mxfile userAgent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36" version="8.5.12" editor="www.draw.io" type="device"><diagram name="Page-1" id="9f46799a-70d6-7492-0946-bef42562c5a5">7V1Zb9s4F/01BjIPKbRbfszSTh86QNHMN8tTQFu0raksGhITx/Prv0uJ1EbKVmItHoBFgFoUTUs8h+TlubzkzH7Yvf2aoP32NxLgaGYZwdvMfpxZlulYHvzHUo55iuf7ecImCQOeqUx4Cv/FPNHgqS9hgNNaRkpIRMN9PXFF4hivaC0NJQk51LOtSVT/1T3aYCnhaYUiOfXPMKBbnmoaRnnjKw43W/7TvstvLNHq5yYhLzH/vZllr7N/+e0dEmXx/OkWBeRQSbI/z+yHhBCaf9q9PeCI1a2otvx7X1ruFs+d4Jh2+cLcX3im6S7WhocXPvZvzXlexCuKXnhlPMXksCRH/sD0KCopPYS7CMVwdb+luwgSTfi4JjF94pnYNYrCTQyfV/BEOIGEV5zQEKr6jt+gZA+pq20YBd/Qkbyw504p1KO4ut+SJPwXikXiN+B2QjlrgGrVHE/sm5BsQGqCU8jzXVSGWSR9QynleVYkitA+DZfFA+9Qsgnje0Ip2fFM4k2/hFH0QCKSZBUgkIVSGeA4ELkFpnn5u3DFP0doiaP7giGipJhkdZjShPzEleKN7F9xRxAxq+TKg/Cvs3r/gnZhxJrcHzgJUIwEHHlNmRa/Vv2GTBzOJQYXfqskcSL9iskO0wRoYYi7nNNHcfnJzRMOlSbk8UzbSusBGvKmy5vtpii7pC584OztyOTiBUomz6x71huEmHUHd6xTOe6xxGt4XVrndB0aUeEyBoLrEV7TVqane7QK4823LM+jU6b84DXCkg7bkOInSGfPdIBOFtIIlLeOMmZtwyDAccY8iijKyctg3JMwplktuvfwB5X9wGBw4b0e4Nosr+GPZU+ADTG8Hwoz3DG0jANmrUPBiPbO4jxHOCnEwHCWEt4QjLA1I66OEa41JSNczYirY8Tcn5IRnmbE1THCNJwpKeFoSlwfJWxjQkqYCwUlGuhHYXNq1MmOPwP9DgCLcIn174wKj7emxAdb5oOtwDmbk3wnaUhDwspP8rwN/KeB2O1oLPpDNHqjpdFD0VsS3LAG/4tu+9MQw5t0OJAVEs2Ma2HGYtJRQTEK4GCDhRyGoyU5fC4Tqhw4pw2hhDL1ieNQFcB8uMZxcMdkT7gk+ww5SKnkhyshAnndtaLseeFCEA2SApRuM6HLPKUZpeQlWeGWWhIDN7zCBrdB7/CpOqu+k8AnOEI0fK3rtr2iassjwVdCDyQJHjHFKwo4aWVUK6OnlFHLrkuji87K6HwIZdTWyujQQ1fRafw3lFHb0oy4OkZMqozaWiu/PkZMqozaWga7PkZMq4zaWiy/QkpMqozabeqIpsSElOiqpA5DCV9BCS2W9wyx39FaHEIst1XuEC2JXkfbn1QSdbQb5WqZATSYkhltkoNmxvTMcDoOJr0wQ4K26jOBV9+SDYlRVHWc1GXlCgfwW0j/YslQffnV3+JODM9VucUu/+YF/IMpPXItGL1QwmAsfvcbyawGoeAXSvJXHL1ixhwlCl08IcLJcdIT4vGxtT9PSPbVuyRBx0oGTsmy5O8soZSwXbH0nVPENhoLyxv5Fyezw4f8AUqGFG/SiTSySZniOICUABpah74i83a0tsjHWQfvTGFctjgvqm6QdxCnzedZBDvwp55VAwZUTodb45Mj2jFHweFiwfuoImHrN7C16wWQ9ToFOje7gPcB3NpYKpA/kN0OxcEPvMLwMtoNp91wp91wjlUnbnc3nFgn3K8FpAXVoU2fotP4b7jhHL0c/foYMakbzmlTVjQjpmPEpG44t01R0YyYjhHTuuFc1XoeLbD3DHFXt9oQArsYg7RYdoVt3550OGhbp6OZMT0zJo1TcOXFGY9QfQ8RRrEWS7RYckYssZ2Gyiei5ytkLpTAKpmF1Nszm+V1Jbdw+fNld0TLNO/gojCluoP7cAdXdBiXiCVKSgzTv8k+gFtOgmcWnaFJMQ0pFHrJeKTwVJqqngr1i7BC/1AiPMRMyGuTSBO8j6AtZU3/jpL7G6gPqGLWKBj6zc/cJhY3dP8wGnv8KQcNr23FcpU+N5oi01LENCcdQ1TrVXOO7KB2n1NAKDMwbphtwViibYyxCaLQXAYjSKvEwkjwTAHSGKZkmgyTkUEhswxHhjan/ZIcaiZHToOH7A6JGDH4kivNjPGYoVj7PBwz2kyLVYTSNFwfa/SAqkW6u5hEtFAsex6OFO3TlXQPb41rpGA9Rb3P0Mbn+PxQLH4e0fiUF3zsExyEK7mT0Iq9VuxP7L+sEuyV3ifTGEKomasCQbUSd6qvKtp+76sVBwFYrb9vML3RI9ckbLBHdDfL0yDAImLHH0iQV7BugrbkvXx1A7NlRNgIUgnYmVXDdbLondZ4ChH/I2KByq+0drAnQ3SK0ydOheiI/ZR6DtGR4i7seXOH/UW9iPxV+LdKLOWCpK36GwXlrysV9IE4Dtn+TTB9SeJLWcK3uavtR1fucudXqGBIVGhnj6CcKVPuY/wRTfIkf0R7HJo/TiOGy/KMTrDL/HHOFNRCxPagswsYZsqrH2FuHTzv8lNptNGsjebuRrPrdl3MJ2aJlwyiws3RMKGyGMbM96Sc92kTqsWEMrujP0G0jym7EW65E0EvVRkF7TEjeUzZQGZoZ6/2/KbxHgPvMeN0TNnQLfE+arzHwHvUKBxTdvcwwOHFcFYnevgeAfAxt7pTnIzIIy2yiUYeYrGOMFJMbjXm/WE+5l52+pyXAQAccac6xYl/+YisxQEtDpwXB7yG4Oo6ig1DFgrq2kYP6oBCY9cWxkWjjdXLdiAqwPsYbBRauQ5oGR9ylUowGOTqSYRGezS0VRrBYGirYxiz9YFY4z0K3kqNYDDA1UskArJ62ZVjuIZ8YMhVKsFgkMszxkIHZOthNOJjIK7SCIZCvCUOWatCoyKuEhWGQlxxIiBDHKb2eza71y18hHmZMaLdpjwvT6uAlwGoWqyoArAHFVBxuh1rr63hnLr9Dg+/aof5wdqvWkhTh29q8EcQ1cbsvGVV7WmP8WorIazVf63+19T/Dqf2WoaCtqbYo/XE0twfbCf/eAMolUcmNLYnt+UusksYGoqAlzGi+J6Bcunq2tYj/lZQOjd2xSpf3V126C6L/uiiXbZUtOslrEO114E2dS/CT7Uhlgq/Hizd1iMF0mzIo4Q1y5tXEgZ6c5uRWq8ni4/Dtd62aHOGJyU5CcqI89o2R4wUmgfD8UC17ZWSB310A22D9j5CxxsN+4iwm6ascwzX/mXnw/9Sec9nOYyujJzLjOpaVF1jLnQ6cE4Rq9l3SKbo5KohdWLcOxtBp1pzdmFU3dytm+3mwqkX0TUq02+cq2X6jYO1eozKnIwoHc7nkyn0MaKIAOoqUdwpidJYTTa3jI8RZWGfKaiFKO89869xhp/Lu6i+zvDzZDfK2CS0TpwSaUnHRCqp0w8vzfFo2Ih4dPz5x1hozs8U1F935ckOmHGZUh+75u6s/TxR88NEEUupT8aK557tUYhi+4tPi7nh+j7YPdbCEZaM6HUM61OWbM49B7J9dC+C07/iM9mtuGfO/U4ce29P5zSG3rlz0XGlcJkQQqvZwYDd/pYvCfj8fw==</diagram></mxfile>
\ No newline at end of file
<mxfile userAgent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36" version="8.5.13" editor="www.draw.io" type="device"><diagram id="813d08ba-7be8-3800-d292-465b29ec56fa" name="Page-1">7Z3Pc5s4FMf/mhzDoN/iuM1ut4ftTGdy2PbI2iRm1jEeQhpn//oFG2xLEExc9IRk+9DGMpbgvY+kp68e+IbcPW3+zOP14ms2T5Y3OJxvbsjvNxgjikn5X1XytisRDO8KHvN0Xh90KLhP/0vqwrAufUnnybNyYJFlyyJdq4WzbLVKZoVSFud59qoe9pAt1VbX8WPSKrifxct26d/pvFjsSiUWh/IvSfq4aFpGPNp98k88+/cxz15WdXs3mDxsX7uPn+KmrvpCnxfxPHs9KiJ/3JC7PMuK3V9Pm7tkWdm2Mdvue5/f+XR/3nmyKoZ8oT7tn/Hypb70VX1ixVtjjPIbpd3LN59eF2mR3K/jWfXJa+n6smxRPC3Ld6j8M35e75zxkG6SsoFP+6sLyzcP2ar4HD+ly4qJL8nyZ1Kks7j8oD6FJC+SzbuXgfbGKaFLsqekyN/KQ+ovyNqcNW6kMe/rwXm0Lloc+a0pi2tcHvcVH0xW/lFb7R2T85YJXbSgbkIJaEHhpQVBIZRemnBvGwgTtodCH0yIOJwJG+A9MyENAU2I/DQh4HTSWMwzE3LAsbAJ3z0zIYMcC6kXJqSRtbAQMy8tCBkWYj/WJroJIcNC7MfiRDchaFjox+JENyFoWOjH4qRlQsDphPixONFNCBkWEj8WJ7oJIcNCOoTC1fy3SsMu362yVaKa7V3DJJu0+F4fVP39o7JkwKp3q/Ikv9eG3b75UR+3azqZt8RwzZTl6WUv+aw+qh6Lijh/TJqjeLfFjyzKOizalOXJMi7Sn+pZdJm5buFblpbnt3fofjJrQqyQqVXszr7+1sFZrYr2+w9NoMG0inbX3Kpo6/X9ZQ8DYciIfh4Ine7eoTDc4Yp3I6vexZp39X442LsRC0R09GJKvahZso3vbGau14/vbOmJs8MAh0cvzdlRaMzZQ2bJqThbXIKzsTDnbGzD2e/P9cMxODGjH+1G2yCDaGQwM2S06h2RjCEaqpNkvBNdg5HxIYeOBAol5kAZohSPCQoQJsQqJqgfE34uJqK3XobNYTJEDncQE+znaNK71GCCG8NkiOQPIjD8CihNSpBCCrVJCsElKZIJROt/VVAI7/r0o9hQyZVqETI3nAzZ15h8eNLJidU1DdHXNETr6sNZ6AMOCQ04jbgRQRmye+MmKFZFSyBQygmhb2QakRMrgiYIJ+wCODkxg43HSRN5e8iJVeUUKEDpa4QiKIasSKwgDFndagEaa2gExQn2lRNiVYQjujwrz1wnt7fizbHghR7byYJVqd7KwpgbHDPMybGQAgrvmFssCygsYKRaT4acMtRM4c16lpAg4kJQFBFGJYnO44SFKCBEirCpS2nkNkKBPP5Ua2VEiKDFWjODTRdEltUV+xAhDSIpjVFkTsu1TZFl6QWAIhr1NcJ62xgRIT9k3i6ELKsy1hE60ciIDPmhAHcxZFmxsc4QjqAY8kMd7mDI8krcfkBEWBTsqq+PMMWQ8EM57mLI8greOkOUQDHkh3LcNZfZVY77E2laiQzDsbGVliewMVLGpsGu51HZdY9fVPU8Lz8WkkaUY8IZOzuM0e5fDc053pxQDCkAduXa2dVurICC9UzPEUGBTtw1M5d0gWJ3bW0FFIJ7qx0RGz+04S5s7C6nrWBDQyhs/BCDu7C5wPiFSrVaY3sIwg8BuAsbu3sIQNiwQPIQIxYyIjghaiucMHUvyhhFfkjAHRRZll6mQJFAUBSZF4FvwyBEQkOpHF1PLr6+JXlaXkqS1yiOSJhdgdjK9MY40PTWJJ65tlifKA6YaTiQcXg4Ve+IQDgq8F4YEIQALZskvvLgAA8UQfHgaBrwpfEQQfHgqIh7YTwwARVQOqvOOrPTMx4j/ctaDLSslc4qsxO6O2ASyMgQChlHVVnv8VBnHc6AZp3IHA8eyxjb+0w5DhFTs4I4D4Ow7MYs4rI66synwW73aM5tZEQ2nNXepza9WOVFUChenE21nloEa5UXiYF42afSTTHT0W8A4HLVUOioLj69xDSro0IkwUYF7AUwE8gtsgoMQlBxBwodldant11vlxgMF3mYE98Np9pPLe3VODHa9oy55xyj0JwCf4FaSLVxwkwPGScaGRMOL7T2KSQdmgbm1O+vBAYhuarrzgERGQXCnIR6dfoJp6vdXhh1s6PKp+8I9P42EzNJBDInbV6JMEQENRobIEd10IsmwmhwgDB8cHBdb/4aEVX6uEEirAiZk/e79nDwjnH6XDWBtCqG0R/RNfl3xK5/wm8f6fqIH15NbtTRZCDJ4WWQDi9SgaesNY1JzFFyoFQaueXIHCLO/tqaK1te4yGiVNvcqGuCiav6OEn/9wwRkUEaHM3evGAasLm7zRC6SpSu4UDMPRUZYXP65AVqDyA4IGEQB3OjwyXiEAGkPpxoZEQ4iIWx4grATcddYQbTtImj2xMOLShHgyLY/6hZ9a86SUQBOfrRM2luyiD4OipMYlQwukdFHE2t9p2AviFAqGOAwSHguovhGhzV/iUQHI5uYlwwHBSBweHo9sUFw1HlywHB4eg+hvpEVrs35zDav+00lAmB1HpMapLE0R0Lze9Wb/zU/X7bqmOSnnd0c0L1vF3xoeV5RB3wPDWnLUJ63mqqS8vzHAWHJ41RGoqxOJAwD6Xak+taeKhRQaxSQdSQket9WtmxagLyDzMS9gWmp1oZExnsw0Bi96dF+pHBTCqrjLORgZxeHJUvNSrodKmI5DjjCCQU5mTLsR1v9Vlk/Y5HwrnhoGMzY9X2/HKZrp8rj78u0iK5X8dbb7zm8VqlIH5eJ7PK4g/pJilb+PS8iOdbYsI+RupTSPIi2fSz0Pb7eyZrsnmOuKAdXDRlXQgoZu3tPY4+MVTrWXWgomweW47XwgCFZbgusWCSNxUcRVICU0RERLZHndnZwr77X/RwDWutjDkGt7Wev+K3JC+LGm8dcMqzl9W86mJb/5/olmC9kLY73T6t7pgPPWnjvF7XVkgae7W73zTtBWsw1hYWGoMRRwxGGajB2mvuxmDUEYNxac5g5ds8y4rjEa+80MXXbJ5UR/wP</diagram></mxfile>
\ No newline at end of file
<mxfile userAgent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36" version="8.5.12" editor="www.draw.io" type="device"><diagram name="Page-1" id="13e1069c-82ec-6db2-03f1-153e76fe0fe0">7Vvdc5s4EP9rmMk9XAYkwPDoj7R56M10mpu566NiFJupjDxYjpP760+yJT4kEWMMTtO6eSishCR2f7/V7go7cLp6+Zyj9fIvmmDiADd5ceDMAcDjf/w/IXk9SIIoOAgWeZrITqXgIf0PS6Erpds0wZtaR0YpYem6LpzTLMNzVpOhPKe7ercnSuqzrtECG4KHOSKm9J80YUsp9Vy3bLjH6WIpp44C2fCI5j8WOd1mcj4HwKf9v0PzCqmxZP/NEiV0VxHBOwdOc0rZ4Wr1MsVE6Fap7fDcp4bWYt05zlibB9Q6nhHZyncnlK7l4tirUghf51pcblfkU45W/HKyW6YMP6zRXMh3HAdctmQrwu88fvlEM/YJrVIiIHCPyTNm6RzxhuKVXX5jrle+wjPOGX6piOT6P2O6wix/5V1UqzKKwpq83ZWGg6rLsmIzT3VEEiyLYuhSYfxC6syuv5Ghvu0G5w4ICZ9l8iiuFqx4T7tCv6RPmKSZ0ClXBNdSukZ7bfC28ZzRXDTgPOWL40PDGZH9v5ayY8bgPGGIP5IX94Sg9SZ93C9HGCLH822+SZ/xN7w50FFIhRW41ciYpIuMyxgVA2/4PGm2+FvczGDIJQQ9YjIpsD+lRKx6VqIfTuiWiUVPC8a6b4GkB1wEgYEDYIFBAHqAATRgYBi8Yo01TTO2ny2YOMFMMy/N2ZIuaIZI1cCNmkpSbjqWUmGeHd6wfpQX1jkVmZzyLLr03R506ZkuyYHje8p2NE9mXB17SrTk0/vQ5uJY94DNQEOh3fNsFprS1QplyTc85+q4GqhuIE6NSxoI2Ay0znGS8re9WqZqGd/q2wazjGWngOMZYmhKMMquvDH2oYtaJ7BZ52GN8Xx5NUzNMDC8qGHMOPuDB1heGHSJsKI+lBn9asoEUV2Z9nDI1CYY9aHO2FTnnetMIiee7C9iJ4qlZDxTTbFYyiGmfUv5egL2SBmjK96As2QsCh1CRuj8Rye646RWBjH1W9GfQl6OCWLc/dQGsulPjvZVwKc01aieWMTxbVAfYkO3+RzLp6qVC20gL4R1m+u5B0P5AjNjoL05i1dsZWFgxrvcjXNrAfdemdAVctHkPiGywYZNOZJZ3dXnwn+j0rGbPENbRqWPFw8giQGCn1i73PxPf+i8Y1Qnnm1T8C3E83rgnSXpTjdTvl9yByPNcqP45yr+jeXFJFASRdZo9EeLss2vTE1vBG81Pwo707NY1KsGgwHoGTY5YGluDoCosLKBBE81zfSLSeHIobq4U4/DRtc+9up9KlPEatLIV02wYT31NZ8JQ7rGmdh80WaJE/kcb5Z19+gtgHJc5q//Cl/i3nqepyTfhdO6HQWFoLL7v13YPdjdqZbNjmL9TGAb4YEeRbUGtXtkoB5BbYl420QV74KvD+XmtAgE6PlJVw9nLKVHMFgi9qMe7kQMnLxX/kaQAXHQD2Z893KYsaQlPWd5tZO8QWt0mt8F1qqQM0i2DC3HETrBRmf63xt1BRpdezHiWE1WRCdj72w2nhEgdOfpmaQ0uBR2deQ6u/WB+iMltJycfFRSBkBT2wVLWBA0bojNgXm5M4JGdhV8jQO9Tzy+6cbu9yb3h95qoV7Wacvqou7cNFCPrB7++P9irA79bqzu42Ma6Dey+o0wtyOtfitWBbAnVoX+5VjVUNbhli7qKRNlzqAOi7ZpjN65zK3NkK4vnAnzP8jbkux3pbRaJNZqvrK6+2V/NwN2RO4/wdqHcW61gFOv3fycIZ3XLc/iGkCvlW7SwzbP49trACVYDyM2PK3tLGC40iZsrgIVUIOtUKiTwdVBXBY7/SviL4b4MOjmmE9FfBjZ/XY7xIfa54BQ52V/iPc7pdtdkapzKdDDjMFpVtnNxoHxFu9Z+X8/TmghqIG21imAHqwMCNvGhNREUAHbEjgmxt/KQ68O9pTI19cONSEcxsUGQdwwUzsnG0DjeT2p6hGvjanWSVXNVuj8CVxW9dBRff40OPLAEWu2PjTQ/eGAsLB8APlRKxn6oYH9i0VnkEqG3xi3XysZPdcHu57l68cHMBrsKM5vOL5tU8k4M7htU9toXSw5/nnUNRBpXdtoC9xzaxtqnm61DeMXXT2yovG7WYnvio8ss6YTY5EjCV5cjlPmY/E7RjAFot0aom/BR/jOSt9xDfC09c1RNxCeShXg2+exUuU4wvlt+cPtQ/fy1/Hw7n8=</diagram></mxfile>
\ No newline at end of file
<mxfile userAgent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36" version="8.5.12" editor="www.draw.io" type="device"><diagram id="4d4f0bbd-8f27-e171-19e5-097d03e0079a" name="Page-1">7VpRk5o6FP41PN4dkoDCI9ht+9KZO7MPt33MSlSmaJwYV72/vkESQgIRV9G6nW4fCicJhHzf+c45iR6aLPdfGF4vvtGMFB70s72HPnkQAvFP/FdaDpUljMLKMGd5Jjtpw0v+P5FGX1q3eUY2RkdOacHztWmc0tWKTLlhw4zRndltRgvzrWs8Jy3DyxQXbet/ecYXlTWCY23/SvL5Qr0ZjOKq5RVPf84Z3a7k+zyIZse/qnmJ1bPkh24WOKO7hgk9e2jCKOXV1XI/IUW5tmrZqnGfHa31vBlZ8bMGBNWIN1xsiZrycWL8oBZDjBDrLm7SBV8WwgbEpZj4umzfcMz4C8e8bJ/lRTGhBWXHgcg//pWdOaM/SaNlNlMt6vvLmxld8c94mRcla76S4o3wfIpFg5wjYZzsnR8K6uUTtCR0STg7iC5ygCKgJCSS67/T6CrTogGssmHJp3n9XL2m4kIuq2OJw/YSP/teGnlxeryIvSiWluSTaorLmVC+oyxrA5IJsspbyviCzukKF8/a2gSqXDWxikVS5POVsL1SzulSNJBVlpSuUj5kTVaVRbpidBK0HpzK6RkobeiWTYlJuDOQY6TAPH8zn9WFhBz6L83FE2vEge8bkANogSmYOydcjrLwrKdxHsRjJ8ShQhapi7G8iCJlSVroJyfQZwu6fN2Kb0h3i5yTlzU+ru1OKLGJvOWNpQpNH8QbkQOahjuCoMMfoyH8MeoGS7hhoIAAyqIwikfyIlWuGoEWMu/ySyz9sSAzfmc3FSCxw3c5j+PNjxLzp7C83ee8bhLXuuUc5x47iCDC99HZmhrgJMc//hMSf9W4a0UAmkwLz9MAseL40Oi2LjtsTrwmtgg9ssJuT/8gtBhcTcAarGZDZ7MNuVqzYqdm3ZvrnK5vTHS/TfTh6NxI3DrpDIZhshXOAv9GVLbeA00qm9y8gHfKIdu8q0NkCnQclARUypwiO2imLa2OWhE2hZrI8skTk+N1DiYu1CuiRDe1gnCZ4pNM8rsnEGM2lTwO/MeOy0q3avCDjsAMOwJzMEBghs4sKkncGF/ADGHxW53rRA3qzh8m8XZH7SslUGHdI4EIdtPqSs1DwKKjXY85NK/3QWBsPaj65iFqAehIL4XmjG2qxrEtUJp90NSlRnWQAFO7hCX8zQI1gPSgsQlRdEflQY6YFDcCRqrXuleCdNXXqOgs5dHF/9hkw8Xq9OEgD4PfCDm8HPKzEToX8pPurqvSWj9qtWjn5X9oYoJC9GTu4N01NVHV6M1TkwGZ8PDJit5w+NHMTxpNKl0B5yUryqf7kpXoNsmKVdMjm3gDFWiB2kJVjuCf3muAVmC1+l9d0KHRIL7RGTM/HKcHScA7+Gvk5FEHpx17EFdyOohM7sQX5t+htQ1XH/QNn3+jd+TfpwXV1mzfJmjdOQ76xfsBs/a7RW9ol18dx2+3i93Ojc5T+nRpFLapFtqvuDkLGxlsEra+4u+mhpaIvn3dG+UJlhYC+1BruHPJoKOubcF/6nS/xPDxz/ZD63BfZTj3ON0PQLe6NGvEtga8s9L/s3Mmsw4AnrsO8N3+3ZMzKaib/h3cJmcKoclGgMLLkqZRYNPaepAjaXpvQTFy/FDCOS/7hOi6gkLc6t87Vd31j8rQ8y8=</diagram></mxfile>
\ No newline at end of file
<mxfile userAgent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36" version="8.5.12" editor="www.draw.io" type="device"><diagram id="120ff508-374b-bf88-8e7a-aaa9685ebcdc" name="Page-1">5VlLk+I2EP41PoayJD+PGGayqUqqpjKH7B4F1oBrbcuxxcDk16eFJduSzYZQwLK1cxmp1Xp9/fVDxiGL4vBrTavtHzxluYPd9OCQpYMx8nAA/6Tko5WE2G0FmzpLlVIveM3+YUqo1XZZyhpDUXCei6wyhWtelmwtDBmta7431d54bu5a0Q0bCV7XNB9L/8pSsW2lEQ57+SeWbbZ6ZxTE7ciKrr9uar4r1X4OJm/Hv3a4oHotddFmS1O+H4jIk0MWNeeibRWHBcslthq2dt7zidHu3DUrxTkT1LHfab5j+sTHc4kPjcV+mwn2WtG17O/B3g5JtqLIoYegSZuqtcBbdmCwavLGS/FMiyyXtv/E8ncmsjWFAbUVqwU7nDwu6kAAcjFeMFF/gMp+aAWF3XZggU5IleU33dz+9tBQAJxAD0+gEeSwRbKCxkYcL9EK5C0NnIK/d1wP/NIcGT0HBexVh36wW+XJdZLImS91w1eNBKlGDJZxdTuxR6Ol3UiwrTwneqhbx9MS3ZjHeqjViZ1ooSW6kcR6SCtHcy2J9DqhbnSIAdgtRiZuIB5gaVENiCFMdt2ETGoCJoozKkghv+0OuEY0JYZcI9egGvlBHK8L6SZWsTvCyp/yS/8qfumPwFoyIS8Pm3Gx53U6Ag9WgGQBneQ/YLwlal5gMcwbw4Ymw9k1UItGqM3XgtcjqCAHVbK5K/JWgSTy1oBC/jtdsfyFN5nIeAkqKy4EL0AhlwNJl+wWPJfzln2669eY59lGzhXcQp7vRJ6VbNHlcPfG5vBNa2B/wuEnjBFcwRjayEN/t8N0F/pl3vitrHYyeNJColaummoqYD4Ey0lo4krcO7JcV5oDYF8FhfILajF5xgJq08eEzU4/eAo2bwK28BqwTRR+io+j5B7p5B5huxLoCxhkVgtdSQPK3qgywTbl1RagrGuVKBnVKmRUojzbs/o6ZDkx6yFp4FlRqcsZ96ABmQhLOuaocm3Yy8p1vpP+pIQbQ2W6pmMpvKxUt+QlM5FlZTqX7zXo8oqVE2mjSzkpbbayzjnOO5F/1AYn7cUOmfgsM83MV70v3UEAusGQ7H5ROam9k7zIt20M9+a7es3MkC9ovWFi6HbffN4gbf+a5VRk7+aeU8ZWy73w7Pgk0eEliExe2dG2PauaNXwiWgt5rhXeQ99cqL3gaKEj97o7nkfHcVX8J2sqXjaPGsPR93Re7yd13oHrDrz189CT+7ELnTceO2/Lzrs4L4ksn4ssnzvXee2FvPh2zhv+LzrCU5/JMu1qbGzgKsLi44ChasJRS31whMf93fKNG2ODthGJVP+F1RnAzGpN7btkonuSGfkz36JzOLuQ0JCNZihGgRcGbkgCK8kRL55FLmiFhMSx7TRX5PoZ303Pjp1q8CQRT7OrY8o47GnmIYN1xPo7QcHLaKY/OBgFT3A3msXWc8ouU85lGA7sese9FY28qfL7/jR6EKq4340ql2ZXZGVXjG8WcTz0kxZ7s9gNDWIiPzwZ+9BVWaq/LQ1Z2n6Lvk/etL6rYXJpzrQjGroWTaHb/1bZqvc/CJOnfwE=</diagram></mxfile>
\ No newline at end of file
\section{ }
\subsection{ }
\begin{itemize}
\item
\end{itemize}
\begin{enumerate}
\item
\end{enumerate}
\begin{figure}[h]
\centering
\includegraphics[scale=0.5]{Figures/2/}
\caption{}
\label{Fig:rbg-image}
\end{figure}
\begin{figure}[h]
\includegraphics[width=\columnwidth]{Figures/2/}
\caption{ }
\label{Fig:}
\end{figure}
\begin{figure}[h]
\begin{lstlisting}
\end{lstlisting}
\caption{ }
\label{Fig: }
\end{figure}
\begin{table}[h]
\caption{ตารางขั้นตอนการดำเนินการ}
\begin{tabular}{c}
\includegraphics[width=\columnwidth]{Figures/table/use-case} \\
\end{tabular}
\end{table}
\ No newline at end of file
## ฟอนต์ที่ควรติดตั้งก่อน
* Tex-Gyre [https://ctan.org/pkg/tex-gyre?lang=en](https://ctan.org/pkg/tex-gyre?lang=en)
* th-sarabun-new [https://www.f0nt.com/release/th-sarabun-new/](https://www.f0nt.com/release/th-sarabun-new/)
## โปรแกรมที่ต้องติดตั้ง
หมายเหตุ: สำหรับผู้ใช้ Windows แนะนำให้ติดตั้ง `https://chocolatey.org`
1. ติดตั้ง texlive สำหรับ compile latex
* Windows - http://mirror.ctan.org/systems/texlive/tlnet/install-tl.zip
* Ubuntu - `sudo apt install texlive-full`
* OSX - `brew cask install mactex`
2. ติดตั้ง pygments สำหรับ syntax hilighting
* Windows - `pip install pygments`
* Ubuntu - `sudo apt install python-pygments python3-pygments`
## วิธีการ compile
```sh
xelatex -interaction=nonstopmode -file-line-error -synctex=1 MathCS-tutorial.tex
```
* คำสั่ง compile บนระบบปฏิบัติการที่มี `latexmk`
```sh
latexmk -g -f CS58*.tex
```
### คำสั่งสร้าง bibliography
```sh
bibtex CS58*.aux
```
### คำสั่งแปลง .eps เป็น .pdf
```sh
pdf2eps [no_page_in_pdf] [figure_file_name]
```
### วิธีการรัน
```
Compilation: *require XeTeX
[When citations/references are changed.]
1. xelatex -interaction=nonstopmode -file-line-error -synctex=1 MathCS-tutorial.tex
2. bibtex MathCS-tutorial.aux
3. xelatex -interaction=nonstopmode -file-line-error -synctex=1 MathCS-tutorial.tex
4. xelatex -interaction=nonstopmode -file-line-error -synctex=1 MathCS-tutorial.tex
[When citations/references are not changed.]
1. xelatex -interaction=nonstopmode -file-line-error -synctex=1 MathCS-tutorial.tex
```
\begin{englishabstract}
TravelEsan aims to provide a sequence of travel routes of attractions of the Northeastern region including detail of each route. Attraction information and location is also given. TravelEsan is developed by using the Laravel framework and bootstrap. The Distance matrix API is used for distance calculation.
\end{englishabstract}
\begin{thaiabstract}
ระบบท่องเที่ยวอีสานมีจุดประสงค์จัดทำขึ้นเพื่อเป็นการบอกลำดับการเดินทางไปยังสถานที่ท่องเที่ยวในภาคตะวันออกเฉียงเหนือที่ผู้ใช้งานสนใจ พร้อมแสดงเส้นทางการเดินทางไปยังสถานที่เหล่านั้น อีกทั้งยังแสดงข้อมูลสถานที่ท่องเที่ยว เช่น รายละเอียดของสถานที่ท่องเที่ยว และตำแหน่งของสถานที่ท่องเที่ยว การพัฒนาระบบท่องเที่ยวอีสานใช้ Laravel Framework และBootstrap ในการพัฒนาเว็บไซต์ และใช้ Distance Matrix API ในการหาระยะทาง
\end{thaiabstract}
\begin{acknowledgements} %TODO update here!
การพัฒนาโครงงานระบบท่องเที่ยวอีสาน สำเร็จลุล่วงได้ด้วยความกรุณาและความช่วยเหลือจากหลายๆท่าน ข้าพเจ้าขอขอบพระคุณทุกท่าน ที่มีส่วนร่วมในการพัฒนาโครงงานนี้
ขอขอบพระคุณอาจารย์วาสนา เหง้าเกษ อาจารย์ที่ปรึกษาโครงงานที่ได้แนะนำทฤษฎีและแนวทางในแก้ปัญหาต่าง ๆ ที่เกิดขึ้นระหว่างการพัฒนาระบบ อีกทั้งยังคอยตรวจสอบความก้าวหน้าของการทำงานเป็นระยะ รวมทั้งสร้างกำลังใจให้ผู้พัฒนาอยู่เสมอ
ขอขอบพระคุณทุกแหล่งข้อมูลที่ไม่สามารถเอ่ยนามได้หมด ที่ได้ให้ความร่วมมือเป็นอย่างดี
ขอกราบขอบพระคุณบิดา มารดา ที่คอยให้กำลังใจ คอยให้ความรักและความห่วงใยเสมอมา
ตลอดจนคอยช่วยเหลือทุนทรัพย์ทางด้านการศึกษาและอุปกรณ์ในการพัฒนาโครงงาน
\end{acknowledgements}
\begin{flushright}
นายธนภูมิ สุปันนุช
\\
พฤษภาคม 63
\end{flushright}
\chapter{การติดตั้งเครื่องมือที่ใช้พัฒนาโปรแกรม}
การติดตั้งเครื่องมือที่ใช้ในการพัฒนาเว็บแนะนำและสร้างแผนการท่องเที่ยว มีโปรแกรมที่จำเป็นในการพัฒนาระบบดังต่อไปนี้
\begin{itemize}
\item การติดตั้ง VisualStudioCode
\item การติดตั้ง XAMPP
\end{itemize}
\section{การติดตั้ง Visual Studio Code}
\begin{enumerate}
\item สามารถดาวน์โหลด VisualStudioCodeได้ที่https://code.visualstudio.com/download ดังแสดงในรูปที่ \ref{Fig:VisualStudioCode1}
\begin{figure}[H]
\includegraphics[width=\columnwidth]{Figures/7/1}
\caption{หน้าเว็บดาวน์โหลด Visual Studio Code}
\label{Fig:VisualStudioCode1}
\end{figure}
\newpage
\item แสดงหน้าต่างต้อนรับของ Visual Studio Codeทำการกด Next เพื่อเริ่มกระบวนการติดตั้ง ดังแสดงในรูปที \ref{Fig:VisualStudioCode2}
\begin{figure}[H]
\centering
\includegraphics[width=0.7\columnwidth]{Figures/7/2}
\caption{หน้าต่างต้อนรับของ Visual Studio Code}
\label{Fig:VisualStudioCode2}
\end{figure}
\item แสดงหน้าต่างข้อตกลงการใช้งาน Visual Studio Code ทำการกด IAgree ดังแสดงในรูปที่ \ref{Fig:VisualStudioCode3}
\begin{figure}[H]
\centering
\includegraphics[width=0.7\columnwidth]{Figures/7/3}
\caption{หน้าต่างข้อตกลงการใช้งาน Visual Studio Code}
\label{Fig:VisualStudioCode3}
\end{figure}
\item แสดงหน้าต่างที่จัดเก็บไฟล์ต่างๆของ Visual Studio Codeทำการกด Next ดังแสดงในรูปที
\ref{Fig:VisualStudioCode4}
\begin{figure}[H]
\centering
\includegraphics[width=0.7\columnwidth]{Figures/7/4}
\caption{หน้าต่างที่จัดเก็บไฟล์ต่างๆของ Visual Studio Code}
\label{Fig:VisualStudioCode4}
\end{figure}
\item แสดงหน้าต่างเริ่มทำการติดตั้งทำการกด Install ดังแสดงในรูปที \ref{Fig:VisualStudioCode5}
\begin{figure}[H]
\centering
\includegraphics[width=0.7\columnwidth]{Figures/7/5}
\caption{หน้าต่างติดตั้งโปรแกรม Visual Studio Code}
\label{Fig:VisualStudioCode5}
\end{figure}
\item แสดงหน้าต่างผลการติดตั้ง Visual Studio Code ดังแสดงในรูปที \ref{Fig:VisualStudioCode6}
\begin{figure}[H]
\centering
\includegraphics[width=0.7\columnwidth]{Figures/7/6}
\caption{ หน้าต่างผลการติดตั้ง Android Studio}
\label{Fig:VisualStudioCode6}
\end{figure}
\end{enumerate}
\newpage
\section{การติดตั้ง XAMPP }
\begin{enumerate}
\item สามารถดาวน์โหลด XAMPP ได้ที่ https://www.apachefriends.org/index.html ดังแสดง ในรูปที \ref{Fig:XAMPP1}
\begin{figure}[H]
\includegraphics[width=\columnwidth]{Figures/7/x1}
\caption{หน้าเว็บดาวน์โหลด XAMPP}
\label{Fig:XAMPP1}
\end{figure}
\newpage
\item แสดงหน้าต่างติดตั้ง (setup) ของ XAMPP ทำการกด Next เพื่อเริ่มกระบวนการติดตั้งดัง แสดงในรูปที \ref{Fig:XAMPP2}
\begin{figure}[H]
\includegraphics[width=\columnwidth]{Figures/7/x2}
\caption{หน้าสำหรับติดตั้ง XAMPP}
\label{Fig:XAMPP2}
\end{figure}
\newpage
\item แสดงหน้าต่างทำการเลือก Components ที่เราต้องการใช้งาน XAMPP และกด Next ดัง แสดงในรูปที่
\ref{Fig:XAMPP3}
\begin{figure}[H]
\centering
\includegraphics[width=0.7\columnwidth]{Figures/7/x3}
\caption{หน้าต่างเลือก Components ที่ต้องการใช้งาน XAMPP}
\label{Fig:XAMPP3}
\end{figure}
\newpage
\item แสดงหน้าต่างเลือกโฟลเดอร์ที่จะทำการติดตั้งและกด Next ดังแสดงในรูปที \ref{Fig:XAMPP4}
\begin{figure}[H]
\centering
\includegraphics[width=0.7\columnwidth]{Figures/7/x4}
\caption{หน้าต่างเลือกโฟลเดอร์ที่จะทำการติดตั้ง XAMPP}
\label{Fig:XAMPP4}
\end{figure}
\item แสดงหน้าต่างติดตั้งเสร็จสิ้นและทำการกด Finish เพื่อจบการติดตั้งดังแสดงในรูปที \ref{Fig:XAMPP5}
\begin{figure}[H]
\centering
\includegraphics[width=0.7\columnwidth]{Figures/7/x5}
\caption{หน้าต่างเสร็จสิ้นการติดตั้ง XAMPP}
\label{Fig:XAMPP5}
\end{figure}
\chapter{คู่มือการติดตั้งระบบ}
ในการติดตั้งเพื่อใช้งานแอปพลิเคชันระบบกองทุนเงินให้กู้ยืมเพื่อการศึกษา คณะวิทยาศาสตร์ มหาวิทยาลัยอุบลราชธานี หรือ ESP สามารถทำได้โดยมีขั้นตอนดังนี้
\begin{enumerate}
\item สามารถดาวน์โหลด ESP installer package ได้ที่ https://drive.google.com/drive/folders/1k6HnoFgLAatgrfLAtFgnJYbRrpJHHwol ดังแสดงในรูปที่ \ref{Fig:dl1}
\begin{figure}[H]
\centering
\includegraphics[width=\columnwidth]{Figures/7/installApp/dl}
\caption{หน้าเว็บดาวน์โหลด ESP installer package}
\label{Fig:dl1}
\end{figure}
\item ดัดลอกไฟล์ app-debug.apk ที่อยู่ในแฟ้มงาน(Folder)ที่อยู่บนคอมพิวเตอร์ไปไว้ในหน่วยความจำบนอุปกรณ์ที่ต้องการ ดังแสดงในรูปที่ \ref{Fig:dl2}
\begin{figure}[H]
\centering
\includegraphics[width=0.3\columnwidth]{Figures/7/installApp/1}
\caption{ไฟล์ app-debug.apk บนอุปรกรณ์}
\label{Fig:dl2}
\end{figure}
\item ทำการเปิดไฟล์ app-debug.apk และกด INSTALL เพื่อทำการติดตั้ง ดังแสดงในรูปที่ \ref{Fig:dl3}
\begin{figure}[H]
\centering
\includegraphics[width=0.3\columnwidth]{Figures/7/installApp/2}
\caption{หน้าจอต้อนรับการติดตั้งแอปพลิเคชันบนอุปรกรณ์แอนดรอย์}
\label{Fig:dl3}
\end{figure}
\item เมื่อทำการติดตั้งแอปพลิเคชันสำเร็จระบบจะแสดงผล ดังแสดงในรูปที่ \ref{Fig:dl4}
\begin{figure}[H]
\centering
\includegraphics[width=0.3\columnwidth]{Figures/7/installApp/3}
\caption{หน้าจอต้อนรับการติดตั้งแอปพลิเคชันบนอุปรกรณ์แอนดรอย์}
\label{Fig:dl4}
\end{figure}
\end{enumerate}
\chapter{คู่มือการใช้งานระบบ}
คู่มือการใช้งานระบบท่องเที่ยวอีสานมีรายละเอียดดังนี้
\begin{enumerate}
\begin{figure}[H]
\begin{center}
\includegraphics[width=\columnwidth]{Figures/7/Manual/1}
\caption{หน้าจอหลักของระบบ}
\label{Fig:a01}
\end{center}
จากรูปที่ \ref{Fig:a01} แสดงหน้าจอหลัก ผู้ใช้งานต้องเลือกจังหวัดและกดปุ่ม ค้นหา เพื่อดูสถานที่ท่องเที่ยวในจังหวัดนั้น
เมื่อกดปุ่ม admin จะเข้าสู่หน้า login สำหรับ admin
\end{figure}
\begin{figure}[H]
\begin{center}
\includegraphics[width=\columnwidth]{Figures/7/Manual/2}
\caption{หน้าlogin}
\label{Fig:a02}
\end{center}
จากรูป \ref{Fig:a02} เป็นหน้าเข้าสู่ระบบของ admin โดยจะต้องกรอกข้อมูลให้ถูกต้องและกดปุ่ม submit
\end{figure}
\begin{figure}[H]
\begin{center}
\includegraphics[width=\columnwidth]{Figures/7/Manual/3}
\caption{หน้าadmin}
\label{Fig:a03}
\end{center}
เมื่อเข้าสู่ระบบสำเร็จจะแสดงหน้า admin ดังรูปที่ \ref{Fig:a03} กดปุ่ม ลบ จะทำการลบข้อมูลสถานที่ท่องเที่ยวในจังหวัดนั้นทั้งหมดออก กดปุ่ม ค้นหา เพื่อดูสถานที่ท่องเที่ยวในจังหวัดนั้น กดปุ่ม เพิ่มข้อมูล เพื่อไปหน้าเพิ่มข้อมูลอ กดปุ่ม Log out เพื่อออกจากระบบและกลับไปแสดงหน้าจอหลัก
\end{figure}
\begin{figure}[H]
\begin{center}
\includegraphics[width=\columnwidth]{Figures/7/Manual/4}
\caption{หน้า adminsearch}
\label{Fig:a04}
\end{center}
เมื่อกดปุ่ม ค้นหา จากรูป \ref{Fig:a03} จะแสดงหน้าดังรูป \ref{Fig:a04} กดปุ่ม ลบ เพื่อลบข้อมูลสถานที่ท่องเที่ยวนั้น
กดปุ่ม แก้ไข เพื่อไปยังหน้าแก้ไขข้อมูลสถานที่ท่องเที่ยว
\end{figure}
\begin{figure}[H]
\begin{center}
\includegraphics[width=\columnwidth]{Figures/7/Manual/5}
\caption{หน้าแก้ไขข้อมูล}
\label{Fig:a05}
\end{center}
เมื่อกดปุ่ม แก้ไข จากรูป \ref{Fig:a03} จะแสดงหน้าให้กรอกข้อมูลดังในรูป \ref{Fig:a05} เมื่อให้การกรอกข้อมูลครบกดปุ่ม submit เพื่อบันทึกข้อมูล
\end{figure}
\begin{figure}[H]
\begin{center}
\includegraphics[width=\columnwidth]{Figures/7/Manual/6}
\caption{หน้าเพิ่มข้อมูล}
\label{Fig:a06}
\end{center}
เมื่อกดปุ่ม เพิ่มข้อมูล ตรงnavbar จะแสดงหน้าดังในรูป \ref{Fig:a06} เมื่อให้การกรอกข้อมูลครบกดปุ่ม submit เพื่อบันทึกข้อมูล
\end{figure}
\begin{figure}[H]
\begin{center}
\includegraphics[width=\columnwidth]{Figures/7/Manual/7}
\caption{หน้าแสดงสถานที่ท่องเที่ยว}
\label{Fig:a07}
\end{center}
เมื่อกดปุ่ม ค้นหา จากรูป \ref{Fig:a01} จะแสดงหน้าแสดงสถานที่ท่องเที่ยวดังรูป \ref{Fig:a07} เมื่อกดปุ่ม รายละเอียด จะแสดงหน้ารายละเอียดดังรูป \ref{Fig:a08} กดปุ่ม เลือก เพื่อเลือกสถานที่ท่องเที่ยวที่สนใจ กดปุ่ม สถานที่ที่เลือก เพื่อดูสถานที่ท่องเที่ยวที่ผู้ใช้กดเลือก
\end{figure}
\begin{figure}[H]
\begin{center}
\includegraphics[width=\columnwidth]{Figures/7/Manual/8}
\caption{หน้าแสดงรายละเอียด}
\label{Fig:a08}
\end{center}
เมื่อกดปุ่ม เลือก จากรูป \ref{Fig:a08} จะทำการเลือกสถานที่ท่องเที่ยวนี้
\end{figure}
\begin{figure}[H]
\begin{center}
\includegraphics[width=\columnwidth]{Figures/7/Manual/9}
\caption{หน้าแสดงสถานที่ท่องเที่ยวที่เลือก}
\label{Fig:a09}
\end{center}
เมื่อกดปุ่ม สถานที่ที่เลือก จากรูป \ref{Fig:a07} จะแสดงสถานที่ท่องเที่ยวที่ผู้ใช้กดเลือกดังรูป \ref{Fig:a09} เมื่อกดปุ่ม ลบที่เลือกทั้งหมด จะทำการลบสถานที่ที่ผู้ใช้เลือก
\end{figure}
\begin{figure}[H]
\begin{center}
\includegraphics[width=\columnwidth]{Figures/7/Manual/10}
\caption{หน้าแสดงลำดับการเดินทาง}
\label{Fig:a10}
\end{center}
เมื่อกดปุ่ม ค้นหาเส้นทาง จากรูป \ref{Fig:a09} จะแสดงลำดับการเดินทางดังรูป \ref{Fig:a10}
\end{figure}
\end{enumerate}
{\setstretch{1.0}\begin{biography}
\justify
ชื่อ-สกุล: นายธนภูมิ สุปันนุช \\
รหัสประจำตัวนักศึกษา: 5711403250\\
วัดเกิด: 7 05 2539\\
ที่อยู่ที่สามารถติดต่อได้: 239 หมู่1 บ้านทุ่งแต้ ตำบลทุ่งแต้ อำเภอเมือง จังหวัดยโสธร 35000\\
เบอร์โทรศัพท์: (+66) 93 320 2389\\
อิเมลล์: thanaphum.su.57@ubu.ac.th\\
ระดับมัธยมต้น: โรงเรียนยโสธรพิทยาคม จังหวัดยโสธร\\
ระดับมัธยมปลาย: โรงเรียนยโสธรพิทยาคม จังหวัดยโสธร\\
ระดับอุดมศึกษา: ภาควิชาคณิตศาสตร์ สถิติ และคอมพิวเตอร์ สาขาวิทยาการ คอมพิวเตอร์ คณะวิทยาศาสตร์ มหาวิทยาลัยอุบลราชธานี
\end{biography}}
%% File: `chulanat.bst'
%% A modification of `plainnat.bst' for use with natbib package
%%
%% Author: Supasate Choochaisri
%% - modify to handle various Chula reference formats.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Changelog
%% July 6, 2015
%% - add "" to format.article.pages to prevent empty pop
%% Copyright of `plainnat.bst' 1993-2007 Patrick W Daly
%% Max-Planck-Institut f\"ur Sonnensystemforschung
%% Max-Planck-Str. 2
%% D-37191 Katlenburg-Lindau
%% Germany
%% E-mail: daly@mps.mpg.de
%%
%% This program can be redistributed and/or modified under the terms
%% of the LaTeX Project Public License Distributed from CTAN
%% archives in directory macros/latex/base/lppl.txt; either
%% version 1 of the License, or any later version.
%%
% Version and source file information:
% \ProvidesFile{natbst.mbs}[2007/02/19 1.92 (PWD)]
%
% BibTeX `plainnat' family
% version 0.99b for BibTeX versions 0.99a or later,
% for LaTeX versions 2.09 and 2e.
%
% For use with the `natbib.sty' package; emulates the corresponding
% member of the `plain' family, but with author-year citations.
%
% With version 6.0 of `natbib.sty', it may also be used for numerical
% citations, while retaining the commands \citeauthor, \citefullauthor,
% and \citeyear to print the corresponding information.
%
% For version 7.0 of `natbib.sty', the KEY field replaces missing
% authors/editors, and the date is left blank in \bibitem.
%
% Includes field EID for the sequence/citation number of electronic journals
% which is used instead of page numbers.
%
% Includes fields ISBN and ISSN.
%
% Includes field URL for Internet addresses.
%
% Includes field DOI for Digital Object Idenfifiers.
%
% Works best with the url.sty package of Donald Arseneau.
%
% Works with identical authors and year are further sorted by
% citation key, to preserve any natural sequence.
%
ENTRY
{ address
author
booktitle
chapter
doi
eid
edition
editor
howpublished
institution
isbn
issn
journal
key
month
note
number
organization
pages
publisher
school
series
title
type
url
volume
year
day
}
{}
{ label extra.label sort.label short.list }
INTEGERS { output.state before.all mid.sentence after.sentence after.block }
FUNCTION {init.state.consts}
{ #0 'before.all :=
#1 'mid.sentence :=
#2 'after.sentence :=
#3 'after.block :=
}
STRINGS { s t }
FUNCTION {output.nonnull}
{ 's :=
output.state mid.sentence =
{ ", " * write$ }
{ output.state after.block =
{ add.period$ write$
newline$
"\newblock " write$
}
{ output.state before.all =
'write$
{ add.period$ " " * write$ }
if$
}
if$
mid.sentence 'output.state :=
}
if$
s
}
FUNCTION {output}
{ duplicate$ empty$
'pop$
'output.nonnull
if$
}
FUNCTION {output.check}
{ 't :=
duplicate$ empty$
{ pop$ "empty " t * " in " * cite$ * warning$ }
'output.nonnull
if$
}
FUNCTION {fin.entry}
{ add.period$
write$
newline$
}
FUNCTION {new.block}
{ output.state before.all =
'skip$
{ after.block 'output.state := }
if$
}
FUNCTION {new.sentence}
{ output.state after.block =
'skip$
{ output.state before.all =
'skip$
{ after.sentence 'output.state := }
if$
}
if$
}
FUNCTION {not}
{ { #0 }
{ #1 }
if$
}
FUNCTION {and}
{ 'skip$
{ pop$ #0 }
if$
}
FUNCTION {or}
{ { pop$ #1 }
'skip$
if$
}
FUNCTION {new.block.checka}
{ empty$
'skip$
'new.block
if$
}
FUNCTION {new.block.checkb}
{ empty$
swap$ empty$
and
'skip$
'new.block
if$
}
FUNCTION {new.sentence.checka}
{ empty$
'skip$
'new.sentence
if$
}
FUNCTION {new.sentence.checkb}
{ empty$
swap$ empty$
and
'skip$
'new.sentence
if$
}
FUNCTION {field.or.null}
{ duplicate$ empty$
{ pop$ "" }
'skip$
if$
}
FUNCTION {emphasize}
{ duplicate$ empty$
{ pop$ "" }
{ "\emph{" swap$ * "}" * }
if$
}
INTEGERS { nameptr namesleft numnames }
FUNCTION {format.names}
{ 's :=
#1 'nameptr :=
s num.names$ 'numnames :=
numnames 'namesleft :=
{ namesleft #0 > }
{ s nameptr "{vv~}{ll}{, f.}{, jj.}" format.name$ 't :=
nameptr #1 >
{ namesleft #1 >
{ ", " * t * }
{ numnames #2 >
{ "," * }
'skip$
if$
t "others" =
{ " et~al." * }
{ " and " * t * }
if$
}
if$
}
't
if$
nameptr #1 + 'nameptr :=
namesleft #1 - 'namesleft :=
}
while$
}
FUNCTION {format.key}
{ empty$
{ key field.or.null }
{ "" }
if$
}
FUNCTION {format.authors}
{ author empty$
{ "" }
{ author format.names }
if$
}
FUNCTION {format.editors}
{ editor empty$
{ "" }
{ editor format.names
editor num.names$ #1 >
{ " (ed.)" * }
{ " (ed.)" * }
if$
}
if$
}
FUNCTION {format.isbn}
{ isbn empty$
{ "" }
{ new.block "ISBN " isbn * }
if$
}
FUNCTION {format.issn}
{ issn empty$
{ "" }
{ new.block "ISSN " issn * }
if$
}
FUNCTION {format.url}
{ url empty$
{ "" }
{ new.block "จาก " url * " " * }
if$
}
FUNCTION {format.doi}
{ doi empty$
{ "" }
{ new.block "\doi{" doi * "}" * }
if$
}
FUNCTION {format.title}
{ title empty$
{ "" }
{ title "t" change.case$ }
if$
}
FUNCTION {format.full.names}
{'s :=
#1 'nameptr :=
s num.names$ 'numnames :=
numnames 'namesleft :=
{ namesleft #0 > }
{ s nameptr
"{vv~}{ll}" format.name$ 't :=
nameptr #1 >
{
namesleft #1 >
{ ", " * t * }
{
numnames #2 >
{ "," * }
'skip$
if$
t "others" =
{ " et~al." * }
{ " and " * t * }
if$
}
if$
}
't
if$
nameptr #1 + 'nameptr :=
namesleft #1 - 'namesleft :=
}
while$
}
FUNCTION {author.editor.full}
{ author empty$
{ editor empty$
{ "" }
{ editor format.full.names }
if$
}
{ author format.full.names }
if$
}
FUNCTION {author.full}
{ author empty$
{ "" }
{ author format.full.names }
if$
}
FUNCTION {editor.full}
{ editor empty$
{ "" }
{ editor format.full.names }
if$
}
FUNCTION {make.full.names}
{ type$ "book" =
type$ "inbook" =
or
'author.editor.full
{ type$ "proceedings" =
'editor.full
'author.full
if$
}
if$
}
FUNCTION {output.bibitem}
{ newline$
"\bibitem[" write$
label write$
")" make.full.names duplicate$ short.list =
{ pop$ }
{ * }
if$
"]{" * write$
cite$ write$
"}" write$
newline$
""
before.all 'output.state :=
}
FUNCTION {n.dashify}
{ 't :=
""
{ t empty$ not }
{ t #1 #1 substring$ "-" =
{ t #1 #2 substring$ "--" = not
{ "--" *
t #2 global.max$ substring$ 't :=
}
{ { t #1 #1 substring$ "-" = }
{ "-" *
t #2 global.max$ substring$ 't :=
}
while$
}
if$
}
{ t #1 #1 substring$ *
t #2 global.max$ substring$ 't :=
}
if$
}
while$
}
FUNCTION {format.date}
{ year duplicate$ empty$
{ "empty year in " cite$ * warning$
pop$ "" }
'skip$
if$
month empty$
'skip$
{ month
" " * swap$ *
}
if$
extra.label *
}
FUNCTION {format.year}
{ year duplicate$ empty$
{ "empty year in " cite$ * warning$
pop$ "" }
'skip$
if$
extra.label *
}
FUNCTION {format.btitle}
{ title emphasize
}
FUNCTION {tie.or.space.connect}
{ duplicate$ text.length$ #3 <
{ "~" }
{ " " }
if$
swap$ * *
}
FUNCTION {either.or.check}
{ empty$
'pop$
{ "can't use both " swap$ * " fields in " * cite$ * warning$ }
if$
}
FUNCTION {format.bvolume}
{ volume empty$
{ "" }
{ "volume" volume tie.or.space.connect
series empty$
'skip$
{ " of " * series emphasize * }
if$
"volume and number" number either.or.check
}
if$
}
FUNCTION {format.number.series}
{ volume empty$
{ number empty$
{ series field.or.null }
{ output.state mid.sentence =
{ "number" }
{ "Number" }
if$
number tie.or.space.connect
series empty$
{ "there's a number but no series in " cite$ * warning$ }
{ " in " * series * }
if$
}
if$
}
{ "" }
if$
}
FUNCTION {format.edition}
{ edition empty$
{ "" }
{ output.state mid.sentence =
{ edition "l" change.case$ " edition" * }
{ edition "t" change.case$ " edition" * }
if$
}
if$
}
INTEGERS { multiresult }
FUNCTION {multi.page.check}
{ 't :=
#0 'multiresult :=
{ multiresult not
t empty$ not
and
}
{ t #1 #1 substring$
duplicate$ "-" =
swap$ duplicate$ "," =
swap$ "+" =
or or
{ #1 'multiresult := }
{ t #2 global.max$ substring$ 't := }
if$
}
while$
multiresult
}
FUNCTION {format.pages}
{ pages empty$
{ "" }
{ pages multi.page.check
{ "pp." pages n.dashify tie.or.space.connect }
{ "p." pages tie.or.space.connect }
if$
}
if$
}
FUNCTION {format.eid}
{ eid empty$
{ "" }
{ "art." eid tie.or.space.connect }
if$
}
FUNCTION {format.vol.num.pages}
{ volume field.or.null
number empty$
'skip$
{ "\penalty0 ," number * "" * *
volume empty$
{ "there's a number but no volume in " cite$ * warning$ }
'skip$
if$
}
if$
pages empty$
'skip$
{ duplicate$ empty$
{ pop$ format.pages }
{ ":\penalty0 " * pages n.dashify * }
if$
}
if$
}
FUNCTION {format.vol.num.eid}
{ volume field.or.null
number empty$
'skip$
{ "\penalty0 ," number * "" * *
volume empty$
{ "there's a number but no volume in " cite$ * warning$ }
'skip$
if$
}
if$
eid empty$
'skip$
{ duplicate$ empty$
{ pop$ format.eid }
{ ":\penalty0 " * eid * }
if$
}
if$
}
FUNCTION {format.chapter.pages}
{ chapter empty$
'format.pages
{ type empty$
{ "chapter" }
{ type "l" change.case$ }
if$
chapter tie.or.space.connect
pages empty$
'skip$
{ ", " * format.pages * }
if$
}
if$
}
FUNCTION {format.in.ed.booktitle}
{ booktitle empty$
{ "" }
{ editor empty$
{ "In " booktitle emphasize * }
{ "In " format.editors * ", " * booktitle emphasize * }
if$
}
if$
}
FUNCTION {empty.misc.check}
{ author empty$ title empty$ howpublished empty$
month empty$ year empty$ note empty$
and and and and and
key empty$ not and
{ "all relevant fields are empty in " cite$ * warning$ }
'skip$
if$
}
FUNCTION {format.thesis.type}
{ type empty$
'skip$
{ pop$
type "t" change.case$
}
if$
}
FUNCTION {format.tr.number}
{ type empty$
{ "Technical Report" }
'type
if$
number empty$
{ "t" change.case$ }
{ number tie.or.space.connect }
if$
}
FUNCTION {format.article.pages}
{ pages empty$
{ "" }
{ pages multi.page.check
{"" pages n.dashify tie.or.space.connect }
{"" pages tie.or.space.connect }
if$
}
if$
}
FUNCTION {format.article.crossref}
{ key empty$
{ journal empty$
{ "need key or journal for " cite$ * " to crossref " * crossref *
warning$
""
}
{ "In \emph{" journal * "}" * }
if$
}
{ "In " }
if$
" \citet{" * crossref * "}" *
}
FUNCTION {format.book.crossref}
{ volume empty$
{ "empty volume in " cite$ * "'s crossref of " * crossref * warning$
"In "
}
{ "Volume" volume tie.or.space.connect
" of " *
}
if$
editor empty$
editor field.or.null author field.or.null =
or
{ key empty$
{ series empty$
{ "need editor, key, or series for " cite$ * " to crossref " *
crossref * warning$
"" *
}
{ "\emph{" * series * "}" * }
if$
}
'skip$
if$
}
'skip$
if$
" \citet{" * crossref * "}" *
}
FUNCTION {format.incoll.inproc.crossref}
{ editor empty$
editor field.or.null author field.or.null =
or
{ key empty$
{ booktitle empty$
{ "need editor, key, or booktitle for " cite$ * " to crossref " *
crossref * warning$
""
}
{ "In \emph{" booktitle * "}" * }
if$
}
{ "In " }
if$
}
{ "In " }
if$
" \citet{" * crossref * "}" *
}
FUNCTION {article}
{ output.bibitem
format.authors "author" output.check
author format.key output
new.block
format.year "year" output.check
new.block
format.title "title" output.check
write$ ". "
new.block
write$ journal emphasize " " *
write$ volume
number empty$
{ }
{ write$ "."
write$ number
}
if$
write$ " ("
month empty$
{ }
{ write$ month
write$ " "
}
if$
write$ year
write$ "):"
write$ ""
format.article.pages output
fin.entry
}
FUNCTION {book}
{ output.bibitem
author empty$
{ format.editors "author and editor" output.check
editor format.key output
}
{ format.authors output.nonnull
crossref missing$
{ "author and editor" editor either.or.check }
'skip$
if$
}
if$
new.block
format.year "year" output.check
new.block
format.btitle "title" output.check
crossref missing$
{ format.bvolume output
new.block
format.number.series output
new.sentence
publisher "publisher" output.check
address output
}
{ new.block
format.book.crossref output.nonnull
}
if$
format.edition output
format.isbn output
format.doi output
format.url output
new.block
note output
fin.entry
}
FUNCTION {booklet}
{ output.bibitem
format.authors output
author format.key output
new.block
format.title "title" output.check
howpublished address new.block.checkb
howpublished output
address output
format.date output
format.isbn output
format.doi output
format.url output
new.block
note output
fin.entry
}
FUNCTION {inbook}
{ output.bibitem
author empty$
{ format.editors "author and editor" output.check
editor format.key output
}
{ format.authors output.nonnull
crossref missing$
{ "author and editor" editor either.or.check }
'skip$
if$
}
if$
new.block
format.year "year" output.check
new.block
format.btitle "title" output.check
crossref missing$
{ format.bvolume output
format.chapter.pages "chapter and pages" output.check
new.block
format.number.series output
new.sentence
publisher "publisher" output.check
address output
}
{ format.chapter.pages "chapter and pages" output.check
new.block
format.book.crossref output.nonnull
}
if$
format.edition output
format.isbn output
format.doi output
format.url output
new.block
note output
fin.entry
}
FUNCTION {incollection}
{ output.bibitem
format.authors "author" output.check
author format.key output
new.block
format.year "year" output.check
new.block
format.title "title" output.check
new.block
crossref missing$
{ format.in.ed.booktitle "booktitle" output.check
format.bvolume output
format.number.series output
format.chapter.pages output
write$ ". "
new.block
write$ address
write$ ": "
write$ publisher
format.edition output
}
{ format.incoll.inproc.crossref output.nonnull
format.chapter.pages output
}
if$
fin.entry
}
FUNCTION {inproceedings}
{ output.bibitem
format.authors "author" output.check
author format.key output
new.block
format.year "year" output.check
new.block
format.title "title" output.check
new.block
crossref missing$
{ format.in.ed.booktitle "booktitle" output.check
format.bvolume output
format.number.series output
format.pages output
}
{ format.incoll.inproc.crossref output.nonnull
format.pages output
}
if$
write$ ". "
new.block
write$ address
write$ ": "
write$ publisher
fin.entry
}
FUNCTION {conference} { inproceedings }
FUNCTION {manual}
{ output.bibitem
format.authors output
author format.key output
new.block
format.year output
new.block
format.btitle "title" output.check
organization address new.block.checkb
organization output
address output
format.edition output
format.url output
fin.entry
}
FUNCTION {mastersthesis}
{ output.bibitem
format.authors "author" output.check
author format.key output
new.block
format.year "year" output.check
new.block
format.title "title" output.check
new.block
"Master's thesis" format.thesis.type output.nonnull
school "school" output.check
address output
format.url output
fin.entry
}
FUNCTION {misc}
{ output.bibitem
format.authors output
author format.key output
title howpublished new.block.checkb
new.block
write$ " "
write$ "("
write$ year
write$ ")"
format.title output
howpublished new.block.checka
howpublished output
new.block
url empty$
{ }
{ write$ " [ออนไลน์]. "
write$ "สืบค้นเมื่อ "
write$ note
}
if$
new.block
format.url output
fin.entry
empty.misc.check
}
FUNCTION {phdthesis}
{ output.bibitem
format.authors "author" output.check
author format.key output
new.block
format.year "year" output.check
new.block
format.btitle "title" output.check
new.block
"PhD thesis" format.thesis.type output.nonnull
school "school" output.check
address output
format.url output
fin.entry
}
FUNCTION {proceedings}
{ output.bibitem
format.editors output
editor format.key output
new.block
format.year "year" output.check
format.btitle "title" output.check
format.bvolume output
format.number.series output
address output
new.sentence
organization output
publisher output
format.isbn output
format.doi output
format.url output
fin.entry
}
FUNCTION {techreport}
{ output.bibitem
format.authors "author" output.check
author format.key output
new.block
format.year "year" output.check
new.block
format.title "title" output.check
new.block
format.tr.number output.nonnull
institution "institution" output.check
address output
fin.entry
}
FUNCTION {unpublished}
{ output.bibitem
format.authors "author" output.check
author format.key output
new.block
format.title "title" output.check
format.date output
format.url output
fin.entry
}
FUNCTION {internet}
{ output.bibitem
title howpublished new.block.checkb
format.title output
howpublished new.block.checka
howpublished output
new.block
url empty$
{ }
{ write$ " [ออนไลน์]. "
write$ "สืบค้นเมื่อ "
write$ day
write$ " "
write$ month
write$ " "
write$ year
}
if$
new.block
format.url output
fin.entry
}
FUNCTION {default.type} { misc }
MACRO {jan} {"January"}
MACRO {feb} {"February"}
MACRO {mar} {"March"}
MACRO {apr} {"April"}
MACRO {may} {"May"}
MACRO {jun} {"June"}
MACRO {jul} {"July"}
MACRO {aug} {"August"}
MACRO {sep} {"September"}
MACRO {oct} {"October"}
MACRO {nov} {"November"}
MACRO {dec} {"December"}
MACRO {acmcs} {"ACM Computing Surveys"}
MACRO {acta} {"Acta Informatica"}
MACRO {cacm} {"Communications of the ACM"}
MACRO {ibmjrd} {"IBM Journal of Research and Development"}
MACRO {ibmsj} {"IBM Systems Journal"}
MACRO {ieeese} {"IEEE Transactions on Software Engineering"}
MACRO {ieeetc} {"IEEE Transactions on Computers"}
MACRO {ieeetcad}
{"IEEE Transactions on Computer-Aided Design of Integrated Circuits"}
MACRO {ipl} {"Information Processing Letters"}
MACRO {jacm} {"Journal of the ACM"}
MACRO {jcss} {"Journal of Computer and System Sciences"}
MACRO {scp} {"Science of Computer Programming"}
MACRO {sicomp} {"SIAM Journal on Computing"}
MACRO {tocs} {"ACM Transactions on Computer Systems"}
MACRO {tods} {"ACM Transactions on Database Systems"}
MACRO {tog} {"ACM Transactions on Graphics"}
MACRO {toms} {"ACM Transactions on Mathematical Software"}
MACRO {toois} {"ACM Transactions on Office Information Systems"}
MACRO {toplas} {"ACM Transactions on Programming Languages and Systems"}
MACRO {tcs} {"Theoretical Computer Science"}
READ
FUNCTION {sortify}
{ purify$
"l" change.case$
}
INTEGERS { len }
FUNCTION {chop.word}
{ 's :=
'len :=
s #1 len substring$ =
{ s len #1 + global.max$ substring$ }
's
if$
}
FUNCTION {format.lab.names}
{ 's :=
s #1 "{vv~}{ll}" format.name$
s num.names$ duplicate$
#2 >
{ pop$ " et~al." * }
{ #2 <
'skip$
{ s #2 "{ff }{vv }{ll}{ jj}" format.name$ "others" =
{ " et~al." * }
{ " and " * s #2 "{vv~}{ll}" format.name$ * }
if$
}
if$
}
if$
}
FUNCTION {author.key.label}
{ author empty$
{ key empty$
{ cite$ #1 #3 substring$ }
'key
if$
}
{ author format.lab.names }
if$
}
FUNCTION {author.editor.key.label}
{ author empty$
{ editor empty$
{ key empty$
{ cite$ #1 #3 substring$ }
'key
if$
}
{ editor format.lab.names }
if$
}
{ author format.lab.names }
if$
}
FUNCTION {author.key.organization.label}
{ author empty$
{ key empty$
{ organization empty$
{ cite$ #1 #3 substring$ }
{ "The " #4 organization chop.word #3 text.prefix$ }
if$
}
'key
if$
}
{ author format.lab.names }
if$
}
FUNCTION {editor.key.organization.label}
{ editor empty$
{ key empty$
{ organization empty$
{ cite$ #1 #3 substring$ }
{ "The " #4 organization chop.word #3 text.prefix$ }
if$
}
'key
if$
}
{ editor format.lab.names }
if$
}
FUNCTION {calc.short.authors}
{ type$ "book" =
type$ "inbook" =
or
'author.editor.key.label
{ type$ "proceedings" =
'editor.key.organization.label
{ type$ "manual" =
'author.key.organization.label
'author.key.label
if$
}
if$
}
if$
'short.list :=
}
FUNCTION {calc.label}
{ calc.short.authors
short.list
"("
*
year duplicate$ empty$
short.list key field.or.null = or
{ pop$ "" }
'skip$
if$
*
'label :=
}
FUNCTION {sort.format.names}
{ 's :=
#1 'nameptr :=
""
s num.names$ 'numnames :=
numnames 'namesleft :=
{ namesleft #0 > }
{
s nameptr "{vv{ } }{ll{ }}{ ff{ }}{ jj{ }}" format.name$ 't :=
nameptr #1 >
{
" " *
namesleft #1 = t "others" = and
{ "zzzzz" * }
{ numnames #2 > nameptr #2 = and
{ "zz" * year field.or.null * " " * }
'skip$
if$
t sortify *
}
if$
}
{ t sortify * }
if$
nameptr #1 + 'nameptr :=
namesleft #1 - 'namesleft :=
}
while$
}
FUNCTION {sort.format.title}
{ 't :=
"A " #2
"An " #3
"The " #4 t chop.word
chop.word
chop.word
sortify
#1 global.max$ substring$
}
FUNCTION {author.sort}
{ author empty$
{ key empty$
{ "to sort, need author or key in " cite$ * warning$
""
}
{ key sortify }
if$
}
{ author sort.format.names }
if$
}
FUNCTION {author.editor.sort}
{ author empty$
{ editor empty$
{ key empty$
{ "to sort, need author, editor, or key in " cite$ * warning$
""
}
{ key sortify }
if$
}
{ editor sort.format.names }
if$
}
{ author sort.format.names }
if$
}
FUNCTION {author.organization.sort}
{ author empty$
{ organization empty$
{ key empty$
{ "to sort, need author, organization, or key in " cite$ * warning$
""
}
{ key sortify }
if$
}
{ "The " #4 organization chop.word sortify }
if$
}
{ author sort.format.names }
if$
}
FUNCTION {editor.organization.sort}
{ editor empty$
{ organization empty$
{ key empty$
{ "to sort, need editor, organization, or key in " cite$ * warning$
""
}
{ key sortify }
if$
}
{ "The " #4 organization chop.word sortify }
if$
}
{ editor sort.format.names }
if$
}
FUNCTION {presort}
{ calc.label
label sortify
" "
*
type$ "book" =
type$ "inbook" =
or
'author.editor.sort
{ type$ "proceedings" =
'editor.organization.sort
{ type$ "manual" =
'author.organization.sort
'author.sort
if$
}
if$
}
if$
" "
*
cite$
*
#1 entry.max$ substring$
'sort.label :=
sort.label *
#1 entry.max$ substring$
'sort.key$ :=
}
ITERATE {presort}
%SORT
STRINGS { longest.label last.label next.extra }
INTEGERS { longest.label.width last.extra.num number.label }
FUNCTION {initialize.longest.label}
{ "" 'longest.label :=
#0 int.to.chr$ 'last.label :=
"" 'next.extra :=
#0 'longest.label.width :=
#0 'last.extra.num :=
#0 'number.label :=
}
FUNCTION {forward.pass}
{ last.label label =
{ last.extra.num #1 + 'last.extra.num :=
last.extra.num int.to.chr$ 'extra.label :=
}
{ "a" chr.to.int$ 'last.extra.num :=
"" 'extra.label :=
label 'last.label :=
}
if$
number.label #1 + 'number.label :=
}
FUNCTION {reverse.pass}
{ next.extra "b" =
{ "a" 'extra.label := }
'skip$
if$
extra.label 'next.extra :=
extra.label
duplicate$ empty$
'skip$
{ "{\natexlab{" swap$ * "}}" * }
if$
'extra.label :=
label extra.label * 'label :=
}
EXECUTE {initialize.longest.label}
ITERATE {forward.pass}
REVERSE {reverse.pass}
FUNCTION {bib.sort.order}
{ sort.label 'sort.key$ :=
}
%ITERATE {bib.sort.order}
%SORT
FUNCTION {begin.bib}
{ preamble$ empty$
'skip$
{ preamble$ write$ newline$ }
if$
"\begin{thebibliography}{" number.label int.to.str$ * "}" *
write$ newline$
"\providecommand{\natexlab}[1]{#1}"
write$ newline$
"\providecommand{\url}[1]{\texttt{#1}}"
write$ newline$
"\expandafter\ifx\csname urlstyle\endcsname\relax"
write$ newline$
" \providecommand{\doi}[1]{doi: #1}\else"
write$ newline$
" \providecommand{\doi}{doi: \begingroup \urlstyle{rm}\Url}\fi"
write$ newline$
}
EXECUTE {begin.bib}
EXECUTE {init.state.consts}
ITERATE {call.type$}
FUNCTION {end.bib}
{ newline$
"\end{thebibliography}" write$ newline$
}
EXECUTE {end.bib}
\RequirePackage{tikz}
\usetikzlibrary{arrows,matrix,positioning,shapes}
\RequirePackage{graphicx}
\RequirePackage{datetime}
\RequirePackage{caption}
\RequirePackage{forloop}
\RequirePackage{minted}
\RequirePackage{listings}
\usepackage{float} % for floating figures
\usepackage{amsmath} % for math related environment
\usepackage{amsfonts} % fonts for math
\usepackage{listings} % for psuedocode, lines of codes
\usepackage{caption}
\usepackage[labelformat=simple]{subcaption}
\renewcommand\thesubfigure{(\alph{subfigure})} % for (a) in subcaption
\usepackage{enumitem}
\setlist{nolistsep,topsep=0pt}
\usepackage{wrapfig} % for figures wrap inside text paragraph
\usepackage{pdfpages} % for including pdf pages
\usepackage{verbatim} % for block comment
\usepackage{multicol}
\usepackage{standalone} % for proposal text inclusion
\usepackage{pgfgantt} % for gantt chart
\usepackage{titlesec}
\titlespacing{\section}{0pt}{\parskip}{-\parskip}
\usepackage{array}
\usepackage{xcolor,colortbl}
\usepackage{pdflscape}
\usepackage{tabularx}
\usepackage{makecell}
\usepackage{rotating}
\newcommand*\rot{\rotatebox{90}}
% listings format
\lstset{
basicstyle=\ttfamily,
numbers=left,
numberstyle=\small,
breaklines=true,
xleftmargin=.1\linewidth,
frame=single,
columns=fullflexible,
captionpos=b,
showstringspaces=false
}
\usemintedstyle{
numberblanklines=true,
numbersep=12pt,
numbersep=5pt,
gobble=0,
fontsize=\footnotesize,
frame=lines,
framerule=0.4pt,
framesep=1mm,
tabsize=2,
obeytabs=true,
samepage=false,
showspaces=false,
showtabs=false,
%stepnumber=2,
linenos,
breaklines
}
latexmk -g -f CS5811400000.tex
##### OR
# xelatex -interaction=nonstopmode -file-line-error -synctex=1 MathCS-tutorial.tex
# bibtex MathCS-tutorial.aux
# xelatex -interaction=nonstopmode -file-line-error -synctex=1 MathCS-tutorial.tex
# xelatex -interaction=nonstopmode -file-line-error -synctex=1 MathCS-tutorial.tex
latexmk -g -f CS5811400000.tex
##### OR
# xelatex -interaction=nonstopmode -file-line-error -synctex=1 MathCS-tutorial.tex
# bibtex MathCS-tutorial.aux
# xelatex -interaction=nonstopmode -file-line-error -synctex=1 MathCS-tutorial.tex
# xelatex -interaction=nonstopmode -file-line-error -synctex=1 MathCS-tutorial.tex
\documentclass[a4paper]{ubu}
\usepackage{coding}
\begin{document}
\chapter{ทฤษฎีที่เกี่ยวข้อง}
บทนี้จะเป็นรายละเอียดเกี่ยวกับทฤษฎีและงานวิจัยที่เกี่ยวของกับการพัฒนาโปรแกรมในครั้งนี้ โดยที่แต่ละหัวข้อจะมีความสัมพันธ์กันเป็นลำดับ โดยหัวข้อที่หนึ่งจะแนะนำความรู้เรื่อง xxx เพื่อให้เข้าใจพื้นฐานเบื้องต้นเกี่ยวกับที่มาของโครงงาน หัวข้อที่สองที่สามจะช่วยเตรียมให้ผู้อ่านเข้าใจเทคโนโลยที่ใช้ในการออกแบบและพัฒนา ส่วน ...
\section{ความรู้พื้นฐาน}
คำนำเรื่องความรู้พื้นฐาน
\section{การเขียนคำสั่ง}
คำนำเรื่องการเขียนคำสั่ง
\subsection{การเขียนคำสั่งโดยแทรกในเอกสาร}
\startminted{python}
import numpy as np
def gaussian_elimination(A, b):
# 1. ขั้นตอนการตัดทอน - Elimination Step
n = len(b)
for j in range(0, n-1):
# 1.1 เลือกสมการตั้งต้น - pivot equation สมการที่ j
# 1.2 ลดรูปสมการที่ i โดยที่ i เริ่มจาก j+1
for i in range(j+1, n):
# 1.2.1 คำนวณหาค่าตัวคูณ lam
lam = A[i,j]/A[j,j]
# 1.2.2 ลบออกจากด้านซ้ายของสมการ
A[i,j:n] = A[i, j:n] - lam*A[j, j:n]
# 1.2.3 ลบออกจากด้านขวาของสมการ
b[i] = b[i] - lam*b[j]
# 2. แทนค่าของตวแปรที่หาค่าได้จากสมการล่างสุด แทนไปสมการบนไล่ไปเรื่อย
# ขั้นตอนนี้ทั้งหมดเรียกว่า back substitution
x = b.copy()
for k in range(n-1, -1, -1):
x[k] = (b[k] - np.dot(A[k,k+1:n], x[k+1:n]))/A[k,k]
# 3. แสดงผลลัพธ์
# ค่าของตัวแปร x ทุกตัว
print(x)
A = np.array([
[4, -2, 1],
[-2, 4, -2],
[1, -2, 4]
], float)
b = np.array([11,-16,17], float)
gaussian_elimination(A, b)
\end{minted}
ตัวอย่างที่ไม่
\begin{minted}{python}
import numpy as np
def gaussian_elimination(A, b):
# 1. ขั้นตอนการตัดทอน - Elimination Step
n = len(b)
for j in range(0, n-1):
# 1.1 เลือกสมการตั้งต้น - pivot equation สมการที่ j
# 1.2 ลดรูปสมการที่ i โดยที่ i เริ่มจาก j+1
for i in range(j+1, n):
# 1.2.1 คำนวณหาค่าตัวคูณ lam
lam = A[i,j]/A[j,j]
# 1.2.2 ลบออกจากด้านซ้ายของสมการ
A[i,j:n] = A[i, j:n] - lam*A[j, j:n]
# 1.2.3 ลบออกจากด้านขวาของสมการ
b[i] = b[i] - lam*b[j]
# 2. แทนค่าของตวแปรที่หาค่าได้จากสมการล่างสุด แทนไปสมการบนไล่ไปเรื่อย
# ขั้นตอนนี้ทั้งหมดเรียกว่า back substitution
x = b.copy()
for k in range(n-1, -1, -1):
x[k] = (b[k] - np.dot(A[k,k+1:n], x[k+1:n]))/A[k,k]
# 3. แสดงผลลัพธ์
# ค่าของตัวแปร x ทุกตัว
print(x)
A = np.array([
[4, -2, 1],
[-2, 4, -2],
[1, -2, 4]
], float)
b = np.array([11,-16,17], float)
gaussian_elimination(A, b)
\end{minted}
\end{document}
@misc{bib1,
author = {{marcuscode}},
title = {โครงสร้างของภาษา PHP},
date = {9},
month = {ธันวาคม},
year = {2559},
note = {},
url = {http://marcuscode.com/lang/php/program-struct}
}
@misc{bib2,
author = {{Krissanawat Kaewsanmuang}},
title = {คู่มือการใช้งาน Laravel},
url = {https://leanpub.com/thailaraveldoc/read\#leanpub-auto-installation},
date = {},
month = {},
year = {},
note = {}
}
@misc{bib3,
author = {{wp63}},
title = {ใช้ Guzzle ในการเชื่อมต่อ API แทน cURL},
url = {https://wp63.co/2019/10/guzzle-php-http-client/},
date = {13},
month = {ตุลาคม},
year = {2562},
note = {}
}
@misc{bib4,
author = {{google maps platform}},
title = {Distance Matrix API},
url = {https://developers-dot-devsite-v2-prod.appspot.com/maps/documentation/distance-matrix/intro\#DistanceMatrixRequests},
date = {16},
month = {เมษายน},
year = {2563},
note = {}
}
@misc{bib5,
author = {{ benext}},
title = {การใช้งาน Blade Template},
url = {https://www.itoffside.com/laravel-ep10-blade-template/},
date = {9},
month = {มกราคม},
year = {2563},
note = {}
}
\ No newline at end of file
package com.ubu.andapp;
import android.os.Bundle;
import android.app.Activity;
import android.util.Log;
public class MainActivity extends Activity {
private String name = "MainActivity";
/** ฟังก์ชันที่จะทำงานเมื่อมีการเริ่มเรียกใช้งาน MainActivity */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d(msg, "The onCreate() event");
}
/** ฟังก์ชันที่จะทำงานเมื่อมีการแสดง MainActivity ให้ผู้ใช้เห็น */
@Override
protected void onStart() {
super.onStart();
Log.d(msg, "The onStart() event");
}
}
import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
Widget build(BuildContext context) {
return new MaterialApp(
title: 'ตัวอย่าง Flutter Application',
home: new MyHomePage(title: 'ตัวอย่าง Flutter App'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text(widget.title),
),
body: new Container(),
floatingActionButton: new Builder(builder: (context) {
return new FloatingActionButton(onPressed: () {
Scaffold.of(context).showSnackBar(
new SnackBar(
backgroundColor: Colors.blue,
content: new Text('SnackBar'),
),
);
});
}),
);
}
}
#include <set>
#include <string>
#include <iostream>
int main(int argc, char **argv)
{
// ประกาศตัวแปรพร้อมกำหนดค่าเริ่มต้น
std::string word;
std::set<std::string> wordcount;
// อ่านคำที่ผู้กรอกเก็บไว้ใน set (rb-tree)
while (std::cin >> word) wordcount.insert(word);
// แสดงผลลัพธ์ ว่าแต่ละคำมีจำนวนเท่าไหร่
std::cout << "คำ: " << wordcount.size() << std::endl;
return 0;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>HTML5 เว็บเพจ</title>
<meta name="description" content="HTML5 เว็บเพจ">
<meta name="author" content="csubu">
<link rel="stylesheet" href="css/styles.css?v=1.23">
</head>
<body>
<script src="js/csubuapp.js"></script>
</body>
</html>
import numpy as np
import pandas as pd
# อ่านข้อมูลจาไฟล์ 'test.csv'
df = pd.read_csv('test.csv')
# แสดงตัวอย่างข้อมูล 5 แถวแรก
df.head()
# แสดง histogram
df.hist()
# แสดงข้อมูลทางสถิติเฉพาะ 'บ้าน' 'ราคา'
df[['บ้าน', 'ราคา']].describe()
function HelloMessage({ name }) {
return <div>สวัสดี {name}</div>;
}
ReactDOM.render(
<HelloMessage name="วิทยา คอม" />,
document.getElementById('container')
);
// import ฟังก์ชันสำคัญของ angular/core
import { Component, OnInit } from '@angular/core';
@Component({
// ประกาศชื่อ selector เพื่อให้ component อื่นสามารถนำไปใช้ได้
selector: 'student',
// ระบุชื่ไฟล์ html ที่ใช้ฟังก์ชันใน component โดยตรง
templateUrl: './student.component.html',
// ระบุ style ที่นำไปใช้กับ html
styleUrls: ['./student.component.css']
})
export class StudentComponent implements OnInit {
constructor() { }
ngOnInit() {}
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Author: Warawoot Pacharoen
%% Date: April 13, 2018
%% Email: warawoot.p@ubu.ac.th, wpacharoen@gmail.com
%%
%% This class file is extended from chula.cls by Dr.Nattee Niparnan.
%%
%% You can freely modified this file.
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Author: Supasate Choochaisri
%% Date: April 19, 2012
%% Email: supasate.c@gmail.com, supasate@larngeartech.com
%%
%% This class file is extended from chula.cls by Dr.Nattee Niparnan.
%% The chula.cls by Dr.Nattee is loosely based on the chula.sty package
%% originally written by Chatchawit Aporntewan. The chula.sty was
%% then undergone many minor changes by Nattee Niparnan, Teerayut
%% Hiruntaraporn, and Mahisorn Wongphati. Then, Nattee rewrote the
%% style file as a class file and provides several option making the
%% class to be more general. Finally, Supasate modified the class
%% file to be used with XeTeX and to comply with the regulation in
%% acedemic year 2554.
%%
%% You can freely modified this file.
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Changelog
%% August 21, 2015: Dittaya Wanvarie
%% - Move fontspec font settings to AtEndOfClass to avoid problem in Windows TeX
%% July 7, 2015: Dittaya Wanvarie
%% - Delete unnecessary comments
%% - Add more comments
%% - Add standard fonts for English similar to IEEEtran template
%% - Correct errors in English template
%% - Re-define bibliography to use \normalfont
%% - Add natbib required pacakge
%% - Define \thalph order (ก, ข, ค, ง,...0) for appendices
%% - Add setspace require package and force doublespacing
%% June 11, 2015: Dittaya Wanvarie
%% - Move font settings to AtEndOfClass
%% - Change Thai font scale to match roman uppercase character
%% - Add 12pt option to base report class
%% - Add \@ThaiBookTitle to all Co-advisor block
%% - Change tabular settings in TH/EN sign pages
%% - Add array package required for tabular
%% - Fix bugs in co-advisor position in abstract pages
%% June 9, 2015: Dittaya Wanvarie
%% - Change the width sign/department dotted line in TH/EN abstract page to fit "Mathematics and Computer Science"
%% July 21, 2014: Boonyarit Intiyot
%% - Add option [Latin,Thai] to ucharclasses
%% - Add \defaultfontfeatures{Mapping=tex-text}
%% - To avoid problem with Miktex for Windows:
%% -Move \newfontfamily\thaifont[Scale=MatchLowercase,Mapping=tex-text]{TH Sarabun New:script=thai} to the end of file
%% -Move \setTransitionTo{Thai}{\fontspec[Scale=MatchLowercase,Mapping=tex-text]{TH Sarabun New}} to the end of file and change it to \setTransitionTo{Thai}{\thaifont}
%% -Add \setTransitionFrom{Thai}{\normalfont} at the end of file
%%
%% July 6, 2014: Dittaya Wanvarie
%% - Add \defaultfontfeatures{Mapping=tex-text}
%% - Change co-advisor parameter in the English abstract page to uppercase "except
%% "Ph.D"
%% - Add subjID for course report in ugrad
%% - Add ugrad option for senior project report
%% - Add "appendicesname" and "appendicespage" in ThaiCaption
%% May 3, 2012 : Supasate Choochaisri
%% - Add a parameter to handle the uppercase of advisor's title except "Ph.D."
%% - Rename chula_nat.bst to chulanat.bst to make it more compatible to LaTeX
%% compiler.
%% - Add a "numappendices" parameter to handle choosing "Appendix" or "Appendices"
%% - Fix indentation of the Thai abstract page.
%% - Modify the bibtex style file (chulanat.bst) to handle Chula bibliography
%% format.
%%
%% Apr 19, 2012 : Supasate Choochaisri
%% - Use XeTeX to support UTF-8 and OpenType font.
%% - Use ucharclasses package to automatically switch language without
%% explicitly issuing switch command.
%% - Capitalize Advisor name at the English abstract page.
%% - Add option for Advisor/Co-Advisor name with abbreviated title to be used
%% at the English abstract page.
%% - Write Deparment, Field of Study, and Academic year on dotted underlines
%% at the abstract page.
%% - Add semi-colon after Academic year at the English abstract page.
%% - Move the word "Fulfillment" to the second line at the Approval page.
%% - Adjust top margin to 1.5", bottom margin to 1.0" with geometry package.
%% - Add line break for a long thesis title at the cover page.
%%
%% Feb 25, 2007: Nattee Niparnan
%% - Change heading mechanism.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Identification %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\NeedsTeXFormat{LaTeX2e}
\ProvidesClass{ubu}[2018/04/13]
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Initial Code %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\RequirePackage{fontspec}
\RequirePackage{calc}
%\RequirePackage{fontspec}
\RequirePackage{xunicode}
\RequirePackage{xltxtra}
\RequirePackage{polyglossia}
\RequirePackage{ragged2e}
\RequirePackage{tikz}
\RequirePackage{geometry}
\RequirePackage{afterpage}
\RequirePackage{array}
\RequirePackage[Latin,Thai]{ucharclasses}
\RequirePackage{url} % for breaking urls (use \url{http://www.example.com})
\RequirePackage{breakcites} % for breaking long citations
\RequirePackage[normalem]{ulem} % for underlineing Journal name in references
\RequirePackage{setspace} % for double spacing
%\RequirePackage{fontspec}
\setdefaultlanguage{thai}
\setotherlanguage{thai}
\setTransitionTo{Thai}{\thaifont\doublespacing}
\setTransitionFrom{Thai}{\normalfont\doublespacing}
\XeTeXlinebreaklocale "th_TH"
\XeTeXlinebreakskip = 0pt plus 1pt
\newif\if@doctor
\newif\if@master
\newif\if@ugrad
\newif\if@coadvisor
\newif\if@thaithesis
\@coadvisorfalse
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Option Declaration %%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\@ugradtrue
\DeclareOption{doctor} {
\@doctortrue
\@masterfalse
\@ugradfalse
} \DeclareOption{master} {
\@doctorfalse
\@mastertrue
\@ugradfalse
} \DeclareOption{ugrad} {
\@doctorfalse
\@masterfalse
} \DeclareOption{coadvisor} {
\@coadvisortrue
} \DeclareOption{thaithesis} {
\@thaithesistrue
} \DeclareOption{engthesis} {
\@thaithesisfalse
}
\DeclareOption*{\PassOptionsToClass{\CurrentOption}{report}} % pass any unknown option to the report class
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Option Execution %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\ExecuteOptions{ugrad,thaithesis}
\ProcessOptions
%%%%%%%%%%%%%%%%%%%%%%%%%%%% Class & Package Loading %%%%%%%%%%%%%%%%%%%%%%%%%%
\LoadClass[a4paper,12pt]{report} % this class is based on the report class
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Main Code %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\AtEndOfClass{
% Add natbib after set all other parameters
%\RequirePackage[round,semicolon]{natbib} % for bibliography sylte
\RequirePackage[square,comma,numbers]{natbib}
\renewenvironment{thebibliography}[1]{%
\thereferences
\bibsection\parindent \z@\bibpreamble\bibfont\list
{\@biblabel{\arabic{NAT@ctr}}}{\@bibsetup{#1}%
\setcounter{NAT@ctr}{0}}%
\normalfont
\ifNAT@openbib
\renewcommand\newblock{\par}
\else
\renewcommand\newblock{\hskip .11em \@plus.33em \@minus.07em}%
\fi
\sloppy\clubpenalty4000\widowpenalty4000
\sfcode`\.=1000\relax
\let\citeN\cite \let\shortcite\cite
\let\citeasnoun\cite
}{\def\@noitemerr{%
\PackageWarning{natbib}
{Empty `thebibliography' environment}}%
\endlist\vskip-\lastskip
}
%% English fonts are Times, Helvetica, Courier, according to IEEEtran template
\defaultfontfeatures{Mapping=tex-text}
\setmainfont{TeX Gyre Termes} % Free Times
\setsansfont{TeX Gyre Heros} % Free Helvetica
\setmonofont{TeX Gyre Cursor} % Free Courier
% Use TH Sarabun New for Thai as it is standard font for Thai formal documents
\newfontfamily{\thaifont}[Scale=MatchUppercase,Mapping=tex-text]{TH Sarabun New:script=thai}
\doublespacing
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% define Thai alphabet sequence
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\def\thalph#1{\expandafter\@thalph\csname c@#1\endcsname}
\def\@thalph#1{%
\ifcase#1\or\or\or\or\or\or\or\or\or
\or\or\or\or\or\or\or\or\or\or\or\or\or\or
\or\or\or\or\or\or\or\or\or\or\or\or\or\or
\or\or\or\or\or\or\else\xpg@ill@value{#1}{@thaialph}\fi}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% localize the strings (xxxxname )
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\newcommand\fillin[1][3cm]{\makebox[#1]{\dotfill}}
\newcommand\selectthesislang{
\if@thaithesis
\selectlanguage{thai}
\else
\selectlanguage{english}
\fi
}
%% string setting
\if@doctor
\newcommand\@ThaiDegreeType{ปริญญาดุษฎีบัณฑิต}
\newcommand\@EnglishDegreeType{Doctoral Degree}
\newcommand\@ThaiBookTitle{วิทยานิพนธ์}
\newcommand\@EnglishBookTitle{Dissertation}
\else
\if@master
\newcommand\@ThaiDegreeType{ปริญญามหาบัณฑิต}
\newcommand\@EnglishDegreeType{Master's Degree}
\newcommand\@ThaiBookTitle{วิทยานิพนธ์}
\newcommand\@EnglishBookTitle{Thesis}
\else
\newcommand\@ThaiDegreeType{ปริญญาบัณฑิต}
\newcommand\@EnglishDegreeType{Bachelor's Degree}
\newcommand\@ThaiBookTitle{โครงงาน}
\newcommand\@EnglishBookTitle{Project}
\fi
\fi
\if@thaithesis
%% my new string
\newcommand{\@AcknowledgementsString}{กิตติกรรมประกาศ}
\if@ugrad
\newcommand{\@BiographyString}{ประวัติผู้เขียน}
\else
\newcommand{\@BiographyString}{ประวัติผู้เขียนวิทยานิพนธ์}
\fi
\newcommand{\@AbstractThaiString}{บทคัดย่อภาษาไทย}
\newcommand{\@AbstractEnglishString}{บทคัดย่อภาษาอังกฤษ}
\newcommand{\@PageString}{หน้า}
\newcommand{\@ThaiFont}{\normalfont}
%%string already defined in babel (some are not used in this class, but I add it anyway
\renewcommand\captionsthai{%
\def\prefacename{คำนำ}%
\def\refname{หนังสืออ้างอิง}%
\def\abstractname{บทคัดย่อ}%
\def\bibname{บรรณานุกรม}%
\def\chaptername{บทที่}%
\def\appendixname{ภาคผนวก}%
\def\appendicesname{ภาคผนวก}%
\def\appendixpage{ภาคผนวก}%
\def\appendicespage{ภาคผนวก}%
\def\contentsname{สารบัญ}%
\def\listfigurename{สารบัญภาพ}%
\def\listtablename{สารบัญตาราง}%
\def\indexname{ดรรชนี}%
\def\figurename{รูปที่}%
\def\tablename{ตารางที่}%
\def\partname{ภาค}%
\def\enclname{สิ่งที่แนบมาด้วย}%
\def\ccname{สำเนาถึง}%
\def\headtoname{เรียน}%
\def\pagename{หน้า}%
\def\seename{ดู}%
\def\alsoname{ดูเพิ่มเติม}%
\def\proofname{พิสูจน์}%
}
\else
%% my new string
\newcommand{\@AcknowledgementsString}{Acknowledgements}
\newcommand{\@BiographyString}{Biography}
\newcommand{\@AbstractThaiString}{Abstract (Thai)}
\newcommand{\@AbstractEnglishString}{Abstract (English)}
\newcommand{\@PageString}{Page}
\newcommand{\@ThaiFont}{\normalfont}
%%string already defined in babel (some are not used in this class, but I add it anyway
\renewcommand\captionsenglish{%
\def\prefacename{Preface}%
\def\refname{References}%
\def\abstractname{Abstract}%
\def\bibname{References}%
\def\chaptername{Chapter}%
\def\appendixname{Appendix}%
\def\appendicesname{Appendices}%
\def\appendixpage{APPENDIX}%
\def\appendicespage{APPENDICES}%
\def\contentsname{Contents}%
\def\listfigurename{List of Figures}%
\def\listtablename{List of Tables}%
\def\indexname{Index}%
\def\figurename{Figure}%
\def\tablename{Table}%
\def\partname{Part}%
\def\enclname{encl}%
\def\ccname{cc}%
\def\headtoname{To}%
\def\pagename{Page}%
\def\seename{see}%
\def\alsoname{see also}%
\def\proofname{Proof}%
\def\glossaryname{Glossary}%
\def\figurename{Figure}
\def\tablename{Table}
}
\fi
\if@thaithesis
\captionsthai
\else
\captionsenglish
\fi
%% set chapter string
\renewcommand\@chapapp{\chaptername}
%% to write text over dotted line
\newcommand{\udot}[1]{%
\tikz[baseline=(todotted.south)]{
\node[inner sep=0pt,outer sep=0pt] (todotted) {#1};
\draw[loosely dotted, thick] (todotted.south west) -- (todotted.south east);
}%
}%
%% to choose the word between Appendix or Appendices
\newcommand{\numappendices}[1]{
\newcommand{\@numappendices}{#1}
}
%% additional command for setting the first few pages of the thesis
%% please refer to the accompanying bare_thesis.tex for the example
%% usage of these command.
\newcommand{\authortitle}[2]{ % define Title of Author
\newcommand{\@ThaiAuthorTitle}{#1}
\newcommand{\@EnglishAuthorTitle}{#2}
}
\newcommand{\thesisauthor}[2]{ % define author
\newcommand{\@ThaiAuthor}{#1}
\newcommand{\@EnglishAuthor}{#2}
\newcommand{\@EnglishAuthorUP}{\uppercase{#2}}
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% add coauthor
%% wichit2s
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\newcommand{\coauthortitle}[2]{ % define Title of Author
\newcommand{\@ThaiCoAuthorTitle}{#1}
\newcommand{\@EnglishCoAuthorTitle}{#2}
}
\newcommand{\thesiscoauthor}[2]{ % define author
\newcommand{\@ThaiCoAuthor}{#1}
\newcommand{\@EnglishCoAuthor}{#2}
\newcommand{\@EnglishCoAuthorUP}{\uppercase{#2}}
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\newcommand{\thesistitle}[2]{ % define Thesis' title
\newcommand{\@ThaiTitle}{#1}
\newcommand{\@EnglishTitle}{#2}
}
\newcommand{\advisor}[4]{ % define Advisor
\newcommand{\@ThaiAdvisor}{#1}
\newcommand{\@ThaiAdvisorShort}{#2}
\newcommand{\@EnglishAdvisor}{#3}
\newcommand{\@EnglishAdvisorUP}{\uppercase{#3}}
\newcommand{\@EnglishAdvisorShort}{#4}
\newcommand{\@EnglishAdvisorShortUP}{\uppercase{#4}}
}
\newcommand{\coadvisor}[4]{ % define co-author (auto include coadvision option)
\newcommand{\@ThaiCoAdvisor}{#1}
\newcommand{\@ThaiCoAdvisorShort}{#2}
\newcommand{\@EnglishCoAdvisor}{#3}
\newcommand{\@EnglishCoAdvisorUP}{\uppercase{#3}}
\newcommand{\@EnglishCoAdvisorShort}{#4}
\newcommand{\@EnglishCoAdvisorShortUP}{\uppercase{#4}}
\@coadvisortrue
}
\newcommand{\faculty}[2]{ % define faculty
\newcommand{\@ThaiFaculty}{#1}
\newcommand{\@EnglishFaculty}{#2}
}
\newcommand{\department}[2]{ % define department
\newcommand{\@ThaiDept}{#1}
\newcommand{\@EnglishDept}{#2}
}
\newcommand{\fieldofstudy}[2]{ % define field of study
\newcommand{\@ThaiFieldOfStudy}{#1}
\newcommand{\@EnglishFieldOfStudy}{#2}
\newcommand{\@EnglishFieldOfStudyUP}{\uppercase{#2}}
}
\newcommand{\degree}[2]{ % define degree name
\newcommand{\@ThaiDegree}{#1}
\newcommand{\@EnglishDegree}{#2}
}
\newcommand{\academicyear}[1]{ % define academic year
\newcounter{AcadYear}
\setcounter{AcadYear}{#1}
\newcommand{\@ThaiAcademicYear}{\theAcadYear}
\newcounter{EngAcadYear}
\setcounter{EngAcadYear}{\value{AcadYear}-543}
\newcommand{\@EnglishAcademicYear}{\theEngAcadYear}
}
\newcommand{\deanname}[2]{ % define name of the dean
\newcommand{\@ThaiDeanName}{#1}
\newcommand{\@EnglishDeanName}{#2}
}
\newcommand{\subjID}[1]{
\newcommand{\@subjID}{#1}
}
\newcommand{\subjName}[2]{
\newcommand{\@ThaiSubjName}{#1}
\newcommand{\@EnglishSubjName}{#2}
}
\newcommand{\keywords}[1]{ % define keywords
\newcommand{\@Keywords}{\uppercase{#1}}
}
\newcommand{\authorid}[1]{ % define student ID of the author
\newcommand{\@AuthorID}{#1}
}
\newcommand{\committee}[1]{ % define commitee
\newcommand{\@Committee}{
\if@thaithesis \fi
#1
}
}
%% additional counter, length, reference, etc
\newcounter{subsubsubsection}[subsubsection]
\setcounter{subsubsection}{0} % this class allow subsubsubsection
\newcounter{bib} \setcounter{bib}{0}
\newcounter{TotalPage} \setcounter{TotalPage}{0}
\newcounter{isAppendiced} \setcounter{isAppendiced}{0}
\setcounter{tocdepth}{5}
\setcounter{secnumdepth}{5}
\newlength{\pageleft} % for the remaining space of the page
\renewcommand{\thechapter}{\@ThaiFont\@arabic\c@chapter} % \ref{} in chapter
\renewcommand{\thesection}{\@ThaiFont\thechapter.\@arabic\c@section} % \ref{} in section
\renewcommand{\thesubsection}{\@ThaiFont\thesection.\@arabic\c@subsection} % \ref{} in subsection
\renewcommand{\thesubsubsection}{\@ThaiFont\thesubsection.\@arabic\c@subsubsection} % \ref{} in subsubsection
\renewcommand{\thesubsubsubsection}{\@ThaiFont\thesubsubsection.\@arabic\c@subsubsubsection}% \ref{} in subsubsubsection
\renewcommand{\@cite}[1]{[#1]}
%\renewcommand{\@biblabel}[1]{#1.} %%Change [1] to 1.
%% command for appendix
\newcommand\startappendix{
%readjust toc length
\addtocontents{toc}{\protect\vspace*{0.5cm}}
\addtocontents{toc}{\protect\setlength{\tocindentchap}{1.4em}}
\addtocontents{toc}{\protect\gentocwidthparam} %regen according to new chapter indent
\addtocontents{toc}{\protect{\setlength{\tocnwidthchap}{10.0em}}} %set the nwidth of chapter AFTER generate (to accommodate \appendixname)
\par
\setcounter{chapter}{0}%
\setcounter{section}{0}%
\setcounter{isAppendiced}{1}%
\renewcommand\@chapapp{\appendixname}%
\if@thaithesis
\renewcommand{\thechapter}{\@thaialph\c@chapter}
\else
\renewcommand{\thechapter}{\@Alph\c@chapter}
\fi
\newpage
\thispagestyle{empty}
\centerline{~}
\vfill
\ifnum \@numappendices > 1
\centerline{\Large \appendicespage}
\else
\centerline{\Large \appendixpage}
\fi
\vfill
\centerline{~}
}
%%%%%%%%%%%%%%%
% page layout %
%%%%%%%%%%%%%%%
\setlength{\textheight}{25.00cm} % text-area height
\geometry{paperwidth=8.27in,paperheight=11.69in,top=1.5in,bottom=1in,left=1.5in,right=1.0in} % set paper size and page margin
\setlength{\headheight}{0.00cm} %
\setlength{\headsep}{1.00cm} %
\setlength{\marginparsep}{0.00cm} %
\setlength{\marginparwidth}{0.00cm} %
\setlength{\footskip}{0.00cm} %
\setlength{\parindent}{1.00cm} % paragraph indent
\setlength{\parskip}{0.20cm} % distance between paragraphs
%%%%%%%%%%%%%%%%%%
% page numbering %
%%%%%%%%%%%%%%%%%%
\def\ps@headings{\def\@oddhead{{\slshape\rightmark}\hfil\if@thaithesis\fi\thepage}}
\pagestyle{myheadings}
\if@thaithesis
\pagenumbering{thaialph}
\else
\pagenumbering{roman}
\fi
%%%%%%%%%%%%%%%%%%
% small commands %
%%%%%%%%%%%%%%%%%%
\renewcommand\chapter{
\selectthesislang
\if@openright\cleardoublepage\else\clearpage\fi
\thispagestyle{empty}%
\global\@topnum\z@ % Prevents figures from going at top of page.
\@afterindenttrue
\ifnum \c@chapter = 0
\ifnum \c@isAppendiced = 0
\pagenumbering{arabic}
\toccont
\addtocontents{toc}{\protect\leftline{\bfseries \chaptername}}
\else
\toccont
\addtocontents{toc}{\protect\vspace*{-0.1cm}}
\ifnum \@numappendices > 1
\addtocontents{toc}{\protect\contentsline{nchapter}{\bfseries \appendicesname}{\@ThaiFont\thepage}}
\else
\addtocontents{toc}{\protect\contentsline{nchapter}{\bfseries \appendixname}{\@ThaiFont\thepage}}
\fi
\fi
\fi
\ifnum \c@isAppendiced = 1
\addtocontents{toc}{\protect\vspace*{-0.1cm}}
\fi
\secdef\@chapter\@schapter
}
\def\@chapter[#1]#2{
\refstepcounter{chapter}
\toccont
\addtocontents{toc}{\protect\vspace*{0cm}}
\ifnum \c@isAppendiced = 0
\addcontentsline{toc}{chapter}{\protect\numberline{\thechapter}#1}
\else
\addcontentsline{toc}{chapter}{\appendixname~\protect\numberline{\thechapter}#1}
\fi
\@makechapterhead{#2}
\@afterheading
\indent
}
\def\@schapter#1{
{
\parindent \z@ \centering % zero indent (\z@ = 0pt}
\bfseries\Large #1 \par\nobreak
}
\@afterheading
\indent
}
\def\@makechapterhead#1{%
{
\parindent \z@ \centering
\bfseries\Large \MakeUppercase{\@chapapp}
\ifnum \c@isAppendiced = 0 % test if this chapter is an appendix
\if@thaithesis
\@ThaiFont\arabic{chapter}
\else
\Roman{chapter}
\fi
\else
\if@thaithesis
\thalph{chapter}
\else
\Alph{chapter}
\fi
\fi
\par\nobreak
\bfseries\Large \uppercase{#1} \par\nobreak
}
}
\renewcommand{\section}{
\toccont
\addtocontents{toc}{\protect\vspace*{-0.1cm}\@ThaiFont}
\@startsection{section}{2}{0cm}{0cm}{0.001cm}{\bfseries\large}
}
\renewcommand{\subsection}{
\toccont
\addtocontents{toc}{\protect\vspace*{-0.1cm}\@ThaiFont}
\@startsection{subsection}{3}{0cm}{0cm}{0.001cm}{\bfseries}
}
\renewcommand{\subsubsection}{
\toccont
\addtocontents{toc}{\protect\vspace*{-0.1cm}\@ThaiFont}
\@startsection{subsubsection}{4}{0cm}{0cm}{0.001cm}{\bfseries}
}
\newcommand{\subsubsubsection} {
\toccont
\addtocontents{toc}{\protect\vspace*{-0.1cm}}
\@startsection{subsubsubsection}{5}{0cm}{0cm}{0.001cm}{\bfseries}
}
%%%%%%%%%%%%
% contents %
%%%%%%%%%%%%
\renewcommand\@pnumwidth{0.5cm} % toc's parameter
\renewcommand\@tocrmarg{1.5cm} % toc's parameter
\renewcommand\@dotsep{4} % toc's parameter
\addtocontents{toc}{\protect\rightline{\pagename}}
\newlength{\tocindentchap}
\newlength{\tocnwidthchap}
\newlength{\tocindentsection}
\newlength{\tocnwidthsection}
\newlength{\tocindentsubsection}
\newlength{\tocnwidthsubsection}
\newlength{\tocindentsubsubsection}
\newlength{\tocnwidthsubsubsection}
\newlength{\tocindentsubsubsubsection}
\newlength{\tocnwidthsubsubsubsection}
\newlength{\tocnwidthperstep}
\newlength{\tocnwidthoffset}
\setlength{\tocnwidthperstep}{0.8em}
\setlength{\tocnwidthoffset}{1.4em}
\setlength{\tocindentchap}{0.0em}
\setlength{\tocnwidthchap}{\tocnwidthoffset}
\newcommand{\gentocwidthparam}{
\setlength{\tocindentsection}{\tocindentchap + \tocnwidthchap}
\setlength{\tocnwidthsection}{\tocnwidthoffset + \tocnwidthperstep * 1}
\setlength{\tocindentsubsection}{\tocindentsection + \tocnwidthsection}
\setlength{\tocnwidthsubsection}{\tocnwidthoffset + \tocnwidthperstep * 2}
\setlength{\tocindentsubsubsection}{\tocindentsubsection + \tocnwidthsubsection}
\setlength{\tocnwidthsubsubsection}{\tocnwidthoffset + \tocnwidthperstep * 3}
\setlength{\tocindentsubsubsubsection}{\tocindentsubsubsection + \tocnwidthsubsubsection}
\setlength{\tocnwidthsubsubsubsection}{\tocnwidthoffset + \tocnwidthperstep * 3}
}
\gentocwidthparam
\newcommand{\l@nchapter}{\@dottedtocline{0}{0cm}{0cm}}
\renewcommand{\l@chapter}[2]{\@dottedtocline{0}{\tocindentchap}{\tocnwidthchap}{\bfseries #1}{\bfseries #2}}
\renewcommand{\l@section}{\@dottedtocline{1}{\tocindentsection}{\tocnwidthsection}}
\renewcommand{\l@subsection}{\@dottedtocline{2}{\tocindentsubsection}{\tocnwidthsubsection}}
\renewcommand{\l@subsubsection}{\@dottedtocline{3}{\tocindentsubsubsection}{\tocnwidthsubsubsection}}
\newcommand{\l@subsubsubsection}{\@dottedtocline{4}{\tocindentsubsubsubsection}{\tocnwidthsubsubsubsection}}
\renewcommand{\l@table}{\@dottedtocline{0}{0cm}{1.6em}}
\renewcommand{\l@figure}{\@dottedtocline{0}{0cm}{2.4em}}
\renewcommand{\tableofcontents}{
\selectthesislang
\thispagestyle{empty}
\toccont
\addtocontents{toc}{\protect\vspace*{-0.1cm}}
\addtocontents{toc}{\protect\contentsline{nchapter}{\bfseries \contentsname}{\@ThaiFont\thepage}}
\centerline{\bfseries\Large \contentsname}
\@starttoc{toc}
}
\newcommand{\toccont}{
\addtocontents{toc}{
\protect\setlength{\protect\pageleft}{\protect\textheight - \protect\pagetotal}
\protect\ifdim \protect\pageleft < 1cm
\protect\newpage
\protect\centerline{\bfseries\Large }
{\hspace{-1cm}\chaptername\hfill\pagename\hspace{-0.1cm}}
\protect\fi
}
}
%%%%%%%%%%%%%%%%%
% list of table %
%%%%%%%%%%%%%%%%%
\setlength{\arraycolsep}{5\p@} % tabular's parameter
\setlength{\tabcolsep}{6\p@} % tabular's parameter
\setlength{\arrayrulewidth}{.4\p@} % tabular's parameter
\setlength{\doublerulesep}{2\p@} % tabular's parameter
\renewcommand{\arraystretch}{1.0} % tabular's parameter
\renewcommand{\thetable}{\ifnum\c@chapter>\z@\thechapter.\fi\@arabic\c@table}
\def\fps@table{tbp}
\def\ftype@table{2}
\def\ext@table{lot}
\def\fnum@table{\tablename~\thetable}
\renewenvironment{table}{
\@float{table}
}{
\lotcont
\end@float
}
\setlength{\abovecaptionskip}{10\p@}
\setlength{\belowcaptionskip}{10\p@}
\long\def\@makecaption#1#2{
\vskip\abovecaptionskip
\sbox\@tempboxa{#1: #2}
\ifdim \wd\@tempboxa > \hsize
#1: #2\par
\else
\global \@minipagefalse
\hb@xt@\hsize{\hfil\box\@tempboxa\hfil}
\fi
\vskip\belowcaptionskip}
\renewcommand{\listoftables}{
\toccont
\addtocontents{toc}{\protect\vspace*{-0.1cm}}
\addtocontents{toc}{\protect\contentsline{nchapter}{\bfseries \listtablename}{\@ThaiFont\thepage}}
\centerline{\bfseries\Large \listtablename}
\@starttoc{lot}
\addtocontents{lot}{\hspace{-1cm}\tablename\hfill\pagename\hspace{-0.1cm}}
\addtocontents{lot}{\protect\setlength{\parskip}{0.0cm}} % distance between paragraphs
}
\newcommand{\lotcont}{
\addtocontents{lot}{
\protect\setlength{\protect\pageleft}{\protect\textheight - \protect\pagetotal}
\protect\ifdim \protect\pageleft < 1cm
\protect\newpage
{\hspace{-1cm}\tablename\hfill\pagename\hspace{-0.1cm}}
\protect\fi
}
}
%%%%%%%%%%%%%%%%%%%
% list of figures %
%%%%%%%%%%%%%%%%%%%
\renewcommand{\thefigure}{\ifnum\c@chapter>\z@\thechapter.\fi\@arabic\c@figure}
\def\fps@figure{tbp}
\def\ftype@figure{1}
\def\ext@figure{lof}
\def\fnum@figure{\figurename~\thefigure}
\renewenvironment{figure}{
\@float{figure}
}{
\lofcont
\end@float
}
\renewcommand{\listoffigures}{
\toccont
\addtocontents{toc}{\protect\vspace*{-0.1cm}}
\addtocontents{toc}{\protect\contentsline{nchapter}{\bfseries \listfigurename}{\@ThaiFont\thepage}}
\addtocontents{toc}{\protect\vspace*{0.5cm}}
\centerline{\bfseries\Large \listfigurename}
\@starttoc{lof}
\addtocontents{lof}{\hspace{-1cm}\figurename\hfill\pagename\hspace{-0.1cm}}
%% my new attempt
\addtocontents{lof}{\protect\setlength{\parskip}{0.0cm}} % distance between paragraphs
\addtocontents{lof}{\protect\thispagestyle{myheadings}}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% save number of roman pages %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\addtocounter{TotalPage}{\arabic{page}}
}
\newcommand{\lofcont}{
\addtocontents{lof}{
\protect\setlength{\protect\pageleft}{\protect\textheight - \protect\pagetotal}
\protect\ifdim \protect\pageleft < 1cm
\protect\newpage
{\hspace{-1cm}\figurename\hfill\pagename\hspace{-0.1cm}}
\protect\fi
}
}
%%%%%%%%%%%%
% equation %
%%%%%%%%%%%%
\@addtoreset{equation}{chapter}
\renewcommand{\theequation}{\ifnum\c@chapter>\z@\thechapter.\fi\@arabic\c@equation}
%%%%%%%%%%%%%
% emphasize %
%%%%%%%%%%%%%
\newcommand\e[1]{{\normalem \emph{#1}}}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Front matter commands
%%
%% These commands generate the first few pages of the thesis, such as
%% Thai Title, English Title, Committee Page, Abstract,
%% Acknowledgement, etc.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\newcommand{\makethaicover}{
%\fontsize{13}{15}\selectfont {
\large
\thispagestyle{empty}
\centerline{ \begin{tabular}{p{14cm}}\centering\@ThaiTitle\end{tabular} }
\centerline{ \begin{tabular}{p{14cm}}\centering\@EnglishTitle\end{tabular}}
\vfill
\centerline{\@ThaiAuthorTitle\@ThaiAuthor}
\if\@ThaiCoAuthorTitle
\centerline{\@ThaiCoAuthorTitle\@ThaiCoAuthor}
\fi
\if\@ThaiCoAuthorTitle
\vspace{1.7cm}
\else
\vspace{2cm}
\fi
\vfill
\begin{center}
{\@ThaiBookTitle}นี้เป็นส่วนหนึ่งของการศึกษา \\
หลักสูตร{\@ThaiDegree} สาขาวิชา{\@ThaiFieldOfStudy} \\
ภาควิชา{\@ThaiDept} คณะ{\@ThaiFaculty} \\
มหาวิทยาลัยอุบลราชธานี \\
ปีการศึกษา {\begin{english}\@ThaiAcademicYear\end{english}} \\
ลิขสิทธิ์ของมหาวิทยาลัยอุบลราชธานี
\end{center}
\normalsize
}
\newcommand{\makeenglishcover}{
\fontsize{11}{15}\selectfont
\thispagestyle{empty}
\centerline{\begin{tabular}{p{14cm}}\centering\@EnglishTitle\end{tabular}}
\vfill
\centerline{\@EnglishAuthorTitle~\@EnglishAuthor} \\
\if@EnglishCoAuthorTitle
\centerline{\@EnglishCoAuthorTitle~\@EnglishCoAuthor}
\vspace{1.7cm}
\else
\vspace{2cm}
\if
\vfill
\begin{center}
A {\@EnglishBookTitle} Submitted in Partial Fulfillment of the Requirements \\
for the Degree of {\@EnglishDegree} Program in {\@EnglishFieldOfStudy} \\
Department of {\@EnglishDept} \\
Faculty of {\@EnglishFaculty} \\
Ubon Ratchathani University \\
Academic Year {\@EnglishAcademicYear} \\
Copyright of Ubon Ratchathani University
\end{center}
}
\newcommand{\ThaiCommittee}[1]{
\thispagestyle{empty}
\noindent
\begin{tabular}{@{}p{3.8cm}p{0.5cm}p{9.2cm}}
{{\@ThaiBookTitle}} & : & \@ThaiTitle \\
{} & {} & \@EnglishTitle \\
{โดย} &: & \@ThaiAuthorTitle\@ThaiAuthor \\
\if@thesiscoauthor
&: & \@ThaiCoAuthorTitle\@ThaiCoAuthor \\
\fi
{อาจารย์ที่ปรึกษา} & : & \@ThaiAdvisorShort \\
\if@coadvisor
{อาจารย์ที่ปรึกษาร่วม} & : & \@ThaiCoAdvisor \\
\fi
{ระดับการศึกษา} & : & {\@ThaiDegree} สาขาวิชา{\@ThaiFieldOfStudy} \\
{ปีการศึกษา} & : & \@ThaiAcademicYear \\
\end{tabular}
\vspace*{0.4cm}
\hrule width 15 cm height 0.0 cm depth 0.025 cm
\begin{center}
{\bfseries
ได้รับการพิจารณาให้เป็นส่วนหนึ่งของการศึกษา \\
ตามหลักสูตร{\@ThaiDegree} สาขา{\@ThaiFieldOfStudy} \\
}
\end{center}
%\if@ugrad {ภาควิชา\@ThaiDept} \fi {คณะ\@ThaiFaculty} {มหาวิทยาลัยอุบลราชธานี} {อนุมัติให้นับ{\@ThaiBookTitle}ฉบับนี้เป็นส่วนหนี่งของการศึกษาตามหลักสูตร{\@ThaiDegreeType}} \if@ugrad ในรายวิชา {\@subjID} {\@ThaiSubjName} \fi
% \vspace*{0.3cm}
\noindent
\hspace*{1.5cm} {\bfseries คณะกรรมการสอบประเมินความรู้โครงงานคอมพิวเตอร์}
\noindent
\begin{tabular}{p{3cm}>{\centering\arraybackslash}p{6cm}l}
\@Committee
\end{tabular}
\noindent
\begin{tabular}{p{3cm}>{\centering\arraybackslash}p{6cm}l}
\hspace*{0.5cm} & \hspace*{8.0cm} & \\
& \dotfill & {\if@ugrad{หัวหน้าภาควิชา}\else{คณบดีคณะ{\@ThaiFaculty}}\fi} \\
& {(\@ThaiDeanName)}
\end{tabular}
\noindent
\begin{tabular}{p{3cm}>{\centering\arraybackslash}p{6cm}l}
\hspace*{0.5cm} & \hspace*{8.0cm} & \\
& วันที่\fillin[1cm]/\fillin[1cm]/\fillin[1cm] & {}
\end{tabular}
}
\newcommand{\EnglishCommittee}{
\fontsize{11}{13.2}\selectfont
\setlength{\textwidth}{16.50cm}
\thispagestyle{empty}
\noindent
\begin{tabular}{p{3cm}p{11cm}}
\@EnglishBookTitle Title & \@EnglishTitle \\
By & \@EnglishAuthorTitle\@EnglishAuthor \\
Field of Study & \@EnglishFieldOfStudy \\
\@EnglishBookTitle~Advisor & \@EnglishAdvisor \\
\if@coadvisor
\@EnglishBookTitle~Co-advisor & \@EnglishCoAdvisor \\
\fi
\end{tabular}
\vspace*{0.4cm}
\hrule width 15 cm height 0.0 cm depth 0.025 cm
Accepted by the \if@ugrad Department of \@EnglishDept\fi Faculty of \@EnglishFaculty, Ubon Ratchathani University in Partial Fulfillment of the Requirements for the \@EnglishDegreeType \if@ugrad in {\@subjID} {\@EnglishSubjName}\fi
\noindent
\begin{tabular}{p{3cm}p{6cm}>{\raggedright\arraybackslash}p{4.5cm}}
\hspace*{0.5cm} & \hspace*{8.0cm} & \\
& \dotfill & Dean of the {\if@ugrad{Department of \@EnglishDept}\else{Faculty of \@EnglishFaculty}\fi} \\
& \multicolumn{2}{l}{(\@EnglishDeanName)}
\end{tabular}
\vspace*{0.4cm}
\noindent
\if@ugrad{PROJECT}\else{THESIS}\fi~COMMITTEE
\noindent
\begin{tabular}{p{3cm}>{\centering\arraybackslash}p{6cm}l}
\@Committee
\end{tabular}
\setlength{\textwidth}{15.00cm}
}
\newcommand{\makecommittee} {
\protect\if@thaithesis
\ThaiCommittee
\protect\else
\EnglishCommittee
\protect\fi
}
\newcommand{\CommitteeBlock}[2] {
\hspace*{0.5cm} & \hspace*{8.0cm} & \\
& \dotfill & {#1} \\
& {(#2)} \\
}
\newcommand{\CommitteeBlockAdvisor} {
\hspace*{0.5cm} & \hspace*{8.0cm} & \\
& \dotfill & {\if@thaithesis {อาจารย์ที่ปรึกษา} \else \@EnglishBookTitle~Advisor \fi} \\
& (\if@thaithesis \@ThaiAdvisorShort \else \@EnglishAdvisor \fi) \\
}
\newcommand{\CommitteeBlockCoAdvisor} {
\if@coadvisor
\hspace*{0.5cm} & \hspace*{8.0cm} & \\
& \dotfill & {\if@thaithesis {อาจารย์ที่ปรึกษาร่วม} \else {\@EnglishBookTitle}~Co-advisor \fi} \\
& (\if@thaithesis \@ThaiCoAdvisorShort \else \@EnglishCoAdvisor~ \fi) \\
\fi
}
%%environment for multiple paragraph page such as abstract and acknowledgement
\newenvironment{thaiabstract}{
\fontsize{11}{15}\selectfont
\thispagestyle{headings}
\toccont
\@ThaiFont
\addtocontents{toc}{\protect\vspace*{-0.1cm}}
\addtocontents{toc}{\protect\contentsline{nchapter}{\bfseries\@AbstractThaiString}{\@ThaiFont\thepage}}
\noindent
\begin{tabular}{@{}p{3.8cm}p{0.5cm}p{9.2cm}}
{{\@ThaiBookTitle}} & : & \@ThaiTitle \\
%{} & {} & \@EnglishTitle \\
{โดย} & : & \@ThaiAuthorTitle\@ThaiAuthor \\
\if@thesiscoauthor
&: & \@ThaiCoAuthorTitle\@ThaiCoAuthor \\
\fi
{อาจารย์ที่ปรึกษา} & : & \@ThaiAdvisorShort \\
\if@coadvisor
{อาจารย์ที่ปรึกษาร่วม} & : & \@ThaiCoAdvisor \\
\fi
{ระดับการศึกษา} & : & {\@ThaiDegree} สาขาวิชา{\@ThaiFieldOfStudy} \\
{ปีการศึกษา} & : & \@ThaiAcademicYear \\
\end{tabular}
\vspace*{0.4cm}
\hrule width 15 cm height 0.0 cm depth 0.025 cm
\vspace*{0.4cm}
\centerline{\bfseries\Large บทคัดย่อ}
%\normalsize
}
\newenvironment{englishabstract}{
\fontsize{11}{15}\selectfont
\thispagestyle{headings}
\toccont
\@ThaiFont
\addtocontents{toc}{\protect\vspace*{-0.1cm}}
\addtocontents{toc}{\protect\contentsline{nchapter}{\bfseries\@AbstractEnglishString}{\@ThaiFont\thepage}}
\noindent
\begin{tabular}{@{}p{3.8cm}p{0.5cm}p{9.2cm}}
{Topic} & : & \@EnglishTitle \\
%{} & {} & \@EnglishTitle \\
{Author} & : & \uppercase{\@EnglishAuthorUP} \\
\if@thesiscoauthor
&: & \uppercase{\@EnglishCoAuthorUP} \\
\fi
{Advisor} & : & \@EnglishAdvisorShort \\
\if@coadvisor
{Co-advisor} & : & \@EnglishCoAdvisorShort \\
\fi
{Degree} & : & {\@EnglishDegree} ({\@EnglishFieldOfStudy}) \\
{Academic Year} & : & \@EnglishAcademicYear \\
\end{tabular}
\vspace*{0.4cm}
\hrule width 15 cm height 0.0 cm depth 0.025 cm
\vspace*{0.4cm}
\centerline{\bfseries\Large Abstract}
%\normalsize
}
\newenvironment{englishabstract2}{
% \selectthesislang
\fontsize{11}{15}\selectfont
\thispagestyle{headings}
\toccont
\@ThaiFont
\addtocontents{toc}{\protect\vspace*{-0.1cm}}
\addtocontents{toc}{\protect\contentsline{nchapter}{\bfseries \@AbstractEnglishString}{\@ThaiFont\thepage}}
\noindent
\#\# \@AuthorID : MAJOR \uppercase{\@EnglishFieldOfStudyUP} \\
KEYWORDS: \@KeywordsEnglish
\vspace{-\parskip}
\hangindent = 1.0 cm \hangafter = 1
\uppercase{\@EnglishAuthorUP} : \@EnglishTitle. ADVISOR : \uppercase{\@EnglishAdvisorShort},
{\if@coadvisor \MakeUppercase{\@EnglishBookTitle} COADVISOR : \uppercase{\@EnglishCoAdvisorShort},\fi } \ref{@TheLastPage} pp.
} {
\vfill
\noindent
\begin{tabular}{l@{}p{6.2cm}p{5.6cm}@{}}
& \\
Department &: {\@EnglishDept}\dotfill & Student's Signature \dotfill \\
Field of Study &: {\@EnglishFieldOfStudy}\dotfill & Advisor's Signature \dotfill \\
Academic Year &: {\@EnglishAcademicYear}\dotfill &
\if@coadvisor
Co-advisor's signature \dotfill \\
\fi
\end{tabular}
}
\newenvironment{acknowledgements}{
\selectthesislang
\fontsize{11}{15}
\toccont
\addtocontents{toc}{\protect\vspace*{-0.1cm}}
\addtocontents{toc}{\protect\contentsline{nchapter}{\bfseries \@AcknowledgementsString}{\@ThaiFont\thepage}}
\centerline{\bfseries\Large \@AcknowledgementsString}
\noindent
\hfill
\hspace*{1.0cm}
\normalfont
}
\newenvironment{biography}{
\selectthesislang
\newpage
\toccont
\addtocontents{toc}{\protect\vspace*{0.5cm}}
\addtocontents{toc}{\protect\contentsline{nchapter}{\bfseries \@BiographyString}{\@ThaiFont\thepage}}
\centerline{\bfseries\Large \@BiographyString}
} {
%%%%%%%%%%%%%%%%%%%%%
% compute TotalPage %
%%%%%%%%%%%%%%%%%%%%%
\addtocounter{TotalPage}{\arabic{page}}
\addtocounter{TotalPage}{-1}
\refstepcounter{TotalPage}
\label{@TheLastPage}
}
\newcommand\thereferences{
\toccont
\addtocontents{toc}{\protect\vspace*{0.5cm}}
\addtocontents{toc}{\protect\contentsline{nchapter}{\bfseries \bibname}{\@ThaiFont\thepage}\vspace*{0.5cm}}
}
root = true
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
indent_style = space
indent_size = 4
trim_trailing_whitespace = true
[*.md]
trim_trailing_whitespace = false
[*.{yml,yaml}]
indent_size = 2
APP_NAME=Laravel
APP_ENV=local
APP_KEY=
APP_DEBUG=true
APP_URL=http://localhost
LOG_CHANNEL=stack
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel
DB_USERNAME=root
DB_PASSWORD=
BROADCAST_DRIVER=log
CACHE_DRIVER=file
QUEUE_CONNECTION=sync
SESSION_DRIVER=file
SESSION_LIFETIME=120
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379
MAIL_DRIVER=smtp
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_DEFAULT_REGION=us-east-1
AWS_BUCKET=
PUSHER_APP_ID=
PUSHER_APP_KEY=
PUSHER_APP_SECRET=
PUSHER_APP_CLUSTER=mt1
MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
* text=auto
*.css linguist-vendored
*.scss linguist-vendored
*.js linguist-vendored
CHANGELOG.md export-ignore
/node_modules
/public/hot
/public/storage
/storage/*.key
/vendor
.env
.env.backup
.phpunit.result.cache
Homestead.json
Homestead.yaml
npm-debug.log
yarn-error.log
php:
preset: laravel
disabled:
- unused_use
finder:
not-name:
- index.php
- server.php
js:
finder:
not-name:
- webpack.mix.js
css: true
web: vendor/bin/heroku-php-apache2 public/
<p align="center"><img src="https://res.cloudinary.com/dtfbvvkyp/image/upload/v1566331377/laravel-logolockup-cmyk-red.svg" width="400"></p>
<p align="center">
<a href="https://travis-ci.org/laravel/framework"><img src="https://travis-ci.org/laravel/framework.svg" alt="Build Status"></a>
<a href="https://packagist.org/packages/laravel/framework"><img src="https://poser.pugx.org/laravel/framework/d/total.svg" alt="Total Downloads"></a>
<a href="https://packagist.org/packages/laravel/framework"><img src="https://poser.pugx.org/laravel/framework/v/stable.svg" alt="Latest Stable Version"></a>
<a href="https://packagist.org/packages/laravel/framework"><img src="https://poser.pugx.org/laravel/framework/license.svg" alt="License"></a>
</p>
## About Laravel
Laravel is a web application framework with expressive, elegant syntax. We believe development must be an enjoyable and creative experience to be truly fulfilling. Laravel takes the pain out of development by easing common tasks used in many web projects, such as:
- [Simple, fast routing engine](https://laravel.com/docs/routing).
- [Powerful dependency injection container](https://laravel.com/docs/container).
- Multiple back-ends for [session](https://laravel.com/docs/session) and [cache](https://laravel.com/docs/cache) storage.
- Expressive, intuitive [database ORM](https://laravel.com/docs/eloquent).
- Database agnostic [schema migrations](https://laravel.com/docs/migrations).
- [Robust background job processing](https://laravel.com/docs/queues).
- [Real-time event broadcasting](https://laravel.com/docs/broadcasting).
Laravel is accessible, powerful, and provides tools required for large, robust applications.
## Learning Laravel
Laravel has the most extensive and thorough [documentation](https://laravel.com/docs) and video tutorial library of all modern web application frameworks, making it a breeze to get started with the framework.
If you don't feel like reading, [Laracasts](https://laracasts.com) can help. Laracasts contains over 1500 video tutorials on a range of topics including Laravel, modern PHP, unit testing, and JavaScript. Boost your skills by digging into our comprehensive video library.
## Laravel Sponsors
We would like to extend our thanks to the following sponsors for funding Laravel development. If you are interested in becoming a sponsor, please visit the Laravel [Patreon page](https://patreon.com/taylorotwell).
- **[Vehikl](https://vehikl.com/)**
- **[Tighten Co.](https://tighten.co)**
- **[Kirschbaum Development Group](https://kirschbaumdevelopment.com)**
- **[64 Robots](https://64robots.com)**
- **[Cubet Techno Labs](https://cubettech.com)**
- **[Cyber-Duck](https://cyber-duck.co.uk)**
- **[British Software Development](https://www.britishsoftware.co)**
- **[Webdock, Fast VPS Hosting](https://www.webdock.io/en)**
- **[DevSquad](https://devsquad.com)**
- [UserInsights](https://userinsights.com)
- [Fragrantica](https://www.fragrantica.com)
- [SOFTonSOFA](https://softonsofa.com/)
- [User10](https://user10.com)
- [Soumettre.fr](https://soumettre.fr/)
- [CodeBrisk](https://codebrisk.com)
- [1Forge](https://1forge.com)
- [TECPRESSO](https://tecpresso.co.jp/)
- [Runtime Converter](http://runtimeconverter.com/)
- [WebL'Agence](https://weblagence.com/)
- [Invoice Ninja](https://www.invoiceninja.com)
- [iMi digital](https://www.imi-digital.de/)
- [Earthlink](https://www.earthlink.ro/)
- [Steadfast Collective](https://steadfastcollective.com/)
- [We Are The Robots Inc.](https://watr.mx/)
- [Understand.io](https://www.understand.io/)
- [Abdel Elrafa](https://abdelelrafa.com)
- [Hyper Host](https://hyper.host)
- [Appoly](https://www.appoly.co.uk)
- [OP.GG](https://op.gg)
## Contributing
Thank you for considering contributing to the Laravel framework! The contribution guide can be found in the [Laravel documentation](https://laravel.com/docs/contributions).
## Code of Conduct
In order to ensure that the Laravel community is welcoming to all, please review and abide by the [Code of Conduct](https://laravel.com/docs/contributions#code-of-conduct).
## Security Vulnerabilities
If you discover a security vulnerability within Laravel, please send an e-mail to Taylor Otwell via [taylor@laravel.com](mailto:taylor@laravel.com). All security vulnerabilities will be promptly addressed.
## License
The Laravel framework is open-sourced software licensed under the [MIT license](https://opensource.org/licenses/MIT).
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Attraction extends Model
{
//
public $timestamps = false;
protected $fillable =['provinces_id','attractions_id','attractions_name',
'Latitude','longitude','description','image_url'
];
}
<?php
namespace App\Console;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
class Kernel extends ConsoleKernel
{
/**
* The Artisan commands provided by your application.
*
* @var array
*/
protected $commands = [
//
];
/**
* Define the application's command schedule.
*
* @param \Illuminate\Console\Scheduling\Schedule $schedule
* @return void
*/
protected function schedule(Schedule $schedule)
{
// $schedule->command('inspire')
// ->hourly();
}
/**
* Register the commands for the application.
*
* @return void
*/
protected function commands()
{
$this->load(__DIR__.'/Commands');
require base_path('routes/console.php');
}
}
<?php
namespace App\Exceptions;
use Exception;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
class Handler extends ExceptionHandler
{
/**
* A list of the exception types that are not reported.
*
* @var array
*/
protected $dontReport = [
//
];
/**
* A list of the inputs that are never flashed for validation exceptions.
*
* @var array
*/
protected $dontFlash = [
'password',
'password_confirmation',
];
/**
* Report or log an exception.
*
* @param \Exception $exception
* @return void
*/
public function report(Exception $exception)
{
parent::report($exception);
}
/**
* Render an exception into an HTTP response.
*
* @param \Illuminate\Http\Request $request
* @param \Exception $exception
* @return \Illuminate\Http\Response
*/
public function render($request, Exception $exception)
{
return parent::render($request, $exception);
}
}
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\ConfirmsPasswords;
class ConfirmPasswordController extends Controller
{
/*
|--------------------------------------------------------------------------
| Confirm Password Controller
|--------------------------------------------------------------------------
|
| This controller is responsible for handling password confirmations and
| uses a simple trait to include the behavior. You're free to explore
| this trait and override any functions that require customization.
|
*/
use ConfirmsPasswords;
/**
* Where to redirect users when the intended url fails.
*
* @var string
*/
protected $redirectTo = '/home';
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->middleware('auth');
}
}
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\SendsPasswordResetEmails;
class ForgotPasswordController extends Controller
{
/*
|--------------------------------------------------------------------------
| Password Reset Controller
|--------------------------------------------------------------------------
|
| This controller is responsible for handling password reset emails and
| includes a trait which assists in sending these notifications from
| your application to your users. Feel free to explore this trait.
|
*/
use SendsPasswordResetEmails;
}
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
class LoginController extends Controller
{
/*
|--------------------------------------------------------------------------
| Login Controller
|--------------------------------------------------------------------------
|
| This controller handles authenticating users for the application and
| redirecting them to your home screen. The controller uses a trait
| to conveniently provide its functionality to your applications.
|
*/
use AuthenticatesUsers;
/**
* Where to redirect users after login.
*
* @var string
*/
protected $redirectTo = '/home';
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->middleware('guest')->except('logout');
}
}
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\User;
use Illuminate\Foundation\Auth\RegistersUsers;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator;
class RegisterController extends Controller
{
/*
|--------------------------------------------------------------------------
| Register Controller
|--------------------------------------------------------------------------
|
| This controller handles the registration of new users as well as their
| validation and creation. By default this controller uses a trait to
| provide this functionality without requiring any additional code.
|
*/
use RegistersUsers;
/**
* Where to redirect users after registration.
*
* @var string
*/
protected $redirectTo = '/home';
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->middleware('guest');
}
/**
* Get a validator for an incoming registration request.
*
* @param array $data
* @return \Illuminate\Contracts\Validation\Validator
*/
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:8', 'confirmed'],
]);
}
/**
* Create a new user instance after a valid registration.
*
* @param array $data
* @return \App\User
*/
protected function create(array $data)
{
return User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => Hash::make($data['password']),
]);
}
}
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\ResetsPasswords;
class ResetPasswordController extends Controller
{
/*
|--------------------------------------------------------------------------
| Password Reset Controller
|--------------------------------------------------------------------------
|
| This controller is responsible for handling password reset requests
| and uses a simple trait to include this behavior. You're free to
| explore this trait and override any methods you wish to tweak.
|
*/
use ResetsPasswords;
/**
* Where to redirect users after resetting their password.
*
* @var string
*/
protected $redirectTo = '/home';
}
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\VerifiesEmails;
class VerificationController extends Controller
{
/*
|--------------------------------------------------------------------------
| Email Verification Controller
|--------------------------------------------------------------------------
|
| This controller is responsible for handling email verification for any
| user that recently registered with the application. Emails may also
| be re-sent if the user didn't receive the original email message.
|
*/
use VerifiesEmails;
/**
* Where to redirect users after verification.
*
* @var string
*/
protected $redirectTo = '/home';
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->middleware('auth');
$this->middleware('signed')->only('verify');
$this->middleware('throttle:6,1')->only('verify', 'resend');
}
}
<?php
namespace App\Http\Controllers;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Routing\Controller as BaseController;
class Controller extends BaseController
{
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
}
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Session;
use App\Attraction;
use GuzzleHttp\Client;
use Redirect;
class ResultController extends Controller
{
public $results = array();
function getresult(Request $request){
$getselects = Session::get('attraction_id');
$lat=$request->input('lat');
$lng=$request->input('lng');
$url= $this->geturl($lat,$lng,$getselects);
$getselects = $this->getdistance($url,$getselects);
while (count($getselects)>1) {
$place = Attraction::where('attractions_id',end($this->results) )->get()->toArray();
foreach ($place as $p) {
$lat=$p["Latitude"];
$lng=$p["longitude"];
}
$url=$this->geturl($lat,$lng,$getselects);
$getselects = $this->getdistance($url,$getselects);
}
if(count($getselects)==1){
foreach ($getselects as $getselect) {
//dd($getselects,$getselect);
array_push($this->results,$getselect);
}
}
//dd($this->results);
Session::put('result', 'have');
$dataresults=array();
foreach($this->results as $result){
$dataresult = Attraction::where('attractions_id',$result )->get()->toArray();
$dataresults=array_merge($dataresults,$dataresult);
}
return view('result')->with('dataresults',$dataresults);
}
public function geturl($lat,$lng,$getselects){
$url = "https://maps.googleapis.com/maps/api/distancematrix/json?origins=".$lat.",".$lng."&destinations=";
$i=1;
foreach ($getselects as $getselect) {
$place = Attraction::where('attractions_id',$getselect )->get()->toArray();
foreach ($place as $p) {
$deslat=$p["Latitude"];
$deslng=$p["longitude"];
$url .= $deslat.",".$deslng;
}
if($i!=count($getselects)){
$i++;
$url .= "|";
}else {
$url .= "&key=AIzaSyAQLj-_PEe0qXFXtqhs_EdE-ZmC5zoReMs";
}
}
return $url;
}
public function getdistance($url,$getselects){
$mindistance = null;
$index=null;
$client = new \GuzzleHttp\Client();
$response = $client->request('GET', $url);
$data = $response->getBody();
$get_rows = json_decode($data, true);
$get_elements = $get_rows["rows"];
$get_distance = $get_elements[0];
$get_value = $get_distance["elements"];
for ($i=0; $i < count($get_value); $i++) {
$text = $get_value[$i]["distance"]["text"];
$split= explode(" ",$text);
$distance = floatval($split[0]);
if($mindistance==null){
$mindistance = $distance;
$index=$i;
}else {
if ($mindistance>=$distance) {
$mindistance = $distance;
$index=$i;
}
}
}
$i=0;
foreach ($getselects as $getselect) {
if($i==$index){
$index=array_search($getselect, $getselects);
array_push($this->results,$getselects[$index]);
unset($getselects[$index]);
}
$i++;
}
return $getselects;
}
}
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Session;
use Redirect;
use App\Attraction;
class addplace extends Controller
{
public $amount=0;
function add(Request $request){
$id=$request->input('id');
$addPlace = Session::has('attraction_id') ? Session::get('attraction_id') : null;
if ($addPlace==null) {
$addPlace= array();
array_push($addPlace,$id);
$request->session()->put('attraction_id',$addPlace);
}else {
$have=false;
for ($i=0; $i < count($addPlace) ; $i++) {
if ($addPlace[$i]==$id) {
$have=true;
break;
}
}
if($have==false){
array_push($addPlace,$id);
$request->session()->put('attraction_id',$addPlace);
}
}
//$request->session()->flush();
//return redirect()->route('getplace.getdata')
return Redirect::back();
}
function showselect(){
if (Session::has('attraction_id')) {
$selecteds = array();
$getselects = Session::get('attraction_id');
foreach($getselects as $getselect){
$place = Attraction::where('attractions_id',$getselect )->get()->toArray();
$selecteds=array_merge($selecteds,$place);
}
return view('selectview')->with('selecteds',$selecteds);
}else {
return view('selectview');
}
}
function del(Request $request){
$id=$request->input('id');
$getselects = Session::get('attraction_id');
$newgetselects=array();
foreach($getselects as $getselect){
if($getselect!=$id){
array_push($newgetselects,$getselect);
$request->session()->put('attraction_id',$newgetselects);
}
}
if ($newgetselects==null) {
$request->session()->forget('attraction_id');
}
return Redirect::to('selectview');
//return redirect('del','/search');
//return view('selectview')->with('selecteds',$selecteds);
}
function delAllSelect(Request $request){
$request->session()->forget('attraction_id');
return Redirect::to('/');
}
}
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Attraction;
use App\Province;
use Redirect;
use Illuminate\Support\Facades\File;
class adminController extends Controller
{
//
function insertAttraction(Request $request)
{
$this->validate($request,[
'image' => 'required',
'image.*' => 'image|mimes:jpeg,png,jpg,gif,svg|max:2048'
]);
if ($request->hasFile('image')) {
$files = $request->file('image');
foreach($files as $file){
$filename=$file->getClientOriginalName();
$file->move('upload',$filename);
$images[]=$filename;
}
$data=implode("|",$images);
}
$attraction = new Attraction([
'provinces_id' => $request->input('province_id'),
'attractions_name' => $request->input('attractions_name'),
'Latitude' => $request->input('lat'),
'longitude' => $request->input('lng'),
'description' => $request->input('description'),
'image_url' => $data
]);
$attraction->timestamps = false;
$attraction->save();
session()->flash('inserted', 'success');
return Redirect::to('/admin/insert');
}
function insertProvince(Request $request)
{
//dd($request->input('province_id'),$request->input('province_name'));
$province = new Province([
'provinces_id' => $request->input('province_id'),
'provinces_name' => $request->input('province_name')
]);
$province->timestamps = false;
$province->save();
session()->flash('inserted', 'success');
return Redirect::to('/admin/insert');
}
function edit(Request $request)
{
$attraction_id = $request->input('attraction_id');
$attractions = Attraction::where('attractions_id', $attraction_id)->get()->toArray();
return view('update')->with('attractions', $attractions);
}
function update(Request $request)
{
$this->validate($request,[
'image' => 'required',
'image.*' => 'image|mimes:jpeg,png,jpg|max:2048'
]);
$attraction_id = $request->input('attractions_id');
$data = Attraction::where('attractions_id',$attraction_id)->get()->toArray();
$data_img = $data[0]['image_url'];
$pics = explode("|",$data_img);
foreach ($pics as $pic) {
if(file_exists(public_path('upload/'.$pic))){
unlink(public_path('upload/'.$pic));
}
}
if ($request->hasFile('image')) {
/*$file = $request->file('image');
$filename = $file->getClientOriginalName();
$file->move('upload',$filename);*/
$files = $request->file('image');
foreach($files as $file){
$filename=$file->getClientOriginalName();
$file->move('upload',$filename);
$images[]=$filename;
}
$data=implode("|",$images);
}
Attraction::where('attractions_id', $attraction_id)
->update([
'attractions_name' => $request->input('attractions_name'),
'Latitude' => $request->input('lat'),
'longitude' => $request->input('lng'),
'description' => $request->input('description'),
'image_url' => $data
]);
session()->flash('success', 'success');
return Redirect::back();
}
function deleteAttraction(Request $request)
{
$attraction_id = $request->input('attraction_id');
$data = Attraction::where('attractions_id',$attraction_id)->get()->toArray();
$data_img = $data[0]['image_url'];
$pics = explode("|",$data_img);
foreach ($pics as $pic) {
if(file_exists(public_path('upload/'.$pic))){
unlink(public_path('upload/'.$pic));
}
}
$attraction = Attraction::where('attractions_id', $attraction_id);
$attraction->delete();
session()->flash('success', 'success');
return Redirect::back();
}
function deleteProvince(Request $request)
{
$province_id = $request->input('province_id');
$attraction = Attraction::where('provinces_id', $province_id)->get()->toArray();
for ($i=0; $i < count($attraction); $i++) {
$data = $attraction[$i];
$data_img = $data['image_url'];
$pics = explode("|",$data_img);
foreach ($pics as $pic) {
if(file_exists(public_path('upload/'.$pic))){
unlink(public_path('upload/'.$pic));
}
}
}
$attractions = Attraction::where('provinces_id', $province_id);
$attractions->delete();
$province = Province::where('provinces_id', $province_id);
$province->delete();
session()->flash('success', 'success');
return Redirect::to('/admin');
}
function search(Request $request)
{
$province_id = $request->input('province_id');
$attractions = Attraction::where('provinces_id', $province_id)->get()->toArray();
return view('adminsearch')
->with('attractions', $attractions);
}
}
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Attraction;
class detail extends Controller
{
//
function showdetail($id){
$details = Attraction::where('attractions_id',$id)->get()->toArray();
return view('viewdetail')->with('details',$details);
}
}
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Attraction;
class getplace extends Controller
{
//
function getdata(Request $request){
$item=$request->input('province');
$places = Attraction::where('provinces_id',$item)->get()->toArray();
return view('getview')
->with('places',$places);
}
}
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Session;
use App\User;
use Illuminate\Support\Facades\Redirect as FacadesRedirect;
use Redirect;
class loginController extends Controller
{
//
function login(Request $request)
{
$user = $request->input('username');
$pass = $request->input('password');
$admin = User::where('username', 'admin')->first()->toArray();
if ($user == $admin["username"] && $pass == $admin["password"]) {
session()->put('login', true);
return Redirect::to('/admin');
} else {
session()->flash('loginFail', 'fail');
return Redirect::to('/adminlogin');
}
}
function checkLogin()
{
if (Session::has('login')) {
return Redirect::to('admin');
} else
return view('login');
}
function logout(Request $request)
{
$request->session()->forget('login');
return Redirect::to('/');
}
}
<?php
namespace App\Http;
use Illuminate\Foundation\Http\Kernel as HttpKernel;
class Kernel extends HttpKernel
{
/**
* The application's global HTTP middleware stack.
*
* These middleware are run during every request to your application.
*
* @var array
*/
protected $middleware = [
\App\Http\Middleware\TrustProxies::class,
\App\Http\Middleware\CheckForMaintenanceMode::class,
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
\App\Http\Middleware\TrimStrings::class,
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
];
/**
* The application's route middleware groups.
*
* @var array
*/
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
// \Illuminate\Session\Middleware\AuthenticateSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
'api' => [
'throttle:60,1',
'bindings',
],
];
/**
* The application's route middleware.
*
* These middleware may be assigned to groups or used individually.
*
* @var array
*/
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
];
/**
* The priority-sorted list of middleware.
*
* This forces non-global middleware to always be in the given order.
*
* @var array
*/
protected $middlewarePriority = [
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\Authenticate::class,
\Illuminate\Routing\Middleware\ThrottleRequests::class,
\Illuminate\Session\Middleware\AuthenticateSession::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
\Illuminate\Auth\Middleware\Authorize::class,
];
}
<?php
namespace App\Http\Middleware;
use Illuminate\Auth\Middleware\Authenticate as Middleware;
class Authenticate extends Middleware
{
/**
* Get the path the user should be redirected to when they are not authenticated.
*
* @param \Illuminate\Http\Request $request
* @return string
*/
protected function redirectTo($request)
{
if (! $request->expectsJson()) {
return route('login');
}
}
}
<?php
namespace App\Http\Middleware;
use Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode as Middleware;
class CheckForMaintenanceMode extends Middleware
{
/**
* The URIs that should be reachable while maintenance mode is enabled.
*
* @var array
*/
protected $except = [
//
];
}
<?php
namespace App\Http\Middleware;
use Illuminate\Cookie\Middleware\EncryptCookies as Middleware;
class EncryptCookies extends Middleware
{
/**
* The names of the cookies that should not be encrypted.
*
* @var array
*/
protected $except = [
//
];
}
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Support\Facades\Auth;
class RedirectIfAuthenticated
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @param string|null $guard
* @return mixed
*/
public function handle($request, Closure $next, $guard = null)
{
if (Auth::guard($guard)->check()) {
return redirect('/home');
}
return $next($request);
}
}
<?php
namespace App\Http\Middleware;
use Illuminate\Foundation\Http\Middleware\TrimStrings as Middleware;
class TrimStrings extends Middleware
{
/**
* The names of the attributes that should not be trimmed.
*
* @var array
*/
protected $except = [
'password',
'password_confirmation',
];
}
<?php
namespace App\Http\Middleware;
use Fideloper\Proxy\TrustProxies as Middleware;
use Illuminate\Http\Request;
class TrustProxies extends Middleware
{
/**
* The trusted proxies for this application.
*
* @var array|string
*/
protected $proxies;
/**
* The headers that should be used to detect proxies.
*
* @var int
*/
protected $headers = Request::HEADER_X_FORWARDED_ALL;
}
<?php
namespace App\Http\Middleware;
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware;
class VerifyCsrfToken extends Middleware
{
/**
* Indicates whether the XSRF-TOKEN cookie should be set on the response.
*
* @var bool
*/
protected $addHttpCookie = true;
/**
* The URIs that should be excluded from CSRF verification.
*
* @var array
*/
protected $except = [
//
];
}
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*
* @return void
*/
public function register()
{
//
}
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
//
}
}
<?php
namespace App\Providers;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Gate;
class AuthServiceProvider extends ServiceProvider
{
/**
* The policy mappings for the application.
*
* @var array
*/
protected $policies = [
// 'App\Model' => 'App\Policies\ModelPolicy',
];
/**
* Register any authentication / authorization services.
*
* @return void
*/
public function boot()
{
$this->registerPolicies();
//
}
}
<?php
namespace App\Providers;
use Illuminate\Support\Facades\Broadcast;
use Illuminate\Support\ServiceProvider;
class BroadcastServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
Broadcast::routes();
require base_path('routes/channels.php');
}
}
<?php
namespace App\Providers;
use Illuminate\Auth\Events\Registered;
use Illuminate\Auth\Listeners\SendEmailVerificationNotification;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Event;
class EventServiceProvider extends ServiceProvider
{
/**
* The event listener mappings for the application.
*
* @var array
*/
protected $listen = [
Registered::class => [
SendEmailVerificationNotification::class,
],
];
/**
* Register any events for your application.
*
* @return void
*/
public function boot()
{
parent::boot();
//
}
}
<?php
namespace App\Providers;
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Route;
class RouteServiceProvider extends ServiceProvider
{
/**
* This namespace is applied to your controller routes.
*
* In addition, it is set as the URL generator's root namespace.
*
* @var string
*/
protected $namespace = 'App\Http\Controllers';
/**
* Define your route model bindings, pattern filters, etc.
*
* @return void
*/
public function boot()
{
//
parent::boot();
}
/**
* Define the routes for the application.
*
* @return void
*/
public function map()
{
$this->mapApiRoutes();
$this->mapWebRoutes();
//
}
/**
* Define the "web" routes for the application.
*
* These routes all receive session state, CSRF protection, etc.
*
* @return void
*/
protected function mapWebRoutes()
{
Route::middleware('web')
->namespace($this->namespace)
->group(base_path('routes/web.php'));
}
/**
* Define the "api" routes for the application.
*
* These routes are typically stateless.
*
* @return void
*/
protected function mapApiRoutes()
{
Route::prefix('api')
->middleware('api')
->namespace($this->namespace)
->group(base_path('routes/api.php'));
}
}
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Province extends Model
{
//
public $timestamps = false;
protected $fillable =['provinces_id','provinces_name'];
}
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
//
}
#!/usr/bin/env php
<?php
define('LARAVEL_START', microtime(true));
/*
|--------------------------------------------------------------------------
| Register The Auto Loader
|--------------------------------------------------------------------------
|
| Composer provides a convenient, automatically generated class loader
| for our application. We just need to utilize it! We'll require it
| into the script here so that we do not have to worry about the
| loading of any our classes "manually". Feels great to relax.
|
*/
require __DIR__.'/vendor/autoload.php';
$app = require_once __DIR__.'/bootstrap/app.php';
/*
|--------------------------------------------------------------------------
| Run The Artisan Application
|--------------------------------------------------------------------------
|
| When we run the console application, the current CLI command will be
| executed in this console and the response sent back to a terminal
| or another output device for the developers. Here goes nothing!
|
*/
$kernel = $app->make(Illuminate\Contracts\Console\Kernel::class);
$status = $kernel->handle(
$input = new Symfony\Component\Console\Input\ArgvInput,
new Symfony\Component\Console\Output\ConsoleOutput
);
/*
|--------------------------------------------------------------------------
| Shutdown The Application
|--------------------------------------------------------------------------
|
| Once Artisan has finished running, we will fire off the shutdown events
| so that any final work may be done by the application before we shut
| down the process. This is the last thing to happen to the request.
|
*/
$kernel->terminate($input, $status);
exit($status);
<?php
/*
|--------------------------------------------------------------------------
| Create The Application
|--------------------------------------------------------------------------
|
| The first thing we will do is create a new Laravel application instance
| which serves as the "glue" for all the components of Laravel, and is
| the IoC container for the system binding all of the various parts.
|
*/
$app = new Illuminate\Foundation\Application(
$_ENV['APP_BASE_PATH'] ?? dirname(__DIR__)
);
/*
|--------------------------------------------------------------------------
| Bind Important Interfaces
|--------------------------------------------------------------------------
|
| Next, we need to bind some important interfaces into the container so
| we will be able to resolve them when needed. The kernels serve the
| incoming requests to this application from both the web and CLI.
|
*/
$app->singleton(
Illuminate\Contracts\Http\Kernel::class,
App\Http\Kernel::class
);
$app->singleton(
Illuminate\Contracts\Console\Kernel::class,
App\Console\Kernel::class
);
$app->singleton(
Illuminate\Contracts\Debug\ExceptionHandler::class,
App\Exceptions\Handler::class
);
/*
|--------------------------------------------------------------------------
| Return The Application
|--------------------------------------------------------------------------
|
| This script returns the application instance. The instance is given to
| the calling script so we can separate the building of the instances
| from the actual running of the application and sending responses.
|
*/
return $app;
{
"name": "laravel/laravel",
"type": "project",
"description": "The Laravel Framework.",
"keywords": [
"framework",
"laravel"
],
"license": "MIT",
"require": {
"php": "^7.2",
"fideloper/proxy": "^4.0",
"guzzlehttp/guzzle": "^6.4",
"laravel/framework": "^6.2",
"laravel/tinker": "^1.0"
},
"require-dev": {
"facade/ignition": "^1.4",
"fzaninotto/faker": "^1.4",
"mockery/mockery": "^1.0",
"nunomaduro/collision": "^3.0",
"phpunit/phpunit": "^8.0"
},
"config": {
"optimize-autoloader": true,
"preferred-install": "dist",
"sort-packages": true
},
"extra": {
"laravel": {
"dont-discover": []
}
},
"autoload": {
"psr-4": {
"App\\": "app/"
},
"classmap": [
"database/seeds",
"database/factories"
]
},
"autoload-dev": {
"psr-4": {
"Tests\\": "tests/"
}
},
"minimum-stability": "dev",
"prefer-stable": true,
"scripts": {
"post-autoload-dump": [
"Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
"@php artisan package:discover --ansi"
],
"post-root-package-install": [
"@php -r \"file_exists('.env') || copy('.env.example', '.env');\""
],
"post-create-project-cmd": [
"@php artisan key:generate --ansi"
]
}
}
This source diff could not be displayed because it is too large. You can view the blob instead.
<?php
return [
/*
|--------------------------------------------------------------------------
| Application Name
|--------------------------------------------------------------------------
|
| This value is the name of your application. This value is used when the
| framework needs to place the application's name in a notification or
| any other location as required by the application or its packages.
|
*/
'name' => env('APP_NAME', 'Laravel'),
/*
|--------------------------------------------------------------------------
| Application Environment
|--------------------------------------------------------------------------
|
| This value determines the "environment" your application is currently
| running in. This may determine how you prefer to configure various
| services the 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'),
'asset_url' => env('ASSET_URL', null),
/*
|--------------------------------------------------------------------------
| 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',
/*
|--------------------------------------------------------------------------
| Faker Locale
|--------------------------------------------------------------------------
|
| This locale will be used by the Faker PHP library when generating fake
| data for your database seeds. For example, this will be used to get
| localized telephone numbers, street address information and more.
|
*/
'faker_locale' => 'en_US',
/*
|--------------------------------------------------------------------------
| 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',
/*
|--------------------------------------------------------------------------
| 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\Notifications\NotificationServiceProvider::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,
/*
* Package Service Providers...
*/
/*
* Application Service Providers...
*/
App\Providers\AppServiceProvider::class,
App\Providers\AuthServiceProvider::class,
// App\Providers\BroadcastServiceProvider::class,
App\Providers\EventServiceProvider::class,
App\Providers\RouteServiceProvider::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,
'Arr' => Illuminate\Support\Arr::class,
'Artisan' => Illuminate\Support\Facades\Artisan::class,
'Auth' => Illuminate\Support\Facades\Auth::class,
'Blade' => Illuminate\Support\Facades\Blade::class,
'Broadcast' => Illuminate\Support\Facades\Broadcast::class,
'Bus' => Illuminate\Support\Facades\Bus::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,
'Lang' => Illuminate\Support\Facades\Lang::class,
'Log' => Illuminate\Support\Facades\Log::class,
'Mail' => Illuminate\Support\Facades\Mail::class,
'Notification' => Illuminate\Support\Facades\Notification::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,
'Str' => Illuminate\Support\Str::class,
'URL' => Illuminate\Support\Facades\URL::class,
'Validator' => Illuminate\Support\Facades\Validator::class,
'View' => Illuminate\Support\Facades\View::class,
],
];
<?php
return [
/*
|--------------------------------------------------------------------------
| Authentication Defaults
|--------------------------------------------------------------------------
|
| This option controls the default authentication "guard" and password
| reset options for your application. You may change these defaults
| as required, but they're a perfect start for most applications.
|
*/
'defaults' => [
'guard' => 'web',
'passwords' => 'users',
],
/*
|--------------------------------------------------------------------------
| Authentication Guards
|--------------------------------------------------------------------------
|
| Next, you may define every authentication guard for your application.
| Of course, a great default configuration has been defined for you
| here which uses session storage and the Eloquent user provider.
|
| All authentication drivers have a user provider. This defines how the
| users are actually retrieved out of your database or other storage
| mechanisms used by this application to persist your user's data.
|
| Supported: "session", "token"
|
*/
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'token',
'provider' => 'users',
'hash' => false,
],
],
/*
|--------------------------------------------------------------------------
| User Providers
|--------------------------------------------------------------------------
|
| All authentication drivers have a user provider. This defines how the
| users are actually retrieved out of your database or other storage
| mechanisms used by this application to persist your user's data.
|
| If you have multiple user tables or models you may configure multiple
| sources which represent each model / table. These sources may then
| be assigned to any extra authentication guards you have defined.
|
| Supported: "database", "eloquent"
|
*/
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\User::class,
],
// 'users' => [
// 'driver' => 'database',
// 'table' => 'users',
// ],
],
/*
|--------------------------------------------------------------------------
| Resetting Passwords
|--------------------------------------------------------------------------
|
| You may specify multiple password reset configurations if you have more
| than one user table or model in the application and you want to have
| separate password reset settings based on the specific user types.
|
| The expire time is the number of minutes that the reset token should be
| considered valid. This security feature keeps tokens short-lived so
| they have less time to be guessed. You may change this as needed.
|
*/
'passwords' => [
'users' => [
'provider' => 'users',
'table' => 'password_resets',
'expire' => 60,
'throttle' => 60,
],
],
/*
|--------------------------------------------------------------------------
| Password Confirmation Timeout
|--------------------------------------------------------------------------
|
| Here you may define the amount of seconds before a password confirmation
| times out and the user is prompted to re-enter their password via the
| confirmation screen. By default, the timeout lasts for three hours.
|
*/
'password_timeout' => 10800,
];
<?php
return [
/*
|--------------------------------------------------------------------------
| Default Broadcaster
|--------------------------------------------------------------------------
|
| This option controls the default broadcaster that will be used by the
| framework when an event needs to be broadcast. You may set this to
| any of the connections defined in the "connections" array below.
|
| Supported: "pusher", "redis", "log", "null"
|
*/
'default' => env('BROADCAST_DRIVER', 'null'),
/*
|--------------------------------------------------------------------------
| Broadcast Connections
|--------------------------------------------------------------------------
|
| Here you may define all of the broadcast connections that will be used
| to broadcast events to other systems or over websockets. Samples of
| each available type of connection are provided inside this array.
|
*/
'connections' => [
'pusher' => [
'driver' => 'pusher',
'key' => env('PUSHER_APP_KEY'),
'secret' => env('PUSHER_APP_SECRET'),
'app_id' => env('PUSHER_APP_ID'),
'options' => [
'cluster' => env('PUSHER_APP_CLUSTER'),
'useTLS' => true,
],
],
'redis' => [
'driver' => 'redis',
'connection' => 'default',
],
'log' => [
'driver' => 'log',
],
'null' => [
'driver' => 'null',
],
],
];
<?php
use Illuminate\Support\Str;
return [
/*
|--------------------------------------------------------------------------
| Default Cache Store
|--------------------------------------------------------------------------
|
| This option controls the default cache connection that gets used while
| using this caching library. This connection is used when another is
| not explicitly specified when executing a given caching function.
|
| Supported: "apc", "array", "database", "file",
| "memcached", "redis", "dynamodb"
|
*/
'default' => env('CACHE_DRIVER', 'file'),
/*
|--------------------------------------------------------------------------
| Cache Stores
|--------------------------------------------------------------------------
|
| Here you may define all of the cache "stores" for your application as
| well as their drivers. You may even define multiple stores for the
| same cache driver to group types of items stored in your caches.
|
*/
'stores' => [
'apc' => [
'driver' => 'apc',
],
'array' => [
'driver' => 'array',
],
'database' => [
'driver' => 'database',
'table' => 'cache',
'connection' => null,
],
'file' => [
'driver' => 'file',
'path' => storage_path('framework/cache/data'),
],
'memcached' => [
'driver' => 'memcached',
'persistent_id' => env('MEMCACHED_PERSISTENT_ID'),
'sasl' => [
env('MEMCACHED_USERNAME'),
env('MEMCACHED_PASSWORD'),
],
'options' => [
// Memcached::OPT_CONNECT_TIMEOUT => 2000,
],
'servers' => [
[
'host' => env('MEMCACHED_HOST', '127.0.0.1'),
'port' => env('MEMCACHED_PORT', 11211),
'weight' => 100,
],
],
],
'redis' => [
'driver' => 'redis',
'connection' => 'cache',
],
'dynamodb' => [
'driver' => 'dynamodb',
'key' => env('AWS_ACCESS_KEY_ID'),
'secret' => env('AWS_SECRET_ACCESS_KEY'),
'region' => env('AWS_DEFAULT_REGION', 'us-east-1'),
'table' => env('DYNAMODB_CACHE_TABLE', 'cache'),
'endpoint' => env('DYNAMODB_ENDPOINT'),
],
],
/*
|--------------------------------------------------------------------------
| Cache Key Prefix
|--------------------------------------------------------------------------
|
| When utilizing a RAM based store such as APC or Memcached, there might
| be other applications utilizing the same cache. So, we'll specify a
| value to get prefixed to all our keys so we can avoid collisions.
|
*/
'prefix' => env('CACHE_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_cache'),
];
<?php
use Illuminate\Support\Str;
return [
/*
|--------------------------------------------------------------------------
| Default Database Connection Name
|--------------------------------------------------------------------------
|
| Here you may specify which of the database connections below you wish
| to use as your default connection for all database work. Of course
| you may use many connections at once using the Database library.
|
*/
'default' => env('DB_CONNECTION', 'mysql'),
/*
|--------------------------------------------------------------------------
| Database Connections
|--------------------------------------------------------------------------
|
| Here are each of the database connections setup for your application.
| Of course, examples of configuring each database platform that is
| supported by Laravel is shown below to make development simple.
|
|
| All database work in Laravel is done through the PHP PDO facilities
| so make sure you have the driver for your particular database of
| choice installed on your machine before you begin development.
|
*/
'connections' => [
'sqlite' => [
'driver' => 'sqlite',
'url' => env('DATABASE_URL'),
'database' => env('DB_DATABASE', database_path('database.sqlite')),
'prefix' => '',
'foreign_key_constraints' => env('DB_FOREIGN_KEYS', true),
],
'mysql' => [
'driver' => 'mysql',
'url' => env('DATABASE_URL'),
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '3306'),
'database' => env('DB_DATABASE', 'project'),
'username' => env('DB_USERNAME', 'root'),
'password' => env('DB_PASSWORD', ''),
'unix_socket' => env('DB_SOCKET', ''),
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
'prefix_indexes' => true,
'strict' => true,
'engine' => null,
'options' => extension_loaded('pdo_mysql') ? array_filter([
PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
]) : [],
],
'pgsql' => [
'driver' => 'pgsql',
'url' => env('DATABASE_URL'),
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '5432'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'charset' => 'utf8',
'prefix' => '',
'prefix_indexes' => true,
'schema' => 'public',
'sslmode' => 'prefer',
],
'sqlsrv' => [
'driver' => 'sqlsrv',
'url' => env('DATABASE_URL'),
'host' => env('DB_HOST', 'localhost'),
'port' => env('DB_PORT', '1433'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'charset' => 'utf8',
'prefix' => '',
'prefix_indexes' => true,
],
],
/*
|--------------------------------------------------------------------------
| Migration Repository Table
|--------------------------------------------------------------------------
|
| This table keeps track of all the migrations that have already run for
| your application. Using this information, we can determine which of
| the migrations on disk haven't actually been run in the database.
|
*/
'migrations' => 'migrations',
/*
|--------------------------------------------------------------------------
| Redis Databases
|--------------------------------------------------------------------------
|
| Redis is an open source, fast, and advanced key-value store that also
| provides a richer body of commands than a typical key-value system
| such as APC or Memcached. Laravel makes it easy to dig right in.
|
*/
'redis' => [
'client' => env('REDIS_CLIENT', 'phpredis'),
'options' => [
'cluster' => env('REDIS_CLUSTER', 'redis'),
'prefix' => env('REDIS_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_database_'),
],
'default' => [
'url' => env('REDIS_URL'),
'host' => env('REDIS_HOST', '127.0.0.1'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', 6379),
'database' => env('REDIS_DB', 0),
],
'cache' => [
'url' => env('REDIS_URL'),
'host' => env('REDIS_HOST', '127.0.0.1'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', 6379),
'database' => env('REDIS_CACHE_DB', 1),
],
],
];
<?php
return [
/*
|--------------------------------------------------------------------------
| Default Filesystem Disk
|--------------------------------------------------------------------------
|
| Here you may specify the default filesystem disk that should be used
| by the framework. The "local" disk, as well as a variety of cloud
| based disks are available to your application. Just store away!
|
*/
'default' => env('FILESYSTEM_DRIVER', 'local'),
/*
|--------------------------------------------------------------------------
| Default Cloud Filesystem Disk
|--------------------------------------------------------------------------
|
| Many applications store files both locally and in the cloud. For this
| reason, you may specify a default "cloud" driver here. This driver
| will be bound as the Cloud disk implementation in the container.
|
*/
'cloud' => env('FILESYSTEM_CLOUD', 's3'),
/*
|--------------------------------------------------------------------------
| Filesystem Disks
|--------------------------------------------------------------------------
|
| Here you may configure as many filesystem "disks" as you wish, and you
| may even configure multiple disks of the same driver. Defaults have
| been setup for each driver as an example of the required options.
|
| Supported Drivers: "local", "ftp", "sftp", "s3"
|
*/
'disks' => [
'local' => [
'driver' => 'local',
'root' => storage_path('app'),
],
'public' => [
'driver' => 'local',
'root' => storage_path('app/public'),
'url' => env('APP_URL').'/storage',
'visibility' => 'public',
],
's3' => [
'driver' => 's3',
'key' => env('AWS_ACCESS_KEY_ID'),
'secret' => env('AWS_SECRET_ACCESS_KEY'),
'region' => env('AWS_DEFAULT_REGION'),
'bucket' => env('AWS_BUCKET'),
'url' => env('AWS_URL'),
],
],
];
<?php
return [
/*
|--------------------------------------------------------------------------
| Default Hash Driver
|--------------------------------------------------------------------------
|
| This option controls the default hash driver that will be used to hash
| passwords for your application. By default, the bcrypt algorithm is
| used; however, you remain free to modify this option if you wish.
|
| Supported: "bcrypt", "argon", "argon2id"
|
*/
'driver' => 'bcrypt',
/*
|--------------------------------------------------------------------------
| Bcrypt Options
|--------------------------------------------------------------------------
|
| Here you may specify the configuration options that should be used when
| passwords are hashed using the Bcrypt algorithm. This will allow you
| to control the amount of time it takes to hash the given password.
|
*/
'bcrypt' => [
'rounds' => env('BCRYPT_ROUNDS', 10),
],
/*
|--------------------------------------------------------------------------
| Argon Options
|--------------------------------------------------------------------------
|
| Here you may specify the configuration options that should be used when
| passwords are hashed using the Argon algorithm. These will allow you
| to control the amount of time it takes to hash the given password.
|
*/
'argon' => [
'memory' => 1024,
'threads' => 2,
'time' => 2,
],
];
<?php
use Monolog\Handler\NullHandler;
use Monolog\Handler\StreamHandler;
use Monolog\Handler\SyslogUdpHandler;
return [
/*
|--------------------------------------------------------------------------
| Default Log Channel
|--------------------------------------------------------------------------
|
| This option defines the default log channel that gets used when writing
| messages to the logs. The name specified in this option should match
| one of the channels defined in the "channels" configuration array.
|
*/
'default' => env('LOG_CHANNEL', 'stack'),
/*
|--------------------------------------------------------------------------
| Log Channels
|--------------------------------------------------------------------------
|
| Here you may configure the log channels 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 Drivers: "single", "daily", "slack", "syslog",
| "errorlog", "monolog",
| "custom", "stack"
|
*/
'channels' => [
'stack' => [
'driver' => 'stack',
'channels' => ['daily'],
'ignore_exceptions' => false,
],
'single' => [
'driver' => 'single',
'path' => storage_path('logs/laravel.log'),
'level' => 'debug',
],
'daily' => [
'driver' => 'daily',
'path' => storage_path('logs/laravel.log'),
'level' => 'debug',
'days' => 14,
],
'slack' => [
'driver' => 'slack',
'url' => env('LOG_SLACK_WEBHOOK_URL'),
'username' => 'Laravel Log',
'emoji' => ':boom:',
'level' => 'critical',
],
'papertrail' => [
'driver' => 'monolog',
'level' => 'debug',
'handler' => SyslogUdpHandler::class,
'handler_with' => [
'host' => env('PAPERTRAIL_URL'),
'port' => env('PAPERTRAIL_PORT'),
],
],
'stderr' => [
'driver' => 'monolog',
'handler' => StreamHandler::class,
'formatter' => env('LOG_STDERR_FORMATTER'),
'with' => [
'stream' => 'php://stderr',
],
],
'syslog' => [
'driver' => 'syslog',
'level' => 'debug',
],
'errorlog' => [
'driver' => 'errorlog',
'level' => 'debug',
],
'null' => [
'driver' => 'monolog',
'handler' => NullHandler::class,
],
],
];
<?php
return [
/*
|--------------------------------------------------------------------------
| Mail Driver
|--------------------------------------------------------------------------
|
| Laravel supports both SMTP and PHP's "mail" function as drivers for the
| sending of e-mail. You may specify which one you're using throughout
| your application here. By default, Laravel is setup for SMTP mail.
|
| Supported: "smtp", "sendmail", "mailgun", "ses",
| "postmark", "log", "array"
|
*/
'driver' => env('MAIL_DRIVER', 'smtp'),
/*
|--------------------------------------------------------------------------
| SMTP Host Address
|--------------------------------------------------------------------------
|
| Here you may provide the host address of the SMTP server used by your
| applications. A default option is provided that is compatible with
| the Mailgun mail service which will provide reliable deliveries.
|
*/
'host' => env('MAIL_HOST', 'smtp.mailgun.org'),
/*
|--------------------------------------------------------------------------
| SMTP Host Port
|--------------------------------------------------------------------------
|
| This is the SMTP port used by your application to deliver e-mails to
| users of the application. Like the host we have set this value to
| stay compatible with the Mailgun e-mail application by default.
|
*/
'port' => env('MAIL_PORT', 587),
/*
|--------------------------------------------------------------------------
| Global "From" Address
|--------------------------------------------------------------------------
|
| You may wish for all e-mails sent by your application to be sent from
| the same address. Here, you may specify a name and address that is
| used globally for all e-mails that are sent by your application.
|
*/
'from' => [
'address' => env('MAIL_FROM_ADDRESS', 'hello@example.com'),
'name' => env('MAIL_FROM_NAME', 'Example'),
],
/*
|--------------------------------------------------------------------------
| E-Mail Encryption Protocol
|--------------------------------------------------------------------------
|
| Here you may specify the encryption protocol that should be used when
| the application send e-mail messages. A sensible default using the
| transport layer security protocol should provide great security.
|
*/
'encryption' => env('MAIL_ENCRYPTION', 'tls'),
/*
|--------------------------------------------------------------------------
| SMTP Server Username
|--------------------------------------------------------------------------
|
| If your SMTP server requires a username for authentication, you should
| set it here. This will get used to authenticate with your server on
| connection. You may also set the "password" value below this one.
|
*/
'username' => env('MAIL_USERNAME'),
'password' => env('MAIL_PASSWORD'),
/*
|--------------------------------------------------------------------------
| Sendmail System Path
|--------------------------------------------------------------------------
|
| When using the "sendmail" driver to send e-mails, we will need to know
| the path to where Sendmail lives on this server. A default path has
| been provided here, which will work well on most of your systems.
|
*/
'sendmail' => '/usr/sbin/sendmail -bs',
/*
|--------------------------------------------------------------------------
| Markdown Mail Settings
|--------------------------------------------------------------------------
|
| If you are using Markdown based email rendering, you may configure your
| theme and component paths here, allowing you to customize the design
| of the emails. Or, you may simply stick with the Laravel defaults!
|
*/
'markdown' => [
'theme' => 'default',
'paths' => [
resource_path('views/vendor/mail'),
],
],
/*
|--------------------------------------------------------------------------
| Log Channel
|--------------------------------------------------------------------------
|
| If you are using the "log" driver, you may specify the logging channel
| if you prefer to keep mail messages separate from other log entries
| for simpler reading. Otherwise, the default channel will be used.
|
*/
'log_channel' => env('MAIL_LOG_CHANNEL'),
];
<?php
return [
/*
|--------------------------------------------------------------------------
| Default Queue Connection Name
|--------------------------------------------------------------------------
|
| Laravel's queue API supports an assortment of back-ends via a single
| API, giving you convenient access to each back-end using the same
| syntax for every one. Here you may define a default connection.
|
*/
'default' => env('QUEUE_CONNECTION', 'sync'),
/*
|--------------------------------------------------------------------------
| Queue Connections
|--------------------------------------------------------------------------
|
| Here you may configure the connection information for each server that
| is used by your application. A default configuration has been added
| for each back-end shipped with Laravel. You are free to add more.
|
| Drivers: "sync", "database", "beanstalkd", "sqs", "redis", "null"
|
*/
'connections' => [
'sync' => [
'driver' => 'sync',
],
'database' => [
'driver' => 'database',
'table' => 'jobs',
'queue' => 'default',
'retry_after' => 90,
],
'beanstalkd' => [
'driver' => 'beanstalkd',
'host' => 'localhost',
'queue' => 'default',
'retry_after' => 90,
'block_for' => 0,
],
'sqs' => [
'driver' => 'sqs',
'key' => env('AWS_ACCESS_KEY_ID'),
'secret' => env('AWS_SECRET_ACCESS_KEY'),
'prefix' => env('SQS_PREFIX', 'https://sqs.us-east-1.amazonaws.com/your-account-id'),
'queue' => env('SQS_QUEUE', 'your-queue-name'),
'region' => env('AWS_DEFAULT_REGION', 'us-east-1'),
],
'redis' => [
'driver' => 'redis',
'connection' => 'default',
'queue' => env('REDIS_QUEUE', 'default'),
'retry_after' => 90,
'block_for' => null,
],
],
/*
|--------------------------------------------------------------------------
| Failed Queue Jobs
|--------------------------------------------------------------------------
|
| These options configure the behavior of failed queue job logging so you
| can control which database and table are used to store the jobs that
| have failed. You may change them to any database / table you wish.
|
*/
'failed' => [
'driver' => env('QUEUE_FAILED_DRIVER', 'database'),
'database' => env('DB_CONNECTION', 'mysql'),
'table' => 'failed_jobs',
],
];
<?php
return [
/*
|--------------------------------------------------------------------------
| Third Party Services
|--------------------------------------------------------------------------
|
| This file is for storing the credentials for third party services such
| as Mailgun, Postmark, AWS and more. This file provides the de facto
| location for this type of information, allowing packages to have
| a conventional file to locate the various service credentials.
|
*/
'mailgun' => [
'domain' => env('MAILGUN_DOMAIN'),
'secret' => env('MAILGUN_SECRET'),
'endpoint' => env('MAILGUN_ENDPOINT', 'api.mailgun.net'),
],
'postmark' => [
'token' => env('POSTMARK_TOKEN'),
],
'ses' => [
'key' => env('AWS_ACCESS_KEY_ID'),
'secret' => env('AWS_SECRET_ACCESS_KEY'),
'region' => env('AWS_DEFAULT_REGION', 'us-east-1'),
],
];
<?php
use Illuminate\Support\Str;
return [
/*
|--------------------------------------------------------------------------
| Default Session Driver
|--------------------------------------------------------------------------
|
| This option controls the default session "driver" that will be used on
| requests. By default, we will use the lightweight native driver but
| you may specify any of the other wonderful drivers provided here.
|
| Supported: "file", "cookie", "database", "apc",
| "memcached", "redis", "dynamodb", "array"
|
*/
'driver' => env('SESSION_DRIVER', 'file'),
/*
|--------------------------------------------------------------------------
| Session Lifetime
|--------------------------------------------------------------------------
|
| Here you may specify the number of minutes that you wish the session
| to be allowed to remain idle before it expires. If you want them
| to immediately expire on the browser closing, set that option.
|
*/
'lifetime' => 120,
'expire_on_close' => false,
/*
|--------------------------------------------------------------------------
| Session Encryption
|--------------------------------------------------------------------------
|
| This option allows you to easily specify that all of your session data
| should be encrypted before it is stored. All encryption will be run
| automatically by Laravel and you can use the Session like normal.
|
*/
'encrypt' => false,
/*
|--------------------------------------------------------------------------
| Session File Location
|--------------------------------------------------------------------------
|
| When using the native session driver, we need a location where session
| files may be stored. A default has been set for you but a different
| location may be specified. This is only needed for file sessions.
|
*/
'files' => storage_path('framework/sessions'),
/*
|--------------------------------------------------------------------------
| Session Database Connection
|--------------------------------------------------------------------------
|
| When using the "database" or "redis" session drivers, you may specify a
| connection that should be used to manage these sessions. This should
| correspond to a connection in your database configuration options.
|
*/
'connection' => env('SESSION_CONNECTION', null),
/*
|--------------------------------------------------------------------------
| Session Database Table
|--------------------------------------------------------------------------
|
| When using the "database" session driver, you may specify the table we
| should use to manage the sessions. Of course, a sensible default is
| provided for you; however, you are free to change this as needed.
|
*/
'table' => 'sessions',
/*
|--------------------------------------------------------------------------
| Session Cache Store
|--------------------------------------------------------------------------
|
| When using the "apc", "memcached", or "dynamodb" session drivers you may
| list a cache store that should be used for these sessions. This value
| must match with one of the application's configured cache "stores".
|
*/
'store' => env('SESSION_STORE', null),
/*
|--------------------------------------------------------------------------
| Session Sweeping Lottery
|--------------------------------------------------------------------------
|
| Some session drivers must manually sweep their storage location to get
| rid of old sessions from storage. Here are the chances that it will
| happen on a given request. By default, the odds are 2 out of 100.
|
*/
'lottery' => [2, 100],
/*
|--------------------------------------------------------------------------
| Session Cookie Name
|--------------------------------------------------------------------------
|
| Here you may change the name of the cookie used to identify a session
| instance by ID. The name specified here will get used every time a
| new session cookie is created by the framework for every driver.
|
*/
'cookie' => env(
'SESSION_COOKIE',
Str::slug(env('APP_NAME', 'laravel'), '_').'_session'
),
/*
|--------------------------------------------------------------------------
| Session Cookie Path
|--------------------------------------------------------------------------
|
| The session cookie path determines the path for which the cookie will
| be regarded as available. Typically, this will be the root path of
| your application but you are free to change this when necessary.
|
*/
'path' => '/',
/*
|--------------------------------------------------------------------------
| Session Cookie Domain
|--------------------------------------------------------------------------
|
| Here you may change the domain of the cookie used to identify a session
| in your application. This will determine which domains the cookie is
| available to in your application. A sensible default has been set.
|
*/
'domain' => env('SESSION_DOMAIN', null),
/*
|--------------------------------------------------------------------------
| HTTPS Only Cookies
|--------------------------------------------------------------------------
|
| By setting this option to true, session cookies will only be sent back
| to the server if the browser has a HTTPS connection. This will keep
| the cookie from being sent to you if it can not be done securely.
|
*/
'secure' => env('SESSION_SECURE_COOKIE', false),
/*
|--------------------------------------------------------------------------
| HTTP Access Only
|--------------------------------------------------------------------------
|
| Setting this value to true will prevent JavaScript from accessing the
| value of the cookie and the cookie will only be accessible through
| the HTTP protocol. You are free to modify this option if needed.
|
*/
'http_only' => true,
/*
|--------------------------------------------------------------------------
| Same-Site Cookies
|--------------------------------------------------------------------------
|
| This option determines how your cookies behave when cross-site requests
| take place, and can be used to mitigate CSRF attacks. By default, we
| do not enable this as other CSRF protection services are in place.
|
| Supported: "lax", "strict"
|
*/
'same_site' => null,
];
<?php
return [
/*
|--------------------------------------------------------------------------
| View Storage Paths
|--------------------------------------------------------------------------
|
| Most templating systems load templates from disk. Here you may specify
| an array of paths that should be checked for your views. Of course
| the usual Laravel view path has already been registered for you.
|
*/
'paths' => [
resource_path('views'),
],
/*
|--------------------------------------------------------------------------
| Compiled View Path
|--------------------------------------------------------------------------
|
| This option determines where all the compiled Blade templates will be
| stored for your application. Typically, this is within the storage
| directory. However, as usual, you are free to change this value.
|
*/
'compiled' => env(
'VIEW_COMPILED_PATH',
realpath(storage_path('framework/views'))
),
];
*.sqlite
*.sqlite-journal
<?php
/** @var \Illuminate\Database\Eloquent\Factory $factory */
use App\User;
use Faker\Generator as Faker;
use Illuminate\Support\Str;
/*
|--------------------------------------------------------------------------
| Model Factories
|--------------------------------------------------------------------------
|
| This directory should contain each of the model factory definitions for
| your application. Factories provide a convenient way to generate new
| model instances for testing / seeding your application's database.
|
*/
$factory->define(User::class, function (Faker $faker) {
return [
'name' => $faker->name,
'email' => $faker->unique()->safeEmail,
'email_verified_at' => now(),
'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password
'remember_token' => Str::random(10),
];
});
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateProvincesTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('provinces', function (Blueprint $table) {
$table->integer('provinces_id');
$table->string('provinces_name');
$table->primary('provinces_id');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('provinces');
}
}
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateAttractionsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('attractions', function (Blueprint $table) {
$table->integer('provinces_id');
$table->increments('attractions_id');
$table->string('attractions_name');
$table->double('Latitude');
$table->double('longitude');
$table->longText('description');
$table->string('image_url');
$table->foreign('provinces_id')->references('provinces_id')->on('provinces');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('attractions');
}
}
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateUsersTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->string('username');
$table->string('password');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('users');
}
}
<?php
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
/**
* Seed the application's database.
*
* @return void
*/
public function run()
{
// $this->call(UsersTableSeeder::class);
}
}
{
"private": true,
"scripts": {
"dev": "npm run development",
"development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
"watch": "npm run development -- --watch",
"watch-poll": "npm run watch -- --watch-poll",
"hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js",
"prod": "npm run production",
"production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js"
},
"devDependencies": {
"axios": "^0.19",
"cross-env": "^5.1",
"laravel-mix": "^4.0.7",
"lodash": "^4.17.13",
"resolve-url-loader": "^2.3.1",
"sass": "^1.15.2",
"sass-loader": "^7.1.0"
}
}
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="./vendor/phpunit/phpunit/phpunit.xsd"
backupGlobals="false"
backupStaticAttributes="false"
bootstrap="vendor/autoload.php"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false">
<testsuites>
<testsuite name="Unit">
<directory suffix="Test.php">./tests/Unit</directory>
</testsuite>
<testsuite name="Feature">
<directory suffix="Test.php">./tests/Feature</directory>
</testsuite>
</testsuites>
<filter>
<whitelist processUncoveredFilesFromWhitelist="true">
<directory suffix=".php">./app</directory>
</whitelist>
</filter>
<php>
<server name="APP_ENV" value="testing"/>
<server name="BCRYPT_ROUNDS" value="4"/>
<server name="CACHE_DRIVER" value="array"/>
<server name="MAIL_DRIVER" value="array"/>
<server name="QUEUE_CONNECTION" value="sync"/>
<server name="SESSION_DRIVER" value="array"/>
</php>
</phpunit>
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews -Indexes
</IfModule>
RewriteEngine On
# Handle Authorization Header
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
# Redirect Trailing Slashes If Not A Folder...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} (.+)/$
RewriteRule ^ %1 [L,R=301]
# Handle Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
</IfModule>
<?php
/**
* Laravel - A PHP Framework For Web Artisans
*
* @package Laravel
* @author Taylor Otwell <taylor@laravel.com>
*/
define('LARAVEL_START', microtime(true));
/*
|--------------------------------------------------------------------------
| Register The Auto Loader
|--------------------------------------------------------------------------
|
| Composer provides a convenient, automatically generated class loader for
| our application. We just need to utilize it! We'll simply require it
| into the script here so that we don't have to worry about manual
| loading any of our classes later on. It feels great to relax.
|
*/
require __DIR__.'/../vendor/autoload.php';
/*
|--------------------------------------------------------------------------
| Turn On The Lights
|--------------------------------------------------------------------------
|
| We need to illuminate PHP development, so let us turn on the lights.
| This bootstraps the framework and gets it ready for use, then it
| will load up this application so that we can run it and send
| the responses back to the browser and delight our users.
|
*/
$app = require_once __DIR__.'/../bootstrap/app.php';
/*
|--------------------------------------------------------------------------
| Run The Application
|--------------------------------------------------------------------------
|
| Once we have the application, we can handle the incoming request
| through the kernel, and send the associated response back to
| the client's browser allowing them to enjoy the creative
| and wonderful application we have prepared for them.
|
*/
$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);
$response = $kernel->handle(
$request = Illuminate\Http\Request::capture()
);
$response->send();
$kernel->terminate($request, $response);
User-agent: *
Disallow:
<!--
Rewrites requires Microsoft URL Rewrite Module for IIS
Download: https://www.microsoft.com/en-us/download/details.aspx?id=47337
Debug Help: https://docs.microsoft.com/en-us/iis/extensions/url-rewrite-module/using-failed-request-tracing-to-trace-rewrite-rules
-->
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="Imported Rule 1" stopProcessing="true">
<match url="^(.*)/$" ignoreCase="false" />
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" ignoreCase="false" negate="true" />
</conditions>
<action type="Redirect" redirectType="Permanent" url="/{R:1}" />
</rule>
<rule name="Imported Rule 2" stopProcessing="true">
<match url="^" ignoreCase="false" />
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" ignoreCase="false" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsFile" ignoreCase="false" negate="true" />
</conditions>
<action type="Rewrite" url="index.php" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
require('./bootstrap');
window._ = require('lodash');
/**
* We'll load the axios HTTP library which allows us to easily issue requests
* to our Laravel back-end. This library automatically handles sending the
* CSRF token as a header based on the value of the "XSRF" token cookie.
*/
window.axios = require('axios');
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
/**
* Echo exposes an expressive API for subscribing to channels and listening
* for events that are broadcast by Laravel. Echo and event broadcasting
* allows your team to easily build robust real-time web applications.
*/
// import Echo from 'laravel-echo';
// window.Pusher = require('pusher-js');
// window.Echo = new Echo({
// broadcaster: 'pusher',
// key: process.env.MIX_PUSHER_APP_KEY,
// cluster: process.env.MIX_PUSHER_APP_CLUSTER,
// encrypted: true
// });
<?php
return [
/*
|--------------------------------------------------------------------------
| Authentication Language Lines
|--------------------------------------------------------------------------
|
| The following language lines are used during authentication for various
| messages that we need to display to the user. You are free to modify
| these language lines according to your application's requirements.
|
*/
'failed' => 'These credentials do not match our records.',
'throttle' => 'Too many login attempts. Please try again in :seconds seconds.',
];
<?php
return [
/*
|--------------------------------------------------------------------------
| Pagination Language Lines
|--------------------------------------------------------------------------
|
| The following language lines are used by the paginator library to build
| the simple pagination links. You are free to change them to anything
| you want to customize your views to better match your application.
|
*/
'previous' => '&laquo; Previous',
'next' => 'Next &raquo;',
];
<?php
return [
/*
|--------------------------------------------------------------------------
| Password Reset Language Lines
|--------------------------------------------------------------------------
|
| The following language lines are the default lines which match reasons
| that are given by the password broker for a password update attempt
| has failed, such as for an invalid token or invalid new password.
|
*/
'reset' => 'Your password has been reset!',
'sent' => 'We have e-mailed your password reset link!',
'token' => 'This password reset token is invalid.',
'user' => "We can't find a user with that e-mail address.",
'throttled' => 'Please wait before retrying.',
];
<?php
return [
/*
|--------------------------------------------------------------------------
| Validation Language Lines
|--------------------------------------------------------------------------
|
| The following language lines contain the default error messages used by
| the validator class. Some of these rules have multiple versions such
| as the size rules. Feel free to tweak each of these messages here.
|
*/
'accepted' => 'The :attribute must be accepted.',
'active_url' => 'The :attribute is not a valid URL.',
'after' => 'The :attribute must be a date after :date.',
'after_or_equal' => 'The :attribute must be a date after or equal to :date.',
'alpha' => 'The :attribute may only contain letters.',
'alpha_dash' => 'The :attribute may only contain letters, numbers, dashes and underscores.',
'alpha_num' => 'The :attribute may only contain letters and numbers.',
'array' => 'The :attribute must be an array.',
'before' => 'The :attribute must be a date before :date.',
'before_or_equal' => 'The :attribute must be a date before or equal to :date.',
'between' => [
'numeric' => 'The :attribute must be between :min and :max.',
'file' => 'The :attribute must be between :min and :max kilobytes.',
'string' => 'The :attribute must be between :min and :max characters.',
'array' => 'The :attribute must have between :min and :max items.',
],
'boolean' => 'The :attribute field must be true or false.',
'confirmed' => 'The :attribute confirmation does not match.',
'date' => 'The :attribute is not a valid date.',
'date_equals' => 'The :attribute must be a date equal to :date.',
'date_format' => 'The :attribute does not match the format :format.',
'different' => 'The :attribute and :other must be different.',
'digits' => 'The :attribute must be :digits digits.',
'digits_between' => 'The :attribute must be between :min and :max digits.',
'dimensions' => 'The :attribute has invalid image dimensions.',
'distinct' => 'The :attribute field has a duplicate value.',
'email' => 'The :attribute must be a valid email address.',
'ends_with' => 'The :attribute must end with one of the following: :values',
'exists' => 'The selected :attribute is invalid.',
'file' => 'The :attribute must be a file.',
'filled' => 'The :attribute field must have a value.',
'gt' => [
'numeric' => 'The :attribute must be greater than :value.',
'file' => 'The :attribute must be greater than :value kilobytes.',
'string' => 'The :attribute must be greater than :value characters.',
'array' => 'The :attribute must have more than :value items.',
],
'gte' => [
'numeric' => 'The :attribute must be greater than or equal :value.',
'file' => 'The :attribute must be greater than or equal :value kilobytes.',
'string' => 'The :attribute must be greater than or equal :value characters.',
'array' => 'The :attribute must have :value items or more.',
],
'image' => 'The :attribute must be an image.',
'in' => 'The selected :attribute is invalid.',
'in_array' => 'The :attribute field does not exist in :other.',
'integer' => 'The :attribute must be an integer.',
'ip' => 'The :attribute must be a valid IP address.',
'ipv4' => 'The :attribute must be a valid IPv4 address.',
'ipv6' => 'The :attribute must be a valid IPv6 address.',
'json' => 'The :attribute must be a valid JSON string.',
'lt' => [
'numeric' => 'The :attribute must be less than :value.',
'file' => 'The :attribute must be less than :value kilobytes.',
'string' => 'The :attribute must be less than :value characters.',
'array' => 'The :attribute must have less than :value items.',
],
'lte' => [
'numeric' => 'The :attribute must be less than or equal :value.',
'file' => 'The :attribute must be less than or equal :value kilobytes.',
'string' => 'The :attribute must be less than or equal :value characters.',
'array' => 'The :attribute must not have more than :value items.',
],
'max' => [
'numeric' => 'The :attribute may not be greater than :max.',
'file' => 'The :attribute may not be greater than :max kilobytes.',
'string' => 'The :attribute may not be greater than :max characters.',
'array' => 'The :attribute may not have more than :max items.',
],
'mimes' => 'The :attribute must be a file of type: :values.',
'mimetypes' => 'The :attribute must be a file of type: :values.',
'min' => [
'numeric' => 'The :attribute must be at least :min.',
'file' => 'The :attribute must be at least :min kilobytes.',
'string' => 'The :attribute must be at least :min characters.',
'array' => 'The :attribute must have at least :min items.',
],
'not_in' => 'The selected :attribute is invalid.',
'not_regex' => 'The :attribute format is invalid.',
'numeric' => 'The :attribute must be a number.',
'password' => 'The password is incorrect.',
'present' => 'The :attribute field must be present.',
'regex' => 'The :attribute format is invalid.',
'required' => 'The :attribute field is required.',
'required_if' => 'The :attribute field is required when :other is :value.',
'required_unless' => 'The :attribute field is required unless :other is in :values.',
'required_with' => 'The :attribute field is required when :values is present.',
'required_with_all' => 'The :attribute field is required when :values are present.',
'required_without' => 'The :attribute field is required when :values is not present.',
'required_without_all' => 'The :attribute field is required when none of :values are present.',
'same' => 'The :attribute and :other must match.',
'size' => [
'numeric' => 'The :attribute must be :size.',
'file' => 'The :attribute must be :size kilobytes.',
'string' => 'The :attribute must be :size characters.',
'array' => 'The :attribute must contain :size items.',
],
'starts_with' => 'The :attribute must start with one of the following: :values',
'string' => 'The :attribute must be a string.',
'timezone' => 'The :attribute must be a valid zone.',
'unique' => 'The :attribute has already been taken.',
'uploaded' => 'The :attribute failed to upload.',
'url' => 'The :attribute format is invalid.',
'uuid' => 'The :attribute must be a valid UUID.',
/*
|--------------------------------------------------------------------------
| Custom Validation Language Lines
|--------------------------------------------------------------------------
|
| Here you may specify custom validation messages for attributes using the
| convention "attribute.rule" to name the lines. This makes it quick to
| specify a specific custom language line for a given attribute rule.
|
*/
'custom' => [
'attribute-name' => [
'rule-name' => 'custom-message',
],
],
/*
|--------------------------------------------------------------------------
| Custom Validation Attributes
|--------------------------------------------------------------------------
|
| The following language lines are used to swap our attribute placeholder
| with something more reader friendly such as "E-Mail Address" instead
| of "email". This simply helps us make our message more expressive.
|
*/
'attributes' => [],
];
<!DOCTYPE html>
<html>
<head>
<title></title>
<!--bootstrap-->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
<!--bootstrap-->
</head>
<body>
<?php
use App\Province;
$provinces = Province::all();
?>
<nav class="navbar navbar-dark bg-dark">
<a href="/" class="navbar-brand">Travel</a>
<form class="form-inline">
<div class="dropdown">
<button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Admin
</button>
<div class="dropdown-menu" aria-labelledby="dropdownMenuButton">
<a href="/admin" class="dropdown-item">หน้าแรก</a>
<a class="dropdown-item" href="/admin/insert">เพิ่มข้อมูล</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="/admin/logout">Log out</a>
</div>
</div>
</form>
</nav>
@if(Session::has('success'))
<div class="alert alert-success alert-dismissible fade show" role="alert">
ลบข้อมูลแล้ว
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
@endif
<div class="card">
<table style="width:100%" class="table">
<tr>
<th scope="col">รหัสจังหสัด</th>
<th scope="col">ชื่อจังหวัด</th>
<th></th>
</tr>
@foreach ($provinces as $province)
<tr>
<td>{{$province["provinces_id"]}}</td>
<td>{{$province["provinces_name"]}}</td>
<form class="delete" action="{{ route('adminController.deleteProvince') }}" method="post">
{{csrf_field()}}
<input type="hidden" name="province_id" value={{$province["provinces_id"]}}>
<td><input type="submit" class="btn btn-danger" value="ลบ"></td>
</form>
<form action="{{ route('adminController.search') }}" method="get">
<input type="hidden" name="province_id" value={{$province["provinces_id"]}}>
<td><input type="submit" class="btn btn-primary" value="ค้นหา"></td>
</form>
</tr>
@endforeach
</table>
</div>
<script>
$(document).ready(function() {
$('.delete').on('submit', function() {
if (confirm("ยืนยันการลบ ?")) {
return true;
} else {
return false;
}
});
});
</script>
</body>
</html>
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<title></title>
<!--bootstrap-->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
<!--bootstrap-->
</head>
<body>
<?php
use App\Province;
$provinces = Province::all();
?>
<nav class="navbar navbar-dark bg-dark">
<a href="/" class="navbar-brand">Travel</a>
<form class="form-inline">
<div class="dropdown">
<button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Admin
</button>
<div class="dropdown-menu" aria-labelledby="dropdownMenuButton">
<a href="/admin" class="dropdown-item">หน้าแรก</a>
<a class="dropdown-item" href="/admin/insert">เพิ่มข้อมูล</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="/admin/logout">Log out</a>
</div>
</div>
</form>
</nav>
@if(Session::has('success'))
<div class="alert alert-success alert-dismissible fade show" role="alert">
success
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
@endif
<div class="card">
@if($attractions!=null)
<table style="width:100%" class="table">
<tr>
<th scope="col">รหัสสถานที่ท่องเที่ยว</th>
<th scope="col">ชื่อสถานที่ท่องเที่ยว</th>
<th></th>
</tr>
@foreach ($attractions as $attraction)
<tr>
<td>{{$attraction["attractions_id"]}}</td>
<td>{{$attraction["attractions_name"]}}</td>
<form action="{{route('adminController.deleteAttraction')}}" method="post">
{{csrf_field()}}
<input type="hidden" name="attraction_id" value={{$attraction["attractions_id"]}}>
<td><input type="submit" class="btn btn-danger" value="ลบ"></td>
</form>
<form action="{{route('adminController.edit')}}" method="get">
<input type="hidden" name="attraction_id" value={{$attraction["attractions_id"]}}>
<td><input type="submit" class="btn btn-warning" value="แก้ไข"></td>
</form>
</tr>
@endforeach
</table>
@else
<p>ไม่มีข้อมูล</p>
@endif
</div>
</body>
</html>
\ No newline at end of file
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<!--bootstrap-->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
<!--bootstrap-->
<style>
.card{
margin:25px 25px 25px 30px;
}
a,form{
margin:5px;
}
img{
width:100%;
height:300px;
}
body {
background-color: #999999;
}
</style>
<title></title>
</head>
<body>
<nav class="navbar navbar-dark bg-dark">
<a href="/" class="navbar-brand">Travel</a>
<form class="form-inline">
<a class="btn btn-primary" href="/selectview">สถานที่ที่เลือก</a>
</form>
</nav>
@if($places!=null)
<div class="row">
@foreach($places as $place)
<div class="card text-white bg-secondary mb-3" style="width: 18rem;">
<?php
$pic= explode("|",$place['image_url']);
?>
<img class="card-img-top" src="../upload/{{$pic[0]}}" alt="Card image cap">
<div class="card-body">
<h5 class="card-title">{{$place["attractions_name"]}}</h5>
<div class="row">
<a href="/detail_/{{$place["attractions_id"]}}" class="btn btn-primary">รายละเอียด</a>
<form action="{{ route('addplace.add') }}" method="get">
<!--{{csrf_field()}}-->
<input type= "hidden" name= "id" value="{{$place["attractions_id"]}}">
<input onclick="success()" type= "submit" class="btn btn-primary" value= "เลือก">
</form>
</div>
</div>
</div>
@endforeach
</div>
<script type="text/javascript">
function success(){
alert("success");
}
</script>
@else
<p>ไม่มีข้อมูล</p>
@endif
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<title></title>
<script type="text/javascript">
function setForm(value) {
if (value == 'form1') {
document.getElementById('form1').style = 'display:block;';
document.getElementById('form2').style = 'display:none;';
} else {
document.getElementById('form2').style = 'display:block;';
document.getElementById('form1').style = 'display:none;';
}
}
/*function setImage(value) {
if (value == 'urlform') {
document.getElementById('urlform').style = 'display:block;';
document.getElementById('browsform').style = 'display:none;';
} else {
document.getElementById('browsform').style = 'display:block;';
document.getElementById('urlform').style = 'display:none;';
}
}*/
</script>
<!--bootstrap-->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
<!--bootstrap-->
<script>
/*$('#myInput').on('change', function() {
//get the file name
var fileName = document.getElementById("myInput").files[0].name;
//replace the "Choose a file" label
$(this).next('.custom-file-label').html(fileName);
})*/
</script>
</head>
<body>
<nav class="navbar navbar-dark bg-dark">
<a href="/" class="navbar-brand">Travel</a>
<form class="form-inline">
<div class="dropdown">
<button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Admin
</button>
<div class="dropdown-menu" aria-labelledby="dropdownMenuButton">
<a href="/admin" class="dropdown-item">หน้าแรก</a>
<a class="dropdown-item" href="/admin/insert">เพิ่มข้อมูล</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="/admin/logout">Log out</a>
</div>
</div>
</form>
</nav>
<?php
use App\Province;
$provinces = Province::all();
?>
<div class="card">
<div class="card-header">
<label>เพิ่มข้อมูล</label>
<select class="custom-select" onchange="setForm(this.value)" style="width: 25rem;">
<option value="form1">สถานที่ท่องเที่ยว</option>
<option value="form2">จังหวัด</option>
</select>
</div>
<div class="card-body">
@if(Session::has('inserted'))
<div class="alert alert-success alert-dismissible fade show" role="alert">
success
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
@endif
@if (count($errors) > 0)
<div class="alert alert-danger">
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
<!--form1-->
<div id="form1">
<form action="{{route('adminController.insertAttraction')}}" method="post" enctype="multipart/form-data">
{{csrf_field()}}
<div class="form-col">
<div class="col-md-4 mb-3">
<label>จังหวัด</label>
<select name="province_id" class="form-control">
@foreach ($provinces as $province)
<option value={{$province["provinces_id"]}}>{{$province["provinces_name"]}}</option>
@endforeach
</select>
</div>
<div class="col-md-4 mb-3">
<label>ชื่อสถานที่ท่องเที่ยว</label>
<input type="text" class="form-control" name="attractions_name" required>
</div>
<div class="col-md-4 mb-3">
<label>Latitude</label>
<input type="number" step="any" class="form-control" name="lat" required>
</div>
<div class="col-md-4 mb-3">
<label>Longtitud</label>
<input type="number" step="any" class="form-control" name="lng" required>
</div>
<div class="col-md-4 mb-3">
<label>รายละเอียด</label>
<textarea class="form-control " name="description" required></textarea>
</div>
<div class="col-md-4 mb-3">
<label>รูปภาพ</label>
<input type="file" name="image[]" multiple="multiple" required multiple>
</div>
<input type="submit" name="submit" class="btn btn-info btn-md" value="submit">
</div>
</form>
</div>
<!--form2-->
<div id="form2" style="display: none">
<form action="{{route('adminController.insertProvince')}}" method="post">
{{csrf_field()}}
<div class="col-md-4 mb-3">
<label>รหัสจังหวัด</label>
<input type="number" class="form-control" name="province_id" required>
</div>
<div class="col-md-4 mb-3">
<label>ชื่อจังหวัด</label>
<input type="text" class="form-control" name="province_name" required>
</div>
<input type="submit" name="submit" class="btn btn-info btn-md" value="submit">
</form>
</div>
</div>
</div>
</body>
</html>
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title></title>
<!--bootstrap-->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
<!--bootstrap-->
</head>
<style>
.card {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
body {
background-color: #999999;
}
</style>
<body>
<div class="card text-white bg-dark mb-3" style="width: 25rem;">
<center>
<div class="card-header">
Login
</div>
</center>
<div class="card-body">
@if(Session::has('loginFail'))
<div class="alert alert-danger alert-dismissible fade show" role="alert">
username หรือ password ไม่ถูกต้อง
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
@else
@endif
<form action="{{route('loginController.login')}}" method="post">
{{csrf_field()}}
<div class="form-col">
<div class="form-group">
<label for="username" class="card-text">Username:</label><br>
<input type="text" name="username" id="username" class="form-control" required>
</div>
<div class="form-group">
<label for="password" class="card-text">Password:</label><br>
<input type="password" name="password" id="password" class="form-control">
</div>
<input type="submit" name="submit" class="btn btn-info btn-md" value="submit">
</div>
</form>
</div>
</div>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
<meta charset="utf-8">
<!--bootstrap-->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
<!--bootstrap-->
<style>
html, body {
height: 100%;
margin: 0;
padding: 0;
background-color: #999999;
}
a{
margin:5px;
}
#map {
height: 100%;
float: left;
width: 70%;
}
</style>
</head>
<body>
<nav class="navbar navbar-dark bg-dark">
<a href="/" class="navbar-brand">Travel</a>
<form class="form-inline">
<a class="btn btn-danger" href="/delAllSelect">ลบที่เลือกทั้งหมด</a>
</form>
</nav>
<div id="map"></div>
<div class="card">
<div class="card-header">
ลำดับการเดินทาง
</div>
<ul class="list-group list-group-flush">
<?php
$p=array('B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K');
$i=0;
?>
<li class="list-group-item">A ตำแหน่งปัจจุบัน</li>
@foreach($dataresults as $data)
<li class="list-group-item">{{$p[$i]}} {{$data["attractions_name"]}}</li>
<?php $i++; ?>
@endforeach
</ul>
</div>
<script>
function initMap() {
var directionsService = new google.maps.DirectionsService();
var directionsRenderer = new google.maps.DirectionsRenderer();
var map = new google.maps.Map(document.getElementById('map'), {
center: {lat: 13.684164, lng: 100.709522},
zoom: 6
});
directionsRenderer.setMap(map);
navigator.geolocation.getCurrentPosition(function(position) {
var pos = {lat: position.coords.latitude,lng: position.coords.longitude};
map.setCenter(pos);
map.setZoom(15);
DisplayRoute(directionsService, directionsRenderer,pos);
});
}
function DisplayRoute(directionsService, directionsRenderer,pos) {
var waypts = [];
<?php
for ($i=0; $i <= count($dataresults)-2; $i++) {
echo "waypts.push({";
echo "location: {lat:".$dataresults[$i]["Latitude"].",lng:".$dataresults[$i]["longitude"]."},";
echo "stopover: true";
echo "});";
}
?>
var posdes = {lat: <?php echo $dataresults[count($dataresults)-1]["Latitude"]; ?>,lng: <?php echo $dataresults[count($dataresults)-1]["longitude"]; ?>};
directionsService.route(
{
origin: pos,
destination: posdes,
waypoints: waypts,
travelMode: 'DRIVING'
},
function(response, status) {
if (status === 'OK') {
directionsRenderer.setDirections(response);
} else {
window.alert('Directions request failed due to ' + status);
}
});
}
</script>
<script async defer
src="https://maps.googleapis.com/maps/api/js?key=AIzaSyAQLj-_PEe0qXFXtqhs_EdE-ZmC5zoReMs&callback=initMap">
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title></title>
<!--bootstrap-->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
<!--bootstrap-->
<style media="screen">
.container{
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
a{
position: fixed;
left: 94%;
margin:5px;
}
body {
background-color: #999999;
}
</style>
</head>
<body>
<?php
use App\Province;
$provinces = Province::all();
?>
<center>
<div class="container">
<form action="{{ route('getplace.getdata') }}" method="get">
<div class="form-group">
<select name="province" class="form-control">
@foreach ($provinces as $province)
<option value={{$province["provinces_id"]}} >{{$province["provinces_name"]}}</option>
@endforeach
</select>
</div>
<input type= "submit" class="btn btn-primary" value= "ค้นหา">
</form>
</div>
</center>
<a class="btn btn-secondary" href="/adminlogin">admin</a>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
<meta charset="utf-8">
<!--bootstrap-->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
<!--bootstrap-->
<style>
body {
background-color: #999999;
}
a,form{
margin:5px;
}
#div1 {
margin: 10px;
padding: 10px;
}
.row{
margin: 10px;
padding: 10px;
}
.card{
margin:25px 25px 25px 30px;
}
img{
width:100%;
height:300px;
}
</style>
</head>
<body>
@if(Session::has('attraction_id'))
<nav class="navbar navbar-dark bg-dark">
<a href="/" class="navbar-brand">Travel</a>
<div class="form-inline">
<a class="btn btn-danger" href="/delAllSelect">ลบที่เลือกทั้งหมด</a>
<form action="{{ route('ResultController.getresult') }}" method="post">
{{csrf_field()}}
<input type= "hidden" name= "lat" id= "lat" >
<input type= "hidden" name= "lng" id= "lng" >
<input type= "submit" class="btn btn-primary" value= "ค้นหาเส้นทาง">
</form>
</div>
</nav>
<div class="row">
@foreach($selecteds as $selected)
<div class="card text-white bg-secondary mb-3" style="width: 18rem;">
<?php
$pic= explode("|",$selected['image_url']);
?>
<img class="card-img-top" src="../upload/{{$pic[0]}}" alt="Card image cap">
<div class="card-body">
<h5 class="card-title">{{$selected["attractions_name"]}}</h5>
</div>
<div class="card-body">
<form action="{{ route('addplace.del') }}" method="get">
<input type= "hidden" name= "id" value="{{$selected["attractions_id"]}}">
<input type= "submit" class="btn btn-danger" value= "ลบ">
</form>
</div>
</div>
@endforeach
</div>
<script>
var lat = document.getElementById("lat");
var lng = document.getElementById("lng");
function getCurrent() {
navigator.geolocation.getCurrentPosition(function(position) {
lat.value = position.coords.latitude;
lng.value = position.coords.longitude;
});
}
</script>
<script async defer
src="https://maps.googleapis.com/maps/api/js?key=AIzaSyAQLj-_PEe0qXFXtqhs_EdE-ZmC5zoReMs&callback=getCurrent">
</script>
@else
<nav class="navbar navbar-dark bg-dark">
<a href="/" class="navbar-brand">Travel</a>
<div class="form-inline">
<a class="btn btn-danger" href="/delAllSelect">ลบที่เลือกทั้งหมด</a>
</div>
</nav>
<p>กรุณาเลือกสถานที่</p>
@endif
</body>
</html>
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<img src="../upload/use_case.png">
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<title></title>
<!--bootstrap-->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
<!--bootstrap-->
</head>
<body>
<nav class="navbar navbar-dark bg-dark">
<a href="/" class="navbar-brand">Travel</a>
<form class="form-inline">
<div class="dropdown">
<button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Admin
</button>
<div class="dropdown-menu" aria-labelledby="dropdownMenuButton">
<a href="/admin" class="dropdown-item">หน้าแรก</a>
<a class="dropdown-item" href="/admin/insert">เพิ่มข้อมูล</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="/admin/logout">Log out</a>
</div>
</div>
</form>
</nav>
@if(Session::has('success'))
<div class="alert alert-success alert-dismissible fade show" role="alert">
success
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
@endif
@if (count($errors) > 0)
<div class="alert alert-danger">
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
@foreach ($attractions as $attraction)
<div class="card">
<div class="card-body">
<form action="{{route('adminController.update')}}" method="post" enctype="multipart/form-data">
{{csrf_field()}}
<div class="form-col">
<input type="hidden" name="attractions_id" value="{{$attraction['attractions_id']}}">
<div class="col-md-4 mb-3">
<label>ชื่อสถานที่ท่องเที่ยว</label>
<input type="text" class="form-control" name="attractions_name" placeholder="{{$attraction['attractions_name']}}" value="{{$attraction['attractions_name']}}" required>
</div>
<div class="col-md-4 mb-3">
<label>Latitude</label>
<input type="number" step="any" class="form-control" name="lat" placeholder="{{$attraction['Latitude']}}" value="{{$attraction['Latitude']}}" required>
</div>
<div class="col-md-4 mb-3">
<label>Longtitud</label>
<input type="number" step="any" class="form-control" name="lng" placeholder="{{$attraction['longitude']}}" value="{{$attraction['longitude']}}" required>
</div>
<div class="col-md-4 mb-3">
<label>รายละเอียด</label>
<textarea class="form-control " name="description" required>{{$attraction['description']}}</textarea>
</div>
<div class="col-md-4 mb-3">
<label>รูปภาพ</label>
<input type="file" name="image[]" multiple="multiple" required multiple>
</div>
<input type="submit" name="submit" class="btn btn-info btn-md" value="submit">
</div>
</form>
</div>
</div>
@endforeach
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<!--bootstrap-->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
<!--bootstrap-->
<style>
/* Set the size of the div element that contains the map */
#map {
height: 500px; /* The height is 400 pixels */
width: 600px; /* The width is the width of the web page */
margin: 25px 25px 25px 100px;
}
.card{
width: 450px;
margin: 25px;
padding: 5px;
}
#cardlocation{
height: auto;
width: auto;
margin: 25px;
padding: 5px;
}
h3 {
margin: 10px 10px 1px 100px;
}
body {
background-color: #999999;
}
img{
width:100%;
height:300px;
}
</style>
</head>
<body>
@foreach($details as $detail)
<nav class="navbar navbar-dark bg-dark">
<a href="/" class="navbar-brand">Travel</a>
<form action="{{ route('addplace.add') }}" method="get">
<!--{{csrf_field()}}-->
<input type= "hidden" name= "id" value="{{$detail["attractions_id"]}}">
<input onclick="success()" type= "submit" class="btn btn-primary" value= "เลือก">
</form>
</nav>
<?php
$pics= explode("|",$detail['image_url']);
?>
<center>
<div class="card">
<div class="card-body">
<div id="carouselExampleControls" class="carousel slide" data-ride="carousel">
<div class="carousel-inner">
<?php
for ($i=0; $i < count($pics) ; $i++) {
if ($i==0) {
echo "<div class='carousel-item active'>";
echo "<img class='d-block w-100' src='../upload/$pics[$i]' >";
echo "</div>";
}else {
echo "<div class='carousel-item'>";
echo "<img class='d-block w-100' src='../upload/$pics[$i]' >";
echo "</div>";
}
} ?>
</div>
<a class="carousel-control-prev" href="#carouselExampleControls" role="button" data-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
<span class="sr-only">Previous</span>
</a>
<a class="carousel-control-next" href="#carouselExampleControls" role="button" data-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
<span class="sr-only">Next</span>
</a>
</div>
</div>
</div>
</center>
<h3 class="text-left">{{$detail['attractions_name']}}</h3>
<div class="row">
<div id="map"></div>
<script>
function initMap() {
var uluru = {lat: {{$detail["Latitude"]}}, lng:{{$detail["longitude"]}} };
var map = new google.maps.Map(
document.getElementById('map'), {
zoom: 16,
center: uluru
});
var marker = new google.maps.Marker({position: uluru, map: map});
}
</script>
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyAQLj-_PEe0qXFXtqhs_EdE-ZmC5zoReMs&callback=initMap"
async defer></script>
<div class="card">
<h3>รายละเอียด</h3>
<p>{{$detail["description"]}}</p>
</div>
</div>
@endforeach
<script type="text/javascript">
function success(){
alert("success");
}
</script>
<div class="card" id="cardlocation">
<div id="fb-root"></div>
<script async defer crossorigin="anonymous" src="https://connect.facebook.net/th_TH/sdk.js#xfbml=1&version=v6.0"></script>
<meta property="fb:app_id" content="548420145834917">
<center><div class="fb-comments" data-href={{Request::url()}} data-width="1000" data-numposts="5"></div></center>
</div>
</body>
</html>
<?php
use Illuminate\Http\Request;
/*
|--------------------------------------------------------------------------
| API Routes
|--------------------------------------------------------------------------
|
| Here is where you can register API routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| is assigned the "api" middleware group. Enjoy building your API!
|
*/
Route::middleware('auth:api')->get('/user', function (Request $request) {
return $request->user();
});
<?php
/*
|--------------------------------------------------------------------------
| Broadcast Channels
|--------------------------------------------------------------------------
|
| Here you may register all of the event broadcasting channels that your
| application supports. The given channel authorization callbacks are
| used to check if an authenticated user can listen to the channel.
|
*/
Broadcast::channel('App.User.{id}', function ($user, $id) {
return (int) $user->id === (int) $id;
});
<?php
use Illuminate\Foundation\Inspiring;
/*
|--------------------------------------------------------------------------
| Console Routes
|--------------------------------------------------------------------------
|
| This file is where you may define all of your Closure based console
| commands. Each Closure is bound to a command instance allowing a
| simple approach to interacting with each command's IO methods.
|
*/
Artisan::command('inspire', function () {
$this->comment(Inspiring::quote());
})->describe('Display an inspiring quote');
<?php
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Route::view('/','search');
Route::get('/search','getplace@getdata')->name('getplace.getdata');
Route::get('/selectview','addplace@showselect');
Route::get('/detail_/{attractions_id}','detail@showdetail');
Route::get('/add','addplace@add')->name('addplace.add');
Route::get('/delAllSelect','addplace@delAllSelect');
Route::get('/del','addplace@del')->name('addplace.del');
Route::post('/result','ResultController@getresult')->name('ResultController.getresult');
//login
Route::get('/adminlogin','loginController@checkLogin')->name('loginController.checkLogin');
Route::post('/login','loginController@login')->name('loginController.login');
Route::view('/admin','admin');
Route::get('/admin/logout','loginController@logout');
/**admin */
Route::view('/admin/insert','insert');
Route::post('/admin/insertAttraction','adminController@insertAttraction')->name('adminController.insertAttraction');
Route::post('/admin/insertProvince','adminController@insertProvince')->name('adminController.insertProvince');
Route::post('/admin/deleteProvince','adminController@deleteProvince')->name('adminController.deleteProvince');
Route::post('/admin/deleteAttraction','adminController@deleteAttraction')->name('adminController.deleteAttraction');
Route::view('admin/delete','delete');
Route::get('/admin/search','adminController@search')->name('adminController.search');
Route::get('/admin/edit','adminController@edit')->name('adminController.edit');
Route::post('/admin/update','adminController@update')->name('adminController.update');
Route::view('/test','test');
Route::get('/show','addplace@show');
<?php
/**
* Laravel - A PHP Framework For Web Artisans
*
* @package Laravel
* @author Taylor Otwell <taylor@laravel.com>
*/
$uri = urldecode(
parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH)
);
// This file allows us to emulate Apache's "mod_rewrite" functionality from the
// built-in PHP web server. This provides a convenient way to test a Laravel
// application without having installed a "real" web server software here.
if ($uri !== '/' && file_exists(__DIR__.'/public'.$uri)) {
return false;
}
require_once __DIR__.'/public/index.php';
*
!public/
!.gitignore
config.php
routes.php
schedule-*
compiled.php
services.json
events.scanned.php
routes.scanned.php
down
<?php
namespace Tests;
use Illuminate\Contracts\Console\Kernel;
trait CreatesApplication
{
/**
* Creates the application.
*
* @return \Illuminate\Foundation\Application
*/
public function createApplication()
{
$app = require __DIR__.'/../bootstrap/app.php';
$app->make(Kernel::class)->bootstrap();
return $app;
}
}
<?php
namespace Tests\Feature;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
class ExampleTest extends TestCase
{
/**
* A basic test example.
*
* @return void
*/
public function testBasicTest()
{
$response = $this->get('/');
$response->assertStatus(200);
}
}
<?php
namespace Tests;
use Illuminate\Foundation\Testing\TestCase as BaseTestCase;
abstract class TestCase extends BaseTestCase
{
use CreatesApplication;
}
<?php
namespace Tests\Unit;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
class ExampleTest extends TestCase
{
/**
* A basic test example.
*
* @return void
*/
public function testBasicTest()
{
$this->assertTrue(true);
}
}
const mix = require('laravel-mix');
/*
|--------------------------------------------------------------------------
| Mix Asset Management
|--------------------------------------------------------------------------
|
| Mix provides a clean, fluent API for defining some Webpack build steps
| for your Laravel application. By default, we are compiling the Sass
| file for the application as well as bundling up all the JS files.
|
*/
mix.js('resources/js/app.js', 'public/js')
.sass('resources/sass/app.scss', 'public/css');
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment