shop documentation - read the docs · 1.2.2end user hugo is an architect and middle aged. he is...
TRANSCRIPT
Shop DocumentationRelease 001
Fabian Affolter
04072014
Inhaltsverzeichnis
1 Basics 311 Products 312 Personas 413 Use cases 414 Design principles 5
2 Web shop Design 721 General 722 Layout 723 Sitemap 824 Main page 9
3 Style and design 1131 Cascading Style Sheets 1132 Pages 11
4 Dynamics 1341 Setup 1342 Current year 1343 Navigation Menu 1344 List of Products 1445 Company details 15
5 External files 1751 Navigation Menu 1752 Header 1753 Footer 18
6 Input processing 1961 ldquoBuy Nowrdquo links 1962 Select options 20
7 Javascript 2171 Simple use case 21
8 Cookies and Sessions 2381 Cookies 2382 Hit counter 2383 Language selection 24
i
84 User Accounts 24
9 Database 2591 Tables 2592 PHP 25
10 Web service 27101 Map 27102 Weather 27
11 Data export 29111 PDF 29112 JSON 29
12 Messaging 31121 MQTT 31122 Email 32
13 Localisation (L10n) 33
14 Templates 35141 Template 35142 Content 35
15 Development 37151 Web server 37152 Database server 37153 Versions 37154 Setup infrastructure 38155 Git respository 38156 Documentation 39
16 Indices and tables 41
ii
Shop Documentation Release 001
This is the documentation of the genesi of a web shop It describes the taken steps and the features The code is notproduction-ready but shows at various locations different way to do things
Contents
Inhaltsverzeichnis 1
Shop Documentation Release 001
2 Inhaltsverzeichnis
KAPITEL 1
Basics
11 Products
The Web shop will be for selling pencils in various types
Categories
bull Standard pencils
bull Mechnical pencils
bull Special pencils
Variants or options
bull Color (red yellow black white etc)
bull Hardness (standard HB hard F H 2H soft B 2B)
bull Additional function (Eraser at the end Protection cap handle)
111 Product overview
(The product names are in German because the main language of the shop will not be English)
3
Shop Documentation Release 001
Type Variant Color Hardness Price CHFBleistift keine rot HB 1Bleistift keine rot B 1Bleistift keine rot 2B 1Bleistift keine gelb F 120Bleistift keine gelb H 120Bleistift keine gelb 2H 120Bleistift Gummi rot HB 110Schreiner-Bleistift keine rot HB 180Schreiner-Bleistift keine rot B 180Bleistift keine rot HB 05Bleistift Gummi rot HB 06Kuumlnstler-Bleistift Griff gelb 2B 2Kuumlnstler-Bleistift Griff rot 2B 2Kuumlnstler-Bleistift Griff schwarz 2B 2Minien-Bleistift keine weiss 4Minien-Bleistift keine blau 4Minien-Bleistift keine gelb 4Minien-Bleistift keine rot 4Minien-Bleistift keine silber 9Minien-Bleistift keine schwarz 9
12 Personas
The following personas are defined to interact with the web shop
121 Major customer
Eva is responsible for the ordering of office supplies in her joinery She is ordering twice a month a large amount ofvarious product for different users (management back office and production) Eva has a fix budget for the orders andshe knows her way around web shops
122 End user
Hugo is an architect and middle aged He is drawing sketches and technical drawings but also artistically demandingpieces by hand Thanks to the work with CAD he decovers the web and its advantages Before he bought all his toolsin a local stationery nowadays he is ordering stuff online
13 Use cases
The shop will be stripped-down to two use cases With those use cases are all major use cases with only little modifi-cations covered The use cases for the shop adimistration will be considered out of scope
131 Major customer
bull Ordering of a large amount of one single products or several products
bull Volume discount
4 Kapitel 1 Basics
Shop Documentation Release 001
bull Splitting of oders (ev delivery to different locations)
132 End user
bull Ordering of single products
bull Small quantities
14 Design principles
The below listed points are the fundation for the implementation of the design and the layout to the shop
bull Products should be in the spot light
bull Reduced to the essentials (typography colors fonts etc)
bull meaningful use of whitespaces
Instead of reinventing the wheel it should be considered to use a matured front-end framework like bootstrap for thelayout especially regarding responsive design
14 Design principles 5
Shop Documentation Release 001
6 Kapitel 1 Basics
KAPITEL 2
Web shop Design
21 General
The used company and all data are notional There is no exisiting connection to any existing company with the sameor similar name
211 Company name
The company name is Pencil AG
212 Address
The complete address of the company is
Pencil AGMusterstrasse 13000 BernSchweiz
213 Logo
The logo used in this project is borrowed from the Tango project icon set The file is out of the categories section thefile name of the origin file is applications-officesvg and is licensed under Public Domain
22 Layout
The layout is splitted in different sections The content of the elements especially of the main section (content) willbe definied by the later usage of the page
7
Shop Documentation Release 001
23 Sitemap
The sitemap shows the clustering of the shop at the beginning of the project
This doesnrsquot mean that everything will be done Static pages are easy to make and to maintain
8 Kapitel 2 Web shop Design
Shop Documentation Release 001
24 Main page
The first draft of the main page is based on the prototype shown in section Layout without any format- und styleinformationen
ltDOCTYPE htmlgtlthtml lang=engt
ltheadgtltmeta charset=utf-8gtltmeta name=viewport content=width=device-width initial-scale=10gtltmeta name=description content=Webshop Pencil AG fuumlr Bleistiftegtltmeta name=author content=Fabian AffoltergtlttitlegtWebshop Pencil AG | Homelttitlegt
ltheadgt
ltbodygtlt-- Header container--gtltdivgt
ltdivgtlt-- Logo and company name --gtltimg src=logologopnggtlth2gtWebshop Pencil AGlth2gtlt-- Navigation --gtltulgt
ltligtlta href=gtHomeltagtltligtltligtlta href=gtProdukteltagtltligtltligtlta href=gtUumlber unsltagtltligt
ltulgtlt-- Breadcrumb --gtltolgt
ltligtlta href=gtEbene 1ltagtltligtltligtlta href=gtEbene 2ltagtltligtltligtlta href=gtEbene 3ltagtltligt
ltolgtltdivgt
ltdivgtlt-- Header container--gt
lt-- Action container --gtltdivgt
lth1gtWochen-Aktionlth1gtltpgtDies ist eine super Aktion 10 Bleistifte fuumlr CHF 8ltpgt
ltdivgtlt-- Action container --gt
lt-- Selected products --gtltdivgt
ltpgtHier hat es zufaumlllige Produkteltpgtltdivgtlt-- Selected products --gt
lt-- Footer --gtltdivgt
ltpgtampcopy Pencil AG 2013ltpgtlt-- Footer --gtltdivgt
ltbodygtlthtmlgt
24 Main page 9
Shop Documentation Release 001
Loaded in a browser the initial draft of the main page looks like in the following screenshot
10 Kapitel 2 Web shop Design
KAPITEL 3
Style and design
31 Cascading Style Sheets
The design of the shop will be nothing fancy The approach which was choosen will reflect the points mentioned inthe Design principles section and makes heavy use of the bootstrap framework cascading style sheet Various changesto this CSS file ensure that it matche the needs of this project
32 Pages
The product page show the elements mentioned in the Product overview section
11
Shop Documentation Release 001
12 Kapitel 3 Style and design
KAPITEL 4
Dynamics
The webshop will be a PHP application at the end Those first steps are only covering the very basic stuff of PHP asan introduction
41 Setup
The setupyml playbook puts a simple PHP file in the root directory of the web server with the namephpinfophp This file displays PHP details
Achtung Remove this file before makeing the shop accessible by a public audience
42 Current year
The first PHP element in the webshop is showing the current year in the footer of every page With the help of thislittle piece of code there is no longer a need to update the year
ltphp echo date(Y) gt
43 Navigation Menu
The basic menu was built with the following snippet
ltphp$menu = array(rsquoHomersquo =gt rsquoindexphprsquo
rsquoProduktersquo =gt rsquoproductsphprsquorsquoUumlber unsrsquo =gt rsquoaboutphprsquo
)foreach($menu as $label =gt $link)
echo rsquoltligtlta href=rsquo $link rsquogtrsquo $label rsquoltagtltligtrsquo
gt
The issue with that snippet was that the CSS class was missing In regards to a future separation and reusability anadditional statements was added This way the label of the active page is highlighted
13
Shop Documentation Release 001
ltphp$menu = array(rsquoHomersquo =gt rsquoindexphprsquo
rsquoProduktersquo =gt rsquoproductsphprsquorsquoUumlber unsrsquo =gt rsquoaboutphprsquo
)foreach ($menu as $label =gt $link)
$url = trim($_SERVER[rsquoPHP_SELFrsquo] rsquorsquo)if ($link == $url)
echo rsquoltli class=activegtlta href=rsquo $link rsquogtrsquo $label rsquoltagtltligtrsquo else
echo rsquoltli class=gtlta href=rsquo $link rsquogtrsquo $label rsquoltagtltligtrsquo
gt
44 List of Products
The product overiew is a simple table The heading of the table is placed in an array
ltdivgtlttable class=table table-stripedgtltthead valign=bottomgtlttrgtltphp
$heading = array(rsquoTypersquo rsquoVariantrsquo rsquoColorrsquo rsquoHardnessrsquo rsquoPrice CHFrsquo)foreach ($heading as $element)
echo rsquoltth class=headgtrsquo$elementrsquoltthgtrsquon
gtlttrgtlttheadgtlttbody valign=topgtltphp
$products = array(array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquoHBrsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquoBrsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquo2Brsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquoFrsquo rsquo12rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquoHrsquo rsquo12rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquo2Hrsquo rsquo12rsquo)
)foreach ($products as $product =gt $details)
echo lttrgtforeach ($details as $detail)
echo lttdgt$detaillttdgtecho lttrgt
gtlttbodygtlttablegt
ltdivgt
14 Kapitel 4 Dynamics
Shop Documentation Release 001
45 Company details
The data for the About page are included out of a static and plain text file
ltphp$str = file_get_contents(companytxt)echo $str
gt
45 Company details 15
Shop Documentation Release 001
16 Kapitel 4 Dynamics
KAPITEL 5
External files
51 Navigation Menu
The menu is outsourced in the file menuphp
ltphpfunction menu()
$part1 = rsquoltul class=nav nav-tabsgtrsquon$part2 = rsquorsquo$part3 = rsquoltulgtrsquon Menu array with page title and assigned file$menu = array(rsquoHomersquo =gt rsquoindexphprsquo
rsquoProduktersquo =gt rsquoproductsphprsquorsquoUumlber unsrsquo =gt rsquoaboutphprsquo
)foreach ($menu as $label =gt $link)
For the CSS only the file name without is needed$url = trim($_SERVER[rsquoPHP_SELFrsquo] rsquorsquo)if ($link == $url)
$part2 = $part2ltli class=rsquoactiversquogtlta href=rsquo$linkrsquogt$labelltagtltligtn else
$part2 = $part2ltli class=rsquorsquogtlta href=rsquo$linkrsquogt$labelltagtltligtn
return $part1$part2$part3
gt
52 Header
The complete header part is loaded from the file headerphp
ltphpfunction head()
$start_page = indexphp$part1 = ltdivgtn$part2 = tlta class=rsquobrand-logorsquo href=rsquo$start_pagersquogtltagtn$part3 = tltp class=rsquobrand-namersquogtWebshop Pencil AGltpgtn$part4 = ltdivgtnreturn $part1$part2$part3$part4
17
Shop Documentation Release 001
gt
53 Footer
The same is done witht the page footers
ltphpfunction foot()
$class1 = rsquoltdiv class=footergtrsquon$class2 = rsquoltdivgtrsquon$text = ltpgtampcopy Pencil AG getYear()rsquoltpgtrsquonreturn $class1$text$class2
function getYear()return date(Y)
gt
18 Kapitel 5 External files
KAPITEL 6
Input processing
61 ldquoBuy Nowrdquo links
The ldquoBuy Nowrdquo links are attached to the Products page Every entry has itrsquos own link which lead to a detail page Thelinks are using hidden form elements to transfer the data
ltphp$products = array(array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquoHBrsquo rsquo1rsquo)
array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquoBrsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquo2Brsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquoFrsquo rsquo12rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquoHrsquo rsquo12rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquo2Hrsquo rsquo12rsquo)
)foreach ($products as $product =gt $details)
echo lttrgtnforeach ($details as $detail)
echo lttdgt$detaillttdgtnecho lttdgtnecho ltform action=rsquoproductphprsquo method=rsquogetrsquo name=rsquopencilrsquogtnecho ltinput type=rsquohiddenrsquo name=rsquotypersquo value=rsquo$details[0]rsquogtnecho ltinput type=rsquohiddenrsquo name=rsquooptionsrsquo value=rsquo$details[1]rsquogtnecho ltinput type=rsquohiddenrsquo name=rsquocolorrsquo value=rsquo$details[2]rsquogtnecho ltinput type=rsquohiddenrsquo name=rsquohardnessrsquo value=rsquo$details[3]rsquogtnecho ltinput type=rsquohiddenrsquo name=rsquopricersquo value=rsquo$details[4]rsquogtnecho ltinput type=rsquosubmitrsquo class=rsquobtn btn-defaultrsquo value=rsquoKauf michrsquogtnecho ltformgtnecho lttdgtnecho lttrgtn
gt
And the detail page contains the code fragement mentioned below
ltphp$type=$_GET[rsquotypersquo]$color=$_GET[rsquocolorrsquo]$hardness=$_GET[rsquohardnessrsquo]$options=$_GET[rsquooptionsrsquo]$price=$_GET[rsquopricersquo]echo I am a $type in $color and a hardness of $hardness I have $options as an option and my price is $price CHF
gt
19
Shop Documentation Release 001
Bemerkung The Products page was modified in the process of the development
62 Select options
The signupbilling page contains a dropdown element that all days of a month for the entry of the userrsquos birthday
ltselect name=daygtltoptiongtDayltoptiongt
ltphp$days = range(31 1)foreach ($days as $day)
echo rsquoltoption value=rsquo$dayrsquogtrsquo$dayrsquoltoptiongtrsquo
gtltselectgt
20 Kapitel 6 Input processing
KAPITEL 7
Javascript
Over the years Javascript became a very popular programming language The webshop is using Javascript at a coupleof places
71 Simple use case
Javascript makes it easy to access elements in the DOM Setting the focus is a nice way to support the user with inputform
ltscript language=javascriptgtfunction setFocus()
documentforms[login][username]focus()
ltscriptgtltheadgtltbody onload=setFocus()gt
Another one is to check if something was entered in an input field
function validateForm() var username = documentforms[rdquologinrdquo][rdquousernamerdquo]value if (username== null || username == ldquordquo)
documentforms[rdquologinrdquo][rdquousernamerdquo]stylebackgroundColor = ldquoFF9999rdquo docu-mentforms[rdquologinrdquo][rdquousernamerdquo]placeholder = ldquoPlease your usernamerdquo docu-mentforms[rdquologinrdquo][rdquousernamerdquo]focus() return false
A simple message is informing the user about an action which was taken against the database
echo ltscript type=textjavascriptgtalert(New entry $entry added successfully)windowlocation = tablesphp
ltscriptgt
The delete process is only executed if the user confirm to delete a record
ltform action=scriptsdelete-processphp onSubmit=return confirm(rsquoAre you sure to delete this entryrsquo) method=POSTgtltinput type=hidden name=table value=$sectiongtltinput type=hidden name=id value=$result-gtidgtltinput type=submit name=Submit value=Deletegt
ltformgt
For additional Javascript please check the source of the indexphp file and the reflsquowebservicelsquo_ section
21
Shop Documentation Release 001
22 Kapitel 7 Javascript
KAPITEL 8
Cookies and Sessions
The built-in support for sessions in PHP is handling all cookie manipulation to provide persistent variables that areaccessible from different pages and across multiple visits to the site
81 Cookies
A cookie is used to track the last time a visitor check the front page The cookie is set when a visitor arrives
function lastVisit($name $expire) $value = getDateDMY() - getTimeHM()setcookie($name $value time() + $expire rsquorsquo $_SERVER[rsquoSERVER_NAMErsquo] true true)
In the footer of the index page the details are presented
ltphpif(isset($_COOKIE[rsquoLastVisitrsquo]))
$last = $_COOKIE[rsquoLastVisitrsquo]echo You last visited us on $last
else echo This is your first visit
gt
82 Hit counter
As a simple show case for PHP sessions a hit counter for the front page is available
ltphpsession_start()
$_SESSION[rsquohitsrsquo] = $_SESSION[rsquohitsrsquo] + 1gt
Included in the footer it shous the users the total of visits
echo Total $_SESSION[rsquohitsrsquo] visits of this page
23
Shop Documentation Release 001
83 Language selection
84 User Accounts
24 Kapitel 8 Cookies and Sessions
KAPITEL 9
Database
The database backend for the webshop will be MariaDB which is the drop-in replacement for MySQL
For the setup please check the Development section in this documentation
91 Tables
The following tables are needed for the webshop to work
bull products
bull customers
bull pencils
bull colors
bull hardness
bull options
bull users
Please use the develwebshopsql to setup the database
92 PHP
Below you find the configuration file for a default installation of the webshop This file is a template and filled duringthe setup process
ltphp$host = localhost$user = root$password = webshop$dbase = webshop$connection = new mysqli($host $user $password $dbase)
if ($connection-gtconnect_errno) echo Failed to connect to MariaDBMySQL ($connection-gtconnect_errno) $connection-gtconnect_error
mysqli_report(MYSQLI_REPORT_ERROR)
gt
25
Shop Documentation Release 001
All connections to the database are done in the same way Below you find an example Everything is done in theobject-oriented style
ltphprequire_once(rsquoconfigdbconnectphprsquo)if ($connection-gtconnect_errno == 0)
$sql = SELECT FROM products$results = $connection-gtquery($sql)echo $results-gtnum_rows$results-gtclose()
else echo Database connection error
gt
26 Kapitel 9 Database
KAPITEL 10
Web service
Tow web services are integrated to take advantages of online available data sources
101 Map
Leafletjs a JavaScript library for working with interactive maps from OpenStreetMap (OSM) is implemented as ashow case for a simple web service
The basic steps to integrate a map is shown below
ltdiv id=map class=map style=width 600px height 400pxgtltdivgt
ltscript src=scriptsleafletjsgtltscriptgtltscript src=scriptsleaflet-providersjsgtltscriptgtltscriptgtvar map = Lmap(rsquomaprsquo
center [250472 -773255]zoom 12zoomControl true
)
var defaultLayer = LtileLayerprovider(rsquoOpenStreetMapMapnikrsquo)addTo(map)ltscriptgt
102 Weather
The OpenWeatherMap service provides free weather data and a forecast API for web applications
ltphp Details about the API httpbugsopenweathermaporgprojectsapiwikiApi_2_5_weather$url = rsquohttpapiopenweathermaporgdata25weatherq=Bernechampunit=metricsampmode=jsonrsquo
$json = file_get_contents($url)$data = json_decode($json)
$tempC = round((27315 - $data-gtmain-gttemp)100) 100$humidity = $data-gtmain-gthumidity$pressure = $data-gtmain-gtpressure
27
Shop Documentation Release 001
echo ltpgtTemperatur $tempC degCltbrgtnecho Luftfeuchtigkeit $humidity ltbrgtnecho Luftdruck $pressure Paltpgtn
gt
28 Kapitel 10 Web service
KAPITEL 11
Data export
111 PDF
FPDF is a PHP class that allows to generate PDF files with pure PHP As a showcase for that the product specificationsfor a given product are filled in a pdf and showed in the browser The user can then decide to download or print thefile
112 JSON
JavaScript Object Notation (JSON) is a lightweight data-interchange format The format is language independent andPHP support the encoding and the decoding JSON with json_encode($data) and json_decode($data)$rows = array()$sql = SELECT FROM products$results = $connection-gtquery($sql)while ($result = $results-gtfetch_object())
$rows[] = $result$results-gtclose()
Writing all rows to a JSON file$fp = fopen(rsquopencilsjsonrsquo rsquowrsquo)fwrite($fp json_encode($rows))fclose($fp)gt
and for reading it
ltphp$json = file_get_contents(rsquopencilsjsonrsquo)print_r(json_decode($json))
gt
29
Shop Documentation Release 001
30 Kapitel 11 Data export
KAPITEL 12
Messaging
Beside standard email messages the webshop supports sending MQ Telemetry Transport protocol (MQTT) messagesas an additional feature The MQTT messages are small
121 MQTT
Mosquitto-PHP is used as a PHP wrapper for MQTT Please check the Projectrsquos README for details about theinstallation and the setup
1211 Broker
Mosquitto is a message broker that implements the MQ Telemetry Transport protocol Check if mosquitto is run-ning
$ sudo systemctl status mosquittoservice
If not start it
$ systemctl start mosquittoservice
All messages are published to the topic webshop
1212 Publishing
After the installation of Mosquitto-PHP the snipplet shown below sends a single message
ltphpdefine(rsquoBROKERrsquo rsquolocalhostrsquo)define(rsquoPORTrsquo 1883)define(rsquoCLIENT_IDrsquo webshop_ + getmypid())$topic = webshop$subtopic = test$completeTopic = $topic$subtopic
$client = new MosquittoClient(CLIENT_ID)$client-gtconnect(BROKER PORT 60)
$message = Test message from webshop at date(Y-m-d His)$client-gtpublish($completeTopic $message 0 false)
gt
31
Shop Documentation Release 001
1213 Subscribing
To read the messages sent by the webshop a client is needed The Mosquitto broker contain a simple command-linetool for subscribing to various topics
$ mosquitto_sub -h localhost -t webshop
122 Email
This section doesnrsquot describe the installation and configuration of a local MTA There are enough resources thatcontains information about the setup of postfix for local delivery only
If you want to test the email feature add the following code in one of PHP pages
ltphp mail(rsquorootlocalhostrsquo rsquoTest message from webshoprsquo rsquoThe webshop is selling pencilsrsquo) gt
By default SELinux is running in Enforcing mode which is restrictive about about what a web server can do Toallow sending email the following SELinux boolean needs to changed
setsebool -P httpd_can_network_connect=1 setsebool -P httpd_can_sendmail=1
32 Kapitel 12 Messaging
KAPITEL 13
Localisation (L10n)
There are several ways to add localisation to a web site For small projects arrays with string can work but this is notvery efficient and user-friendly With Gettext is a toolset available that provide a framework to produce multi-lingualcontent in a wide area of programming languages
Make sure that the php-gettext package is available on your system If not install it
$ sudo yum -y install php-php-gettext
Check if gettext support is available
ltphpif (function_exists(gettext))
echo gettext is not installednelse
echo gettext is supportedn
gt
Make sure that all locales your want are available on the server
locale -a
The first step is to mark all string which should be translatable as shown below For further details please refer to theGettext documentation
echo _(rsquoSome textrsquo)
The next step is to extract all strings
xgettext --from-code=UTF-8 -o localewebshoppot php scriptsphp
To re-generate the file after an update join the strings
xgettext -j --from-code=UTF-8 -o localewebshoppot php scriptsphp
For every language a po file is needed for the transations Generate it with the command mentioned below
msginit --no-translator -l de_CH -o localede_CHpo -i localewebshoppot
Once created there are only updates of the message catalog needed in the futures
msgmerge -U localede_CHpo localewebshoppot
If you re finish create the mo file for the specific language
33
Shop Documentation Release 001
msgfmt -c -v -o localede_CHLC_MESSAGESwebshopmo localede_CHpo
34 Kapitel 13 Localisation (L10n)
KAPITEL 14
Templates
Beside other solutions Savant3 is a lightweight object-oriented template system for PHP This solution does not needa lot of additional configuration
141 Template
A simple template file looks like the one shown below
lthtmlgtltheadgt
lttitlegtltphp echo $this-gteprint($this-gttitle) gtlttitlegtltheadgtltbodygt
ltphp echo $this-gteprint($this-gtcontent) gtltbodygt
lthtmlgt
For a more detailed intro check this article on Zend Developer Zone
142 Content
To fill the template with data all wished variables needs to be defined in a seperate PHP file
ltphprequire_once rsquoscriptsSavant3phprsquo$tpl = new Savant3()
Create a title$title = Simple sample page
Create the content of the page$content = Some sample text to show
Assign values to the Savant instance$tpl-gttitle = $title$tpl-gtcontent = $content
Define the template source file to show$tpl-gtdisplay(rsquosimpletplphprsquo)
gt
35
Shop Documentation Release 001
The webshop contains a page (master)
36 Kapitel 14 Templates
KAPITEL 15
Development
This sections describes the configuration of the development and runtime environment for the web shop
151 Web server
Instead of Apache the project is running on Lighttpd The reasons are that Lighttpd provides faster setup easierconfiguration and better performance Lighttpd is running with FastCGI
The path of the web server is varwwwlighttpd and the SELinux configuration are still the defaults
The web server is running in SSL-only mode and the certificate is generated during the server setup process
152 Database server
For persistence storage the drop-in replacement MariaDB is used MySQL will work to but this is not tested phpMyAd-min is available under phpmyadmin on the web server beside the command-line tools for easy administration
The default credentials for phpMyAdmin are rootwebshop or the entry you made in the Ansible playbookdevelvariablessensitiveyml
153 Versions
The web shop is built with the below listed components and tested Other releases can be used and may work but thiswill not be tested Probably it will work with different releases
bull Operating system Fedora 20
bull Kernel 3135-202fc20x86_64
bull Lighttpd 1434
bull PHP 557
bull MariaDB 5534
For communication postfix and mosquitto are needed additionally
37
Shop Documentation Release 001
154 Setup infrastructure
1541 Configuration management
For the creation of reproducable and identical environment for the development and the run-time across differentsystems Ansible is used as configuration management solution All needed steps of the installation are automated Theconfiguration doesnrsquot differentiate between local or remote installations This matters only for the deployment of theweb content
For local development itrsquos possible to use an LX container
$ sudo ansible-playbook develcontaineryml
To get everything running some additional steps (check the network inside the container generate keys etc) areneeded After you are done check it
$ sudo ansible webshop -m setup
From the management system
$ sudo ssh-copy-id -i rootsshid_rsapub root[IP address of your managed node]
The configuration of Ansible itself (adding the system to etcansiblehosts and copying the SSH keys) isnot documented at this place There are various resources available like here All playbooks are located in the folderdevel Start the setup with the command shown below
$ sudo ansible-playbook develsetupyml
The used group name in etcansiblehosts is webshop
If the setup completes without errors then the web server is accessible and show a default page Please keep in mindthat the server is only accessible over https unencrypted traffic is not allowed
1542 DeploymentSetup website
For the simple deployment of the lastest version of the shop a playbook called deployyml is provided Thisplaybook put all files in place
$ sudo ansible-playbook develdeployyml
To full deploy the webshop all tables in the database must exist The file webshopsql contains all needed SQLcommands and sample data for the web application
Itrsquos possible to deploy the website manually but this is not recommended A couple of files are depending on templateswhich are created during the deployment
Itrsquos also not recommanded to clone everything into your webserver root This would save you the trouble of doing itby hand but third-party features are missing then Those missing parts are the template engine the pdf generation theconnection to Openstreetmap and probably other things not mentioned here
155 Git respository
All project relevante informations (Source code templates documentation etc) is located in a public Git repositoryon Github
38 Kapitel 15 Development
Shop Documentation Release 001
156 Documentation
The documentation is using reStructuredText as markup language For a local build Sphinx is needed Sphinx isavailable in the Fedora Package Collection and can be installed with yum or any other package management tool
yum -y install python-sphinx python-docutils
The source files of the documentation are located under docs
$ cd docs$ make html
The output is stored under docs_buildhtml
After every push to Github a hook launch a rebuild of the documentation The latest release will be published on Readthe Docs automatically
httpsshoprtfdorg
156 Documentation 39
Shop Documentation Release 001
40 Kapitel 15 Development
KAPITEL 16
Indices and tables
bull genindex
bull modindex
bull search
41
- Basics
-
- Products
- Personas
- Use cases
- Design principles
-
- Web shop Design
-
- General
- Layout
- Sitemap
- Main page
-
- Style and design
-
- Cascading Style Sheets
- Pages
-
- Dynamics
-
- Setup
- Current year
- Navigation Menu
- List of Products
- Company details
-
- External files
-
- Navigation Menu
- Header
- Footer
-
- Input processing
-
- ``Buy Now links
- Select options
-
- Javascript
-
- Simple use case
-
- Cookies and Sessions
-
- Cookies
- Hit counter
- Language selection
- User Accounts
-
- Database
-
- Tables
- PHP
-
- Web service
-
- Map
- Weather
-
- Data export
-
- JSON
-
- Messaging
-
- MQTT
-
- Localisation (L10n)
- Templates
-
- Template
- Content
-
- Development
-
- Web server
- Database server
- Versions
- Setup infrastructure
- Git respository
- Documentation
-
- Indices and tables
-
Inhaltsverzeichnis
1 Basics 311 Products 312 Personas 413 Use cases 414 Design principles 5
2 Web shop Design 721 General 722 Layout 723 Sitemap 824 Main page 9
3 Style and design 1131 Cascading Style Sheets 1132 Pages 11
4 Dynamics 1341 Setup 1342 Current year 1343 Navigation Menu 1344 List of Products 1445 Company details 15
5 External files 1751 Navigation Menu 1752 Header 1753 Footer 18
6 Input processing 1961 ldquoBuy Nowrdquo links 1962 Select options 20
7 Javascript 2171 Simple use case 21
8 Cookies and Sessions 2381 Cookies 2382 Hit counter 2383 Language selection 24
i
84 User Accounts 24
9 Database 2591 Tables 2592 PHP 25
10 Web service 27101 Map 27102 Weather 27
11 Data export 29111 PDF 29112 JSON 29
12 Messaging 31121 MQTT 31122 Email 32
13 Localisation (L10n) 33
14 Templates 35141 Template 35142 Content 35
15 Development 37151 Web server 37152 Database server 37153 Versions 37154 Setup infrastructure 38155 Git respository 38156 Documentation 39
16 Indices and tables 41
ii
Shop Documentation Release 001
This is the documentation of the genesi of a web shop It describes the taken steps and the features The code is notproduction-ready but shows at various locations different way to do things
Contents
Inhaltsverzeichnis 1
Shop Documentation Release 001
2 Inhaltsverzeichnis
KAPITEL 1
Basics
11 Products
The Web shop will be for selling pencils in various types
Categories
bull Standard pencils
bull Mechnical pencils
bull Special pencils
Variants or options
bull Color (red yellow black white etc)
bull Hardness (standard HB hard F H 2H soft B 2B)
bull Additional function (Eraser at the end Protection cap handle)
111 Product overview
(The product names are in German because the main language of the shop will not be English)
3
Shop Documentation Release 001
Type Variant Color Hardness Price CHFBleistift keine rot HB 1Bleistift keine rot B 1Bleistift keine rot 2B 1Bleistift keine gelb F 120Bleistift keine gelb H 120Bleistift keine gelb 2H 120Bleistift Gummi rot HB 110Schreiner-Bleistift keine rot HB 180Schreiner-Bleistift keine rot B 180Bleistift keine rot HB 05Bleistift Gummi rot HB 06Kuumlnstler-Bleistift Griff gelb 2B 2Kuumlnstler-Bleistift Griff rot 2B 2Kuumlnstler-Bleistift Griff schwarz 2B 2Minien-Bleistift keine weiss 4Minien-Bleistift keine blau 4Minien-Bleistift keine gelb 4Minien-Bleistift keine rot 4Minien-Bleistift keine silber 9Minien-Bleistift keine schwarz 9
12 Personas
The following personas are defined to interact with the web shop
121 Major customer
Eva is responsible for the ordering of office supplies in her joinery She is ordering twice a month a large amount ofvarious product for different users (management back office and production) Eva has a fix budget for the orders andshe knows her way around web shops
122 End user
Hugo is an architect and middle aged He is drawing sketches and technical drawings but also artistically demandingpieces by hand Thanks to the work with CAD he decovers the web and its advantages Before he bought all his toolsin a local stationery nowadays he is ordering stuff online
13 Use cases
The shop will be stripped-down to two use cases With those use cases are all major use cases with only little modifi-cations covered The use cases for the shop adimistration will be considered out of scope
131 Major customer
bull Ordering of a large amount of one single products or several products
bull Volume discount
4 Kapitel 1 Basics
Shop Documentation Release 001
bull Splitting of oders (ev delivery to different locations)
132 End user
bull Ordering of single products
bull Small quantities
14 Design principles
The below listed points are the fundation for the implementation of the design and the layout to the shop
bull Products should be in the spot light
bull Reduced to the essentials (typography colors fonts etc)
bull meaningful use of whitespaces
Instead of reinventing the wheel it should be considered to use a matured front-end framework like bootstrap for thelayout especially regarding responsive design
14 Design principles 5
Shop Documentation Release 001
6 Kapitel 1 Basics
KAPITEL 2
Web shop Design
21 General
The used company and all data are notional There is no exisiting connection to any existing company with the sameor similar name
211 Company name
The company name is Pencil AG
212 Address
The complete address of the company is
Pencil AGMusterstrasse 13000 BernSchweiz
213 Logo
The logo used in this project is borrowed from the Tango project icon set The file is out of the categories section thefile name of the origin file is applications-officesvg and is licensed under Public Domain
22 Layout
The layout is splitted in different sections The content of the elements especially of the main section (content) willbe definied by the later usage of the page
7
Shop Documentation Release 001
23 Sitemap
The sitemap shows the clustering of the shop at the beginning of the project
This doesnrsquot mean that everything will be done Static pages are easy to make and to maintain
8 Kapitel 2 Web shop Design
Shop Documentation Release 001
24 Main page
The first draft of the main page is based on the prototype shown in section Layout without any format- und styleinformationen
ltDOCTYPE htmlgtlthtml lang=engt
ltheadgtltmeta charset=utf-8gtltmeta name=viewport content=width=device-width initial-scale=10gtltmeta name=description content=Webshop Pencil AG fuumlr Bleistiftegtltmeta name=author content=Fabian AffoltergtlttitlegtWebshop Pencil AG | Homelttitlegt
ltheadgt
ltbodygtlt-- Header container--gtltdivgt
ltdivgtlt-- Logo and company name --gtltimg src=logologopnggtlth2gtWebshop Pencil AGlth2gtlt-- Navigation --gtltulgt
ltligtlta href=gtHomeltagtltligtltligtlta href=gtProdukteltagtltligtltligtlta href=gtUumlber unsltagtltligt
ltulgtlt-- Breadcrumb --gtltolgt
ltligtlta href=gtEbene 1ltagtltligtltligtlta href=gtEbene 2ltagtltligtltligtlta href=gtEbene 3ltagtltligt
ltolgtltdivgt
ltdivgtlt-- Header container--gt
lt-- Action container --gtltdivgt
lth1gtWochen-Aktionlth1gtltpgtDies ist eine super Aktion 10 Bleistifte fuumlr CHF 8ltpgt
ltdivgtlt-- Action container --gt
lt-- Selected products --gtltdivgt
ltpgtHier hat es zufaumlllige Produkteltpgtltdivgtlt-- Selected products --gt
lt-- Footer --gtltdivgt
ltpgtampcopy Pencil AG 2013ltpgtlt-- Footer --gtltdivgt
ltbodygtlthtmlgt
24 Main page 9
Shop Documentation Release 001
Loaded in a browser the initial draft of the main page looks like in the following screenshot
10 Kapitel 2 Web shop Design
KAPITEL 3
Style and design
31 Cascading Style Sheets
The design of the shop will be nothing fancy The approach which was choosen will reflect the points mentioned inthe Design principles section and makes heavy use of the bootstrap framework cascading style sheet Various changesto this CSS file ensure that it matche the needs of this project
32 Pages
The product page show the elements mentioned in the Product overview section
11
Shop Documentation Release 001
12 Kapitel 3 Style and design
KAPITEL 4
Dynamics
The webshop will be a PHP application at the end Those first steps are only covering the very basic stuff of PHP asan introduction
41 Setup
The setupyml playbook puts a simple PHP file in the root directory of the web server with the namephpinfophp This file displays PHP details
Achtung Remove this file before makeing the shop accessible by a public audience
42 Current year
The first PHP element in the webshop is showing the current year in the footer of every page With the help of thislittle piece of code there is no longer a need to update the year
ltphp echo date(Y) gt
43 Navigation Menu
The basic menu was built with the following snippet
ltphp$menu = array(rsquoHomersquo =gt rsquoindexphprsquo
rsquoProduktersquo =gt rsquoproductsphprsquorsquoUumlber unsrsquo =gt rsquoaboutphprsquo
)foreach($menu as $label =gt $link)
echo rsquoltligtlta href=rsquo $link rsquogtrsquo $label rsquoltagtltligtrsquo
gt
The issue with that snippet was that the CSS class was missing In regards to a future separation and reusability anadditional statements was added This way the label of the active page is highlighted
13
Shop Documentation Release 001
ltphp$menu = array(rsquoHomersquo =gt rsquoindexphprsquo
rsquoProduktersquo =gt rsquoproductsphprsquorsquoUumlber unsrsquo =gt rsquoaboutphprsquo
)foreach ($menu as $label =gt $link)
$url = trim($_SERVER[rsquoPHP_SELFrsquo] rsquorsquo)if ($link == $url)
echo rsquoltli class=activegtlta href=rsquo $link rsquogtrsquo $label rsquoltagtltligtrsquo else
echo rsquoltli class=gtlta href=rsquo $link rsquogtrsquo $label rsquoltagtltligtrsquo
gt
44 List of Products
The product overiew is a simple table The heading of the table is placed in an array
ltdivgtlttable class=table table-stripedgtltthead valign=bottomgtlttrgtltphp
$heading = array(rsquoTypersquo rsquoVariantrsquo rsquoColorrsquo rsquoHardnessrsquo rsquoPrice CHFrsquo)foreach ($heading as $element)
echo rsquoltth class=headgtrsquo$elementrsquoltthgtrsquon
gtlttrgtlttheadgtlttbody valign=topgtltphp
$products = array(array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquoHBrsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquoBrsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquo2Brsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquoFrsquo rsquo12rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquoHrsquo rsquo12rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquo2Hrsquo rsquo12rsquo)
)foreach ($products as $product =gt $details)
echo lttrgtforeach ($details as $detail)
echo lttdgt$detaillttdgtecho lttrgt
gtlttbodygtlttablegt
ltdivgt
14 Kapitel 4 Dynamics
Shop Documentation Release 001
45 Company details
The data for the About page are included out of a static and plain text file
ltphp$str = file_get_contents(companytxt)echo $str
gt
45 Company details 15
Shop Documentation Release 001
16 Kapitel 4 Dynamics
KAPITEL 5
External files
51 Navigation Menu
The menu is outsourced in the file menuphp
ltphpfunction menu()
$part1 = rsquoltul class=nav nav-tabsgtrsquon$part2 = rsquorsquo$part3 = rsquoltulgtrsquon Menu array with page title and assigned file$menu = array(rsquoHomersquo =gt rsquoindexphprsquo
rsquoProduktersquo =gt rsquoproductsphprsquorsquoUumlber unsrsquo =gt rsquoaboutphprsquo
)foreach ($menu as $label =gt $link)
For the CSS only the file name without is needed$url = trim($_SERVER[rsquoPHP_SELFrsquo] rsquorsquo)if ($link == $url)
$part2 = $part2ltli class=rsquoactiversquogtlta href=rsquo$linkrsquogt$labelltagtltligtn else
$part2 = $part2ltli class=rsquorsquogtlta href=rsquo$linkrsquogt$labelltagtltligtn
return $part1$part2$part3
gt
52 Header
The complete header part is loaded from the file headerphp
ltphpfunction head()
$start_page = indexphp$part1 = ltdivgtn$part2 = tlta class=rsquobrand-logorsquo href=rsquo$start_pagersquogtltagtn$part3 = tltp class=rsquobrand-namersquogtWebshop Pencil AGltpgtn$part4 = ltdivgtnreturn $part1$part2$part3$part4
17
Shop Documentation Release 001
gt
53 Footer
The same is done witht the page footers
ltphpfunction foot()
$class1 = rsquoltdiv class=footergtrsquon$class2 = rsquoltdivgtrsquon$text = ltpgtampcopy Pencil AG getYear()rsquoltpgtrsquonreturn $class1$text$class2
function getYear()return date(Y)
gt
18 Kapitel 5 External files
KAPITEL 6
Input processing
61 ldquoBuy Nowrdquo links
The ldquoBuy Nowrdquo links are attached to the Products page Every entry has itrsquos own link which lead to a detail page Thelinks are using hidden form elements to transfer the data
ltphp$products = array(array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquoHBrsquo rsquo1rsquo)
array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquoBrsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquo2Brsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquoFrsquo rsquo12rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquoHrsquo rsquo12rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquo2Hrsquo rsquo12rsquo)
)foreach ($products as $product =gt $details)
echo lttrgtnforeach ($details as $detail)
echo lttdgt$detaillttdgtnecho lttdgtnecho ltform action=rsquoproductphprsquo method=rsquogetrsquo name=rsquopencilrsquogtnecho ltinput type=rsquohiddenrsquo name=rsquotypersquo value=rsquo$details[0]rsquogtnecho ltinput type=rsquohiddenrsquo name=rsquooptionsrsquo value=rsquo$details[1]rsquogtnecho ltinput type=rsquohiddenrsquo name=rsquocolorrsquo value=rsquo$details[2]rsquogtnecho ltinput type=rsquohiddenrsquo name=rsquohardnessrsquo value=rsquo$details[3]rsquogtnecho ltinput type=rsquohiddenrsquo name=rsquopricersquo value=rsquo$details[4]rsquogtnecho ltinput type=rsquosubmitrsquo class=rsquobtn btn-defaultrsquo value=rsquoKauf michrsquogtnecho ltformgtnecho lttdgtnecho lttrgtn
gt
And the detail page contains the code fragement mentioned below
ltphp$type=$_GET[rsquotypersquo]$color=$_GET[rsquocolorrsquo]$hardness=$_GET[rsquohardnessrsquo]$options=$_GET[rsquooptionsrsquo]$price=$_GET[rsquopricersquo]echo I am a $type in $color and a hardness of $hardness I have $options as an option and my price is $price CHF
gt
19
Shop Documentation Release 001
Bemerkung The Products page was modified in the process of the development
62 Select options
The signupbilling page contains a dropdown element that all days of a month for the entry of the userrsquos birthday
ltselect name=daygtltoptiongtDayltoptiongt
ltphp$days = range(31 1)foreach ($days as $day)
echo rsquoltoption value=rsquo$dayrsquogtrsquo$dayrsquoltoptiongtrsquo
gtltselectgt
20 Kapitel 6 Input processing
KAPITEL 7
Javascript
Over the years Javascript became a very popular programming language The webshop is using Javascript at a coupleof places
71 Simple use case
Javascript makes it easy to access elements in the DOM Setting the focus is a nice way to support the user with inputform
ltscript language=javascriptgtfunction setFocus()
documentforms[login][username]focus()
ltscriptgtltheadgtltbody onload=setFocus()gt
Another one is to check if something was entered in an input field
function validateForm() var username = documentforms[rdquologinrdquo][rdquousernamerdquo]value if (username== null || username == ldquordquo)
documentforms[rdquologinrdquo][rdquousernamerdquo]stylebackgroundColor = ldquoFF9999rdquo docu-mentforms[rdquologinrdquo][rdquousernamerdquo]placeholder = ldquoPlease your usernamerdquo docu-mentforms[rdquologinrdquo][rdquousernamerdquo]focus() return false
A simple message is informing the user about an action which was taken against the database
echo ltscript type=textjavascriptgtalert(New entry $entry added successfully)windowlocation = tablesphp
ltscriptgt
The delete process is only executed if the user confirm to delete a record
ltform action=scriptsdelete-processphp onSubmit=return confirm(rsquoAre you sure to delete this entryrsquo) method=POSTgtltinput type=hidden name=table value=$sectiongtltinput type=hidden name=id value=$result-gtidgtltinput type=submit name=Submit value=Deletegt
ltformgt
For additional Javascript please check the source of the indexphp file and the reflsquowebservicelsquo_ section
21
Shop Documentation Release 001
22 Kapitel 7 Javascript
KAPITEL 8
Cookies and Sessions
The built-in support for sessions in PHP is handling all cookie manipulation to provide persistent variables that areaccessible from different pages and across multiple visits to the site
81 Cookies
A cookie is used to track the last time a visitor check the front page The cookie is set when a visitor arrives
function lastVisit($name $expire) $value = getDateDMY() - getTimeHM()setcookie($name $value time() + $expire rsquorsquo $_SERVER[rsquoSERVER_NAMErsquo] true true)
In the footer of the index page the details are presented
ltphpif(isset($_COOKIE[rsquoLastVisitrsquo]))
$last = $_COOKIE[rsquoLastVisitrsquo]echo You last visited us on $last
else echo This is your first visit
gt
82 Hit counter
As a simple show case for PHP sessions a hit counter for the front page is available
ltphpsession_start()
$_SESSION[rsquohitsrsquo] = $_SESSION[rsquohitsrsquo] + 1gt
Included in the footer it shous the users the total of visits
echo Total $_SESSION[rsquohitsrsquo] visits of this page
23
Shop Documentation Release 001
83 Language selection
84 User Accounts
24 Kapitel 8 Cookies and Sessions
KAPITEL 9
Database
The database backend for the webshop will be MariaDB which is the drop-in replacement for MySQL
For the setup please check the Development section in this documentation
91 Tables
The following tables are needed for the webshop to work
bull products
bull customers
bull pencils
bull colors
bull hardness
bull options
bull users
Please use the develwebshopsql to setup the database
92 PHP
Below you find the configuration file for a default installation of the webshop This file is a template and filled duringthe setup process
ltphp$host = localhost$user = root$password = webshop$dbase = webshop$connection = new mysqli($host $user $password $dbase)
if ($connection-gtconnect_errno) echo Failed to connect to MariaDBMySQL ($connection-gtconnect_errno) $connection-gtconnect_error
mysqli_report(MYSQLI_REPORT_ERROR)
gt
25
Shop Documentation Release 001
All connections to the database are done in the same way Below you find an example Everything is done in theobject-oriented style
ltphprequire_once(rsquoconfigdbconnectphprsquo)if ($connection-gtconnect_errno == 0)
$sql = SELECT FROM products$results = $connection-gtquery($sql)echo $results-gtnum_rows$results-gtclose()
else echo Database connection error
gt
26 Kapitel 9 Database
KAPITEL 10
Web service
Tow web services are integrated to take advantages of online available data sources
101 Map
Leafletjs a JavaScript library for working with interactive maps from OpenStreetMap (OSM) is implemented as ashow case for a simple web service
The basic steps to integrate a map is shown below
ltdiv id=map class=map style=width 600px height 400pxgtltdivgt
ltscript src=scriptsleafletjsgtltscriptgtltscript src=scriptsleaflet-providersjsgtltscriptgtltscriptgtvar map = Lmap(rsquomaprsquo
center [250472 -773255]zoom 12zoomControl true
)
var defaultLayer = LtileLayerprovider(rsquoOpenStreetMapMapnikrsquo)addTo(map)ltscriptgt
102 Weather
The OpenWeatherMap service provides free weather data and a forecast API for web applications
ltphp Details about the API httpbugsopenweathermaporgprojectsapiwikiApi_2_5_weather$url = rsquohttpapiopenweathermaporgdata25weatherq=Bernechampunit=metricsampmode=jsonrsquo
$json = file_get_contents($url)$data = json_decode($json)
$tempC = round((27315 - $data-gtmain-gttemp)100) 100$humidity = $data-gtmain-gthumidity$pressure = $data-gtmain-gtpressure
27
Shop Documentation Release 001
echo ltpgtTemperatur $tempC degCltbrgtnecho Luftfeuchtigkeit $humidity ltbrgtnecho Luftdruck $pressure Paltpgtn
gt
28 Kapitel 10 Web service
KAPITEL 11
Data export
111 PDF
FPDF is a PHP class that allows to generate PDF files with pure PHP As a showcase for that the product specificationsfor a given product are filled in a pdf and showed in the browser The user can then decide to download or print thefile
112 JSON
JavaScript Object Notation (JSON) is a lightweight data-interchange format The format is language independent andPHP support the encoding and the decoding JSON with json_encode($data) and json_decode($data)$rows = array()$sql = SELECT FROM products$results = $connection-gtquery($sql)while ($result = $results-gtfetch_object())
$rows[] = $result$results-gtclose()
Writing all rows to a JSON file$fp = fopen(rsquopencilsjsonrsquo rsquowrsquo)fwrite($fp json_encode($rows))fclose($fp)gt
and for reading it
ltphp$json = file_get_contents(rsquopencilsjsonrsquo)print_r(json_decode($json))
gt
29
Shop Documentation Release 001
30 Kapitel 11 Data export
KAPITEL 12
Messaging
Beside standard email messages the webshop supports sending MQ Telemetry Transport protocol (MQTT) messagesas an additional feature The MQTT messages are small
121 MQTT
Mosquitto-PHP is used as a PHP wrapper for MQTT Please check the Projectrsquos README for details about theinstallation and the setup
1211 Broker
Mosquitto is a message broker that implements the MQ Telemetry Transport protocol Check if mosquitto is run-ning
$ sudo systemctl status mosquittoservice
If not start it
$ systemctl start mosquittoservice
All messages are published to the topic webshop
1212 Publishing
After the installation of Mosquitto-PHP the snipplet shown below sends a single message
ltphpdefine(rsquoBROKERrsquo rsquolocalhostrsquo)define(rsquoPORTrsquo 1883)define(rsquoCLIENT_IDrsquo webshop_ + getmypid())$topic = webshop$subtopic = test$completeTopic = $topic$subtopic
$client = new MosquittoClient(CLIENT_ID)$client-gtconnect(BROKER PORT 60)
$message = Test message from webshop at date(Y-m-d His)$client-gtpublish($completeTopic $message 0 false)
gt
31
Shop Documentation Release 001
1213 Subscribing
To read the messages sent by the webshop a client is needed The Mosquitto broker contain a simple command-linetool for subscribing to various topics
$ mosquitto_sub -h localhost -t webshop
122 Email
This section doesnrsquot describe the installation and configuration of a local MTA There are enough resources thatcontains information about the setup of postfix for local delivery only
If you want to test the email feature add the following code in one of PHP pages
ltphp mail(rsquorootlocalhostrsquo rsquoTest message from webshoprsquo rsquoThe webshop is selling pencilsrsquo) gt
By default SELinux is running in Enforcing mode which is restrictive about about what a web server can do Toallow sending email the following SELinux boolean needs to changed
setsebool -P httpd_can_network_connect=1 setsebool -P httpd_can_sendmail=1
32 Kapitel 12 Messaging
KAPITEL 13
Localisation (L10n)
There are several ways to add localisation to a web site For small projects arrays with string can work but this is notvery efficient and user-friendly With Gettext is a toolset available that provide a framework to produce multi-lingualcontent in a wide area of programming languages
Make sure that the php-gettext package is available on your system If not install it
$ sudo yum -y install php-php-gettext
Check if gettext support is available
ltphpif (function_exists(gettext))
echo gettext is not installednelse
echo gettext is supportedn
gt
Make sure that all locales your want are available on the server
locale -a
The first step is to mark all string which should be translatable as shown below For further details please refer to theGettext documentation
echo _(rsquoSome textrsquo)
The next step is to extract all strings
xgettext --from-code=UTF-8 -o localewebshoppot php scriptsphp
To re-generate the file after an update join the strings
xgettext -j --from-code=UTF-8 -o localewebshoppot php scriptsphp
For every language a po file is needed for the transations Generate it with the command mentioned below
msginit --no-translator -l de_CH -o localede_CHpo -i localewebshoppot
Once created there are only updates of the message catalog needed in the futures
msgmerge -U localede_CHpo localewebshoppot
If you re finish create the mo file for the specific language
33
Shop Documentation Release 001
msgfmt -c -v -o localede_CHLC_MESSAGESwebshopmo localede_CHpo
34 Kapitel 13 Localisation (L10n)
KAPITEL 14
Templates
Beside other solutions Savant3 is a lightweight object-oriented template system for PHP This solution does not needa lot of additional configuration
141 Template
A simple template file looks like the one shown below
lthtmlgtltheadgt
lttitlegtltphp echo $this-gteprint($this-gttitle) gtlttitlegtltheadgtltbodygt
ltphp echo $this-gteprint($this-gtcontent) gtltbodygt
lthtmlgt
For a more detailed intro check this article on Zend Developer Zone
142 Content
To fill the template with data all wished variables needs to be defined in a seperate PHP file
ltphprequire_once rsquoscriptsSavant3phprsquo$tpl = new Savant3()
Create a title$title = Simple sample page
Create the content of the page$content = Some sample text to show
Assign values to the Savant instance$tpl-gttitle = $title$tpl-gtcontent = $content
Define the template source file to show$tpl-gtdisplay(rsquosimpletplphprsquo)
gt
35
Shop Documentation Release 001
The webshop contains a page (master)
36 Kapitel 14 Templates
KAPITEL 15
Development
This sections describes the configuration of the development and runtime environment for the web shop
151 Web server
Instead of Apache the project is running on Lighttpd The reasons are that Lighttpd provides faster setup easierconfiguration and better performance Lighttpd is running with FastCGI
The path of the web server is varwwwlighttpd and the SELinux configuration are still the defaults
The web server is running in SSL-only mode and the certificate is generated during the server setup process
152 Database server
For persistence storage the drop-in replacement MariaDB is used MySQL will work to but this is not tested phpMyAd-min is available under phpmyadmin on the web server beside the command-line tools for easy administration
The default credentials for phpMyAdmin are rootwebshop or the entry you made in the Ansible playbookdevelvariablessensitiveyml
153 Versions
The web shop is built with the below listed components and tested Other releases can be used and may work but thiswill not be tested Probably it will work with different releases
bull Operating system Fedora 20
bull Kernel 3135-202fc20x86_64
bull Lighttpd 1434
bull PHP 557
bull MariaDB 5534
For communication postfix and mosquitto are needed additionally
37
Shop Documentation Release 001
154 Setup infrastructure
1541 Configuration management
For the creation of reproducable and identical environment for the development and the run-time across differentsystems Ansible is used as configuration management solution All needed steps of the installation are automated Theconfiguration doesnrsquot differentiate between local or remote installations This matters only for the deployment of theweb content
For local development itrsquos possible to use an LX container
$ sudo ansible-playbook develcontaineryml
To get everything running some additional steps (check the network inside the container generate keys etc) areneeded After you are done check it
$ sudo ansible webshop -m setup
From the management system
$ sudo ssh-copy-id -i rootsshid_rsapub root[IP address of your managed node]
The configuration of Ansible itself (adding the system to etcansiblehosts and copying the SSH keys) isnot documented at this place There are various resources available like here All playbooks are located in the folderdevel Start the setup with the command shown below
$ sudo ansible-playbook develsetupyml
The used group name in etcansiblehosts is webshop
If the setup completes without errors then the web server is accessible and show a default page Please keep in mindthat the server is only accessible over https unencrypted traffic is not allowed
1542 DeploymentSetup website
For the simple deployment of the lastest version of the shop a playbook called deployyml is provided Thisplaybook put all files in place
$ sudo ansible-playbook develdeployyml
To full deploy the webshop all tables in the database must exist The file webshopsql contains all needed SQLcommands and sample data for the web application
Itrsquos possible to deploy the website manually but this is not recommended A couple of files are depending on templateswhich are created during the deployment
Itrsquos also not recommanded to clone everything into your webserver root This would save you the trouble of doing itby hand but third-party features are missing then Those missing parts are the template engine the pdf generation theconnection to Openstreetmap and probably other things not mentioned here
155 Git respository
All project relevante informations (Source code templates documentation etc) is located in a public Git repositoryon Github
38 Kapitel 15 Development
Shop Documentation Release 001
156 Documentation
The documentation is using reStructuredText as markup language For a local build Sphinx is needed Sphinx isavailable in the Fedora Package Collection and can be installed with yum or any other package management tool
yum -y install python-sphinx python-docutils
The source files of the documentation are located under docs
$ cd docs$ make html
The output is stored under docs_buildhtml
After every push to Github a hook launch a rebuild of the documentation The latest release will be published on Readthe Docs automatically
httpsshoprtfdorg
156 Documentation 39
Shop Documentation Release 001
40 Kapitel 15 Development
KAPITEL 16
Indices and tables
bull genindex
bull modindex
bull search
41
- Basics
-
- Products
- Personas
- Use cases
- Design principles
-
- Web shop Design
-
- General
- Layout
- Sitemap
- Main page
-
- Style and design
-
- Cascading Style Sheets
- Pages
-
- Dynamics
-
- Setup
- Current year
- Navigation Menu
- List of Products
- Company details
-
- External files
-
- Navigation Menu
- Header
- Footer
-
- Input processing
-
- ``Buy Now links
- Select options
-
- Javascript
-
- Simple use case
-
- Cookies and Sessions
-
- Cookies
- Hit counter
- Language selection
- User Accounts
-
- Database
-
- Tables
- PHP
-
- Web service
-
- Map
- Weather
-
- Data export
-
- JSON
-
- Messaging
-
- MQTT
-
- Localisation (L10n)
- Templates
-
- Template
- Content
-
- Development
-
- Web server
- Database server
- Versions
- Setup infrastructure
- Git respository
- Documentation
-
- Indices and tables
-
84 User Accounts 24
9 Database 2591 Tables 2592 PHP 25
10 Web service 27101 Map 27102 Weather 27
11 Data export 29111 PDF 29112 JSON 29
12 Messaging 31121 MQTT 31122 Email 32
13 Localisation (L10n) 33
14 Templates 35141 Template 35142 Content 35
15 Development 37151 Web server 37152 Database server 37153 Versions 37154 Setup infrastructure 38155 Git respository 38156 Documentation 39
16 Indices and tables 41
ii
Shop Documentation Release 001
This is the documentation of the genesi of a web shop It describes the taken steps and the features The code is notproduction-ready but shows at various locations different way to do things
Contents
Inhaltsverzeichnis 1
Shop Documentation Release 001
2 Inhaltsverzeichnis
KAPITEL 1
Basics
11 Products
The Web shop will be for selling pencils in various types
Categories
bull Standard pencils
bull Mechnical pencils
bull Special pencils
Variants or options
bull Color (red yellow black white etc)
bull Hardness (standard HB hard F H 2H soft B 2B)
bull Additional function (Eraser at the end Protection cap handle)
111 Product overview
(The product names are in German because the main language of the shop will not be English)
3
Shop Documentation Release 001
Type Variant Color Hardness Price CHFBleistift keine rot HB 1Bleistift keine rot B 1Bleistift keine rot 2B 1Bleistift keine gelb F 120Bleistift keine gelb H 120Bleistift keine gelb 2H 120Bleistift Gummi rot HB 110Schreiner-Bleistift keine rot HB 180Schreiner-Bleistift keine rot B 180Bleistift keine rot HB 05Bleistift Gummi rot HB 06Kuumlnstler-Bleistift Griff gelb 2B 2Kuumlnstler-Bleistift Griff rot 2B 2Kuumlnstler-Bleistift Griff schwarz 2B 2Minien-Bleistift keine weiss 4Minien-Bleistift keine blau 4Minien-Bleistift keine gelb 4Minien-Bleistift keine rot 4Minien-Bleistift keine silber 9Minien-Bleistift keine schwarz 9
12 Personas
The following personas are defined to interact with the web shop
121 Major customer
Eva is responsible for the ordering of office supplies in her joinery She is ordering twice a month a large amount ofvarious product for different users (management back office and production) Eva has a fix budget for the orders andshe knows her way around web shops
122 End user
Hugo is an architect and middle aged He is drawing sketches and technical drawings but also artistically demandingpieces by hand Thanks to the work with CAD he decovers the web and its advantages Before he bought all his toolsin a local stationery nowadays he is ordering stuff online
13 Use cases
The shop will be stripped-down to two use cases With those use cases are all major use cases with only little modifi-cations covered The use cases for the shop adimistration will be considered out of scope
131 Major customer
bull Ordering of a large amount of one single products or several products
bull Volume discount
4 Kapitel 1 Basics
Shop Documentation Release 001
bull Splitting of oders (ev delivery to different locations)
132 End user
bull Ordering of single products
bull Small quantities
14 Design principles
The below listed points are the fundation for the implementation of the design and the layout to the shop
bull Products should be in the spot light
bull Reduced to the essentials (typography colors fonts etc)
bull meaningful use of whitespaces
Instead of reinventing the wheel it should be considered to use a matured front-end framework like bootstrap for thelayout especially regarding responsive design
14 Design principles 5
Shop Documentation Release 001
6 Kapitel 1 Basics
KAPITEL 2
Web shop Design
21 General
The used company and all data are notional There is no exisiting connection to any existing company with the sameor similar name
211 Company name
The company name is Pencil AG
212 Address
The complete address of the company is
Pencil AGMusterstrasse 13000 BernSchweiz
213 Logo
The logo used in this project is borrowed from the Tango project icon set The file is out of the categories section thefile name of the origin file is applications-officesvg and is licensed under Public Domain
22 Layout
The layout is splitted in different sections The content of the elements especially of the main section (content) willbe definied by the later usage of the page
7
Shop Documentation Release 001
23 Sitemap
The sitemap shows the clustering of the shop at the beginning of the project
This doesnrsquot mean that everything will be done Static pages are easy to make and to maintain
8 Kapitel 2 Web shop Design
Shop Documentation Release 001
24 Main page
The first draft of the main page is based on the prototype shown in section Layout without any format- und styleinformationen
ltDOCTYPE htmlgtlthtml lang=engt
ltheadgtltmeta charset=utf-8gtltmeta name=viewport content=width=device-width initial-scale=10gtltmeta name=description content=Webshop Pencil AG fuumlr Bleistiftegtltmeta name=author content=Fabian AffoltergtlttitlegtWebshop Pencil AG | Homelttitlegt
ltheadgt
ltbodygtlt-- Header container--gtltdivgt
ltdivgtlt-- Logo and company name --gtltimg src=logologopnggtlth2gtWebshop Pencil AGlth2gtlt-- Navigation --gtltulgt
ltligtlta href=gtHomeltagtltligtltligtlta href=gtProdukteltagtltligtltligtlta href=gtUumlber unsltagtltligt
ltulgtlt-- Breadcrumb --gtltolgt
ltligtlta href=gtEbene 1ltagtltligtltligtlta href=gtEbene 2ltagtltligtltligtlta href=gtEbene 3ltagtltligt
ltolgtltdivgt
ltdivgtlt-- Header container--gt
lt-- Action container --gtltdivgt
lth1gtWochen-Aktionlth1gtltpgtDies ist eine super Aktion 10 Bleistifte fuumlr CHF 8ltpgt
ltdivgtlt-- Action container --gt
lt-- Selected products --gtltdivgt
ltpgtHier hat es zufaumlllige Produkteltpgtltdivgtlt-- Selected products --gt
lt-- Footer --gtltdivgt
ltpgtampcopy Pencil AG 2013ltpgtlt-- Footer --gtltdivgt
ltbodygtlthtmlgt
24 Main page 9
Shop Documentation Release 001
Loaded in a browser the initial draft of the main page looks like in the following screenshot
10 Kapitel 2 Web shop Design
KAPITEL 3
Style and design
31 Cascading Style Sheets
The design of the shop will be nothing fancy The approach which was choosen will reflect the points mentioned inthe Design principles section and makes heavy use of the bootstrap framework cascading style sheet Various changesto this CSS file ensure that it matche the needs of this project
32 Pages
The product page show the elements mentioned in the Product overview section
11
Shop Documentation Release 001
12 Kapitel 3 Style and design
KAPITEL 4
Dynamics
The webshop will be a PHP application at the end Those first steps are only covering the very basic stuff of PHP asan introduction
41 Setup
The setupyml playbook puts a simple PHP file in the root directory of the web server with the namephpinfophp This file displays PHP details
Achtung Remove this file before makeing the shop accessible by a public audience
42 Current year
The first PHP element in the webshop is showing the current year in the footer of every page With the help of thislittle piece of code there is no longer a need to update the year
ltphp echo date(Y) gt
43 Navigation Menu
The basic menu was built with the following snippet
ltphp$menu = array(rsquoHomersquo =gt rsquoindexphprsquo
rsquoProduktersquo =gt rsquoproductsphprsquorsquoUumlber unsrsquo =gt rsquoaboutphprsquo
)foreach($menu as $label =gt $link)
echo rsquoltligtlta href=rsquo $link rsquogtrsquo $label rsquoltagtltligtrsquo
gt
The issue with that snippet was that the CSS class was missing In regards to a future separation and reusability anadditional statements was added This way the label of the active page is highlighted
13
Shop Documentation Release 001
ltphp$menu = array(rsquoHomersquo =gt rsquoindexphprsquo
rsquoProduktersquo =gt rsquoproductsphprsquorsquoUumlber unsrsquo =gt rsquoaboutphprsquo
)foreach ($menu as $label =gt $link)
$url = trim($_SERVER[rsquoPHP_SELFrsquo] rsquorsquo)if ($link == $url)
echo rsquoltli class=activegtlta href=rsquo $link rsquogtrsquo $label rsquoltagtltligtrsquo else
echo rsquoltli class=gtlta href=rsquo $link rsquogtrsquo $label rsquoltagtltligtrsquo
gt
44 List of Products
The product overiew is a simple table The heading of the table is placed in an array
ltdivgtlttable class=table table-stripedgtltthead valign=bottomgtlttrgtltphp
$heading = array(rsquoTypersquo rsquoVariantrsquo rsquoColorrsquo rsquoHardnessrsquo rsquoPrice CHFrsquo)foreach ($heading as $element)
echo rsquoltth class=headgtrsquo$elementrsquoltthgtrsquon
gtlttrgtlttheadgtlttbody valign=topgtltphp
$products = array(array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquoHBrsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquoBrsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquo2Brsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquoFrsquo rsquo12rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquoHrsquo rsquo12rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquo2Hrsquo rsquo12rsquo)
)foreach ($products as $product =gt $details)
echo lttrgtforeach ($details as $detail)
echo lttdgt$detaillttdgtecho lttrgt
gtlttbodygtlttablegt
ltdivgt
14 Kapitel 4 Dynamics
Shop Documentation Release 001
45 Company details
The data for the About page are included out of a static and plain text file
ltphp$str = file_get_contents(companytxt)echo $str
gt
45 Company details 15
Shop Documentation Release 001
16 Kapitel 4 Dynamics
KAPITEL 5
External files
51 Navigation Menu
The menu is outsourced in the file menuphp
ltphpfunction menu()
$part1 = rsquoltul class=nav nav-tabsgtrsquon$part2 = rsquorsquo$part3 = rsquoltulgtrsquon Menu array with page title and assigned file$menu = array(rsquoHomersquo =gt rsquoindexphprsquo
rsquoProduktersquo =gt rsquoproductsphprsquorsquoUumlber unsrsquo =gt rsquoaboutphprsquo
)foreach ($menu as $label =gt $link)
For the CSS only the file name without is needed$url = trim($_SERVER[rsquoPHP_SELFrsquo] rsquorsquo)if ($link == $url)
$part2 = $part2ltli class=rsquoactiversquogtlta href=rsquo$linkrsquogt$labelltagtltligtn else
$part2 = $part2ltli class=rsquorsquogtlta href=rsquo$linkrsquogt$labelltagtltligtn
return $part1$part2$part3
gt
52 Header
The complete header part is loaded from the file headerphp
ltphpfunction head()
$start_page = indexphp$part1 = ltdivgtn$part2 = tlta class=rsquobrand-logorsquo href=rsquo$start_pagersquogtltagtn$part3 = tltp class=rsquobrand-namersquogtWebshop Pencil AGltpgtn$part4 = ltdivgtnreturn $part1$part2$part3$part4
17
Shop Documentation Release 001
gt
53 Footer
The same is done witht the page footers
ltphpfunction foot()
$class1 = rsquoltdiv class=footergtrsquon$class2 = rsquoltdivgtrsquon$text = ltpgtampcopy Pencil AG getYear()rsquoltpgtrsquonreturn $class1$text$class2
function getYear()return date(Y)
gt
18 Kapitel 5 External files
KAPITEL 6
Input processing
61 ldquoBuy Nowrdquo links
The ldquoBuy Nowrdquo links are attached to the Products page Every entry has itrsquos own link which lead to a detail page Thelinks are using hidden form elements to transfer the data
ltphp$products = array(array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquoHBrsquo rsquo1rsquo)
array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquoBrsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquo2Brsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquoFrsquo rsquo12rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquoHrsquo rsquo12rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquo2Hrsquo rsquo12rsquo)
)foreach ($products as $product =gt $details)
echo lttrgtnforeach ($details as $detail)
echo lttdgt$detaillttdgtnecho lttdgtnecho ltform action=rsquoproductphprsquo method=rsquogetrsquo name=rsquopencilrsquogtnecho ltinput type=rsquohiddenrsquo name=rsquotypersquo value=rsquo$details[0]rsquogtnecho ltinput type=rsquohiddenrsquo name=rsquooptionsrsquo value=rsquo$details[1]rsquogtnecho ltinput type=rsquohiddenrsquo name=rsquocolorrsquo value=rsquo$details[2]rsquogtnecho ltinput type=rsquohiddenrsquo name=rsquohardnessrsquo value=rsquo$details[3]rsquogtnecho ltinput type=rsquohiddenrsquo name=rsquopricersquo value=rsquo$details[4]rsquogtnecho ltinput type=rsquosubmitrsquo class=rsquobtn btn-defaultrsquo value=rsquoKauf michrsquogtnecho ltformgtnecho lttdgtnecho lttrgtn
gt
And the detail page contains the code fragement mentioned below
ltphp$type=$_GET[rsquotypersquo]$color=$_GET[rsquocolorrsquo]$hardness=$_GET[rsquohardnessrsquo]$options=$_GET[rsquooptionsrsquo]$price=$_GET[rsquopricersquo]echo I am a $type in $color and a hardness of $hardness I have $options as an option and my price is $price CHF
gt
19
Shop Documentation Release 001
Bemerkung The Products page was modified in the process of the development
62 Select options
The signupbilling page contains a dropdown element that all days of a month for the entry of the userrsquos birthday
ltselect name=daygtltoptiongtDayltoptiongt
ltphp$days = range(31 1)foreach ($days as $day)
echo rsquoltoption value=rsquo$dayrsquogtrsquo$dayrsquoltoptiongtrsquo
gtltselectgt
20 Kapitel 6 Input processing
KAPITEL 7
Javascript
Over the years Javascript became a very popular programming language The webshop is using Javascript at a coupleof places
71 Simple use case
Javascript makes it easy to access elements in the DOM Setting the focus is a nice way to support the user with inputform
ltscript language=javascriptgtfunction setFocus()
documentforms[login][username]focus()
ltscriptgtltheadgtltbody onload=setFocus()gt
Another one is to check if something was entered in an input field
function validateForm() var username = documentforms[rdquologinrdquo][rdquousernamerdquo]value if (username== null || username == ldquordquo)
documentforms[rdquologinrdquo][rdquousernamerdquo]stylebackgroundColor = ldquoFF9999rdquo docu-mentforms[rdquologinrdquo][rdquousernamerdquo]placeholder = ldquoPlease your usernamerdquo docu-mentforms[rdquologinrdquo][rdquousernamerdquo]focus() return false
A simple message is informing the user about an action which was taken against the database
echo ltscript type=textjavascriptgtalert(New entry $entry added successfully)windowlocation = tablesphp
ltscriptgt
The delete process is only executed if the user confirm to delete a record
ltform action=scriptsdelete-processphp onSubmit=return confirm(rsquoAre you sure to delete this entryrsquo) method=POSTgtltinput type=hidden name=table value=$sectiongtltinput type=hidden name=id value=$result-gtidgtltinput type=submit name=Submit value=Deletegt
ltformgt
For additional Javascript please check the source of the indexphp file and the reflsquowebservicelsquo_ section
21
Shop Documentation Release 001
22 Kapitel 7 Javascript
KAPITEL 8
Cookies and Sessions
The built-in support for sessions in PHP is handling all cookie manipulation to provide persistent variables that areaccessible from different pages and across multiple visits to the site
81 Cookies
A cookie is used to track the last time a visitor check the front page The cookie is set when a visitor arrives
function lastVisit($name $expire) $value = getDateDMY() - getTimeHM()setcookie($name $value time() + $expire rsquorsquo $_SERVER[rsquoSERVER_NAMErsquo] true true)
In the footer of the index page the details are presented
ltphpif(isset($_COOKIE[rsquoLastVisitrsquo]))
$last = $_COOKIE[rsquoLastVisitrsquo]echo You last visited us on $last
else echo This is your first visit
gt
82 Hit counter
As a simple show case for PHP sessions a hit counter for the front page is available
ltphpsession_start()
$_SESSION[rsquohitsrsquo] = $_SESSION[rsquohitsrsquo] + 1gt
Included in the footer it shous the users the total of visits
echo Total $_SESSION[rsquohitsrsquo] visits of this page
23
Shop Documentation Release 001
83 Language selection
84 User Accounts
24 Kapitel 8 Cookies and Sessions
KAPITEL 9
Database
The database backend for the webshop will be MariaDB which is the drop-in replacement for MySQL
For the setup please check the Development section in this documentation
91 Tables
The following tables are needed for the webshop to work
bull products
bull customers
bull pencils
bull colors
bull hardness
bull options
bull users
Please use the develwebshopsql to setup the database
92 PHP
Below you find the configuration file for a default installation of the webshop This file is a template and filled duringthe setup process
ltphp$host = localhost$user = root$password = webshop$dbase = webshop$connection = new mysqli($host $user $password $dbase)
if ($connection-gtconnect_errno) echo Failed to connect to MariaDBMySQL ($connection-gtconnect_errno) $connection-gtconnect_error
mysqli_report(MYSQLI_REPORT_ERROR)
gt
25
Shop Documentation Release 001
All connections to the database are done in the same way Below you find an example Everything is done in theobject-oriented style
ltphprequire_once(rsquoconfigdbconnectphprsquo)if ($connection-gtconnect_errno == 0)
$sql = SELECT FROM products$results = $connection-gtquery($sql)echo $results-gtnum_rows$results-gtclose()
else echo Database connection error
gt
26 Kapitel 9 Database
KAPITEL 10
Web service
Tow web services are integrated to take advantages of online available data sources
101 Map
Leafletjs a JavaScript library for working with interactive maps from OpenStreetMap (OSM) is implemented as ashow case for a simple web service
The basic steps to integrate a map is shown below
ltdiv id=map class=map style=width 600px height 400pxgtltdivgt
ltscript src=scriptsleafletjsgtltscriptgtltscript src=scriptsleaflet-providersjsgtltscriptgtltscriptgtvar map = Lmap(rsquomaprsquo
center [250472 -773255]zoom 12zoomControl true
)
var defaultLayer = LtileLayerprovider(rsquoOpenStreetMapMapnikrsquo)addTo(map)ltscriptgt
102 Weather
The OpenWeatherMap service provides free weather data and a forecast API for web applications
ltphp Details about the API httpbugsopenweathermaporgprojectsapiwikiApi_2_5_weather$url = rsquohttpapiopenweathermaporgdata25weatherq=Bernechampunit=metricsampmode=jsonrsquo
$json = file_get_contents($url)$data = json_decode($json)
$tempC = round((27315 - $data-gtmain-gttemp)100) 100$humidity = $data-gtmain-gthumidity$pressure = $data-gtmain-gtpressure
27
Shop Documentation Release 001
echo ltpgtTemperatur $tempC degCltbrgtnecho Luftfeuchtigkeit $humidity ltbrgtnecho Luftdruck $pressure Paltpgtn
gt
28 Kapitel 10 Web service
KAPITEL 11
Data export
111 PDF
FPDF is a PHP class that allows to generate PDF files with pure PHP As a showcase for that the product specificationsfor a given product are filled in a pdf and showed in the browser The user can then decide to download or print thefile
112 JSON
JavaScript Object Notation (JSON) is a lightweight data-interchange format The format is language independent andPHP support the encoding and the decoding JSON with json_encode($data) and json_decode($data)$rows = array()$sql = SELECT FROM products$results = $connection-gtquery($sql)while ($result = $results-gtfetch_object())
$rows[] = $result$results-gtclose()
Writing all rows to a JSON file$fp = fopen(rsquopencilsjsonrsquo rsquowrsquo)fwrite($fp json_encode($rows))fclose($fp)gt
and for reading it
ltphp$json = file_get_contents(rsquopencilsjsonrsquo)print_r(json_decode($json))
gt
29
Shop Documentation Release 001
30 Kapitel 11 Data export
KAPITEL 12
Messaging
Beside standard email messages the webshop supports sending MQ Telemetry Transport protocol (MQTT) messagesas an additional feature The MQTT messages are small
121 MQTT
Mosquitto-PHP is used as a PHP wrapper for MQTT Please check the Projectrsquos README for details about theinstallation and the setup
1211 Broker
Mosquitto is a message broker that implements the MQ Telemetry Transport protocol Check if mosquitto is run-ning
$ sudo systemctl status mosquittoservice
If not start it
$ systemctl start mosquittoservice
All messages are published to the topic webshop
1212 Publishing
After the installation of Mosquitto-PHP the snipplet shown below sends a single message
ltphpdefine(rsquoBROKERrsquo rsquolocalhostrsquo)define(rsquoPORTrsquo 1883)define(rsquoCLIENT_IDrsquo webshop_ + getmypid())$topic = webshop$subtopic = test$completeTopic = $topic$subtopic
$client = new MosquittoClient(CLIENT_ID)$client-gtconnect(BROKER PORT 60)
$message = Test message from webshop at date(Y-m-d His)$client-gtpublish($completeTopic $message 0 false)
gt
31
Shop Documentation Release 001
1213 Subscribing
To read the messages sent by the webshop a client is needed The Mosquitto broker contain a simple command-linetool for subscribing to various topics
$ mosquitto_sub -h localhost -t webshop
122 Email
This section doesnrsquot describe the installation and configuration of a local MTA There are enough resources thatcontains information about the setup of postfix for local delivery only
If you want to test the email feature add the following code in one of PHP pages
ltphp mail(rsquorootlocalhostrsquo rsquoTest message from webshoprsquo rsquoThe webshop is selling pencilsrsquo) gt
By default SELinux is running in Enforcing mode which is restrictive about about what a web server can do Toallow sending email the following SELinux boolean needs to changed
setsebool -P httpd_can_network_connect=1 setsebool -P httpd_can_sendmail=1
32 Kapitel 12 Messaging
KAPITEL 13
Localisation (L10n)
There are several ways to add localisation to a web site For small projects arrays with string can work but this is notvery efficient and user-friendly With Gettext is a toolset available that provide a framework to produce multi-lingualcontent in a wide area of programming languages
Make sure that the php-gettext package is available on your system If not install it
$ sudo yum -y install php-php-gettext
Check if gettext support is available
ltphpif (function_exists(gettext))
echo gettext is not installednelse
echo gettext is supportedn
gt
Make sure that all locales your want are available on the server
locale -a
The first step is to mark all string which should be translatable as shown below For further details please refer to theGettext documentation
echo _(rsquoSome textrsquo)
The next step is to extract all strings
xgettext --from-code=UTF-8 -o localewebshoppot php scriptsphp
To re-generate the file after an update join the strings
xgettext -j --from-code=UTF-8 -o localewebshoppot php scriptsphp
For every language a po file is needed for the transations Generate it with the command mentioned below
msginit --no-translator -l de_CH -o localede_CHpo -i localewebshoppot
Once created there are only updates of the message catalog needed in the futures
msgmerge -U localede_CHpo localewebshoppot
If you re finish create the mo file for the specific language
33
Shop Documentation Release 001
msgfmt -c -v -o localede_CHLC_MESSAGESwebshopmo localede_CHpo
34 Kapitel 13 Localisation (L10n)
KAPITEL 14
Templates
Beside other solutions Savant3 is a lightweight object-oriented template system for PHP This solution does not needa lot of additional configuration
141 Template
A simple template file looks like the one shown below
lthtmlgtltheadgt
lttitlegtltphp echo $this-gteprint($this-gttitle) gtlttitlegtltheadgtltbodygt
ltphp echo $this-gteprint($this-gtcontent) gtltbodygt
lthtmlgt
For a more detailed intro check this article on Zend Developer Zone
142 Content
To fill the template with data all wished variables needs to be defined in a seperate PHP file
ltphprequire_once rsquoscriptsSavant3phprsquo$tpl = new Savant3()
Create a title$title = Simple sample page
Create the content of the page$content = Some sample text to show
Assign values to the Savant instance$tpl-gttitle = $title$tpl-gtcontent = $content
Define the template source file to show$tpl-gtdisplay(rsquosimpletplphprsquo)
gt
35
Shop Documentation Release 001
The webshop contains a page (master)
36 Kapitel 14 Templates
KAPITEL 15
Development
This sections describes the configuration of the development and runtime environment for the web shop
151 Web server
Instead of Apache the project is running on Lighttpd The reasons are that Lighttpd provides faster setup easierconfiguration and better performance Lighttpd is running with FastCGI
The path of the web server is varwwwlighttpd and the SELinux configuration are still the defaults
The web server is running in SSL-only mode and the certificate is generated during the server setup process
152 Database server
For persistence storage the drop-in replacement MariaDB is used MySQL will work to but this is not tested phpMyAd-min is available under phpmyadmin on the web server beside the command-line tools for easy administration
The default credentials for phpMyAdmin are rootwebshop or the entry you made in the Ansible playbookdevelvariablessensitiveyml
153 Versions
The web shop is built with the below listed components and tested Other releases can be used and may work but thiswill not be tested Probably it will work with different releases
bull Operating system Fedora 20
bull Kernel 3135-202fc20x86_64
bull Lighttpd 1434
bull PHP 557
bull MariaDB 5534
For communication postfix and mosquitto are needed additionally
37
Shop Documentation Release 001
154 Setup infrastructure
1541 Configuration management
For the creation of reproducable and identical environment for the development and the run-time across differentsystems Ansible is used as configuration management solution All needed steps of the installation are automated Theconfiguration doesnrsquot differentiate between local or remote installations This matters only for the deployment of theweb content
For local development itrsquos possible to use an LX container
$ sudo ansible-playbook develcontaineryml
To get everything running some additional steps (check the network inside the container generate keys etc) areneeded After you are done check it
$ sudo ansible webshop -m setup
From the management system
$ sudo ssh-copy-id -i rootsshid_rsapub root[IP address of your managed node]
The configuration of Ansible itself (adding the system to etcansiblehosts and copying the SSH keys) isnot documented at this place There are various resources available like here All playbooks are located in the folderdevel Start the setup with the command shown below
$ sudo ansible-playbook develsetupyml
The used group name in etcansiblehosts is webshop
If the setup completes without errors then the web server is accessible and show a default page Please keep in mindthat the server is only accessible over https unencrypted traffic is not allowed
1542 DeploymentSetup website
For the simple deployment of the lastest version of the shop a playbook called deployyml is provided Thisplaybook put all files in place
$ sudo ansible-playbook develdeployyml
To full deploy the webshop all tables in the database must exist The file webshopsql contains all needed SQLcommands and sample data for the web application
Itrsquos possible to deploy the website manually but this is not recommended A couple of files are depending on templateswhich are created during the deployment
Itrsquos also not recommanded to clone everything into your webserver root This would save you the trouble of doing itby hand but third-party features are missing then Those missing parts are the template engine the pdf generation theconnection to Openstreetmap and probably other things not mentioned here
155 Git respository
All project relevante informations (Source code templates documentation etc) is located in a public Git repositoryon Github
38 Kapitel 15 Development
Shop Documentation Release 001
156 Documentation
The documentation is using reStructuredText as markup language For a local build Sphinx is needed Sphinx isavailable in the Fedora Package Collection and can be installed with yum or any other package management tool
yum -y install python-sphinx python-docutils
The source files of the documentation are located under docs
$ cd docs$ make html
The output is stored under docs_buildhtml
After every push to Github a hook launch a rebuild of the documentation The latest release will be published on Readthe Docs automatically
httpsshoprtfdorg
156 Documentation 39
Shop Documentation Release 001
40 Kapitel 15 Development
KAPITEL 16
Indices and tables
bull genindex
bull modindex
bull search
41
- Basics
-
- Products
- Personas
- Use cases
- Design principles
-
- Web shop Design
-
- General
- Layout
- Sitemap
- Main page
-
- Style and design
-
- Cascading Style Sheets
- Pages
-
- Dynamics
-
- Setup
- Current year
- Navigation Menu
- List of Products
- Company details
-
- External files
-
- Navigation Menu
- Header
- Footer
-
- Input processing
-
- ``Buy Now links
- Select options
-
- Javascript
-
- Simple use case
-
- Cookies and Sessions
-
- Cookies
- Hit counter
- Language selection
- User Accounts
-
- Database
-
- Tables
- PHP
-
- Web service
-
- Map
- Weather
-
- Data export
-
- JSON
-
- Messaging
-
- MQTT
-
- Localisation (L10n)
- Templates
-
- Template
- Content
-
- Development
-
- Web server
- Database server
- Versions
- Setup infrastructure
- Git respository
- Documentation
-
- Indices and tables
-
Shop Documentation Release 001
This is the documentation of the genesi of a web shop It describes the taken steps and the features The code is notproduction-ready but shows at various locations different way to do things
Contents
Inhaltsverzeichnis 1
Shop Documentation Release 001
2 Inhaltsverzeichnis
KAPITEL 1
Basics
11 Products
The Web shop will be for selling pencils in various types
Categories
bull Standard pencils
bull Mechnical pencils
bull Special pencils
Variants or options
bull Color (red yellow black white etc)
bull Hardness (standard HB hard F H 2H soft B 2B)
bull Additional function (Eraser at the end Protection cap handle)
111 Product overview
(The product names are in German because the main language of the shop will not be English)
3
Shop Documentation Release 001
Type Variant Color Hardness Price CHFBleistift keine rot HB 1Bleistift keine rot B 1Bleistift keine rot 2B 1Bleistift keine gelb F 120Bleistift keine gelb H 120Bleistift keine gelb 2H 120Bleistift Gummi rot HB 110Schreiner-Bleistift keine rot HB 180Schreiner-Bleistift keine rot B 180Bleistift keine rot HB 05Bleistift Gummi rot HB 06Kuumlnstler-Bleistift Griff gelb 2B 2Kuumlnstler-Bleistift Griff rot 2B 2Kuumlnstler-Bleistift Griff schwarz 2B 2Minien-Bleistift keine weiss 4Minien-Bleistift keine blau 4Minien-Bleistift keine gelb 4Minien-Bleistift keine rot 4Minien-Bleistift keine silber 9Minien-Bleistift keine schwarz 9
12 Personas
The following personas are defined to interact with the web shop
121 Major customer
Eva is responsible for the ordering of office supplies in her joinery She is ordering twice a month a large amount ofvarious product for different users (management back office and production) Eva has a fix budget for the orders andshe knows her way around web shops
122 End user
Hugo is an architect and middle aged He is drawing sketches and technical drawings but also artistically demandingpieces by hand Thanks to the work with CAD he decovers the web and its advantages Before he bought all his toolsin a local stationery nowadays he is ordering stuff online
13 Use cases
The shop will be stripped-down to two use cases With those use cases are all major use cases with only little modifi-cations covered The use cases for the shop adimistration will be considered out of scope
131 Major customer
bull Ordering of a large amount of one single products or several products
bull Volume discount
4 Kapitel 1 Basics
Shop Documentation Release 001
bull Splitting of oders (ev delivery to different locations)
132 End user
bull Ordering of single products
bull Small quantities
14 Design principles
The below listed points are the fundation for the implementation of the design and the layout to the shop
bull Products should be in the spot light
bull Reduced to the essentials (typography colors fonts etc)
bull meaningful use of whitespaces
Instead of reinventing the wheel it should be considered to use a matured front-end framework like bootstrap for thelayout especially regarding responsive design
14 Design principles 5
Shop Documentation Release 001
6 Kapitel 1 Basics
KAPITEL 2
Web shop Design
21 General
The used company and all data are notional There is no exisiting connection to any existing company with the sameor similar name
211 Company name
The company name is Pencil AG
212 Address
The complete address of the company is
Pencil AGMusterstrasse 13000 BernSchweiz
213 Logo
The logo used in this project is borrowed from the Tango project icon set The file is out of the categories section thefile name of the origin file is applications-officesvg and is licensed under Public Domain
22 Layout
The layout is splitted in different sections The content of the elements especially of the main section (content) willbe definied by the later usage of the page
7
Shop Documentation Release 001
23 Sitemap
The sitemap shows the clustering of the shop at the beginning of the project
This doesnrsquot mean that everything will be done Static pages are easy to make and to maintain
8 Kapitel 2 Web shop Design
Shop Documentation Release 001
24 Main page
The first draft of the main page is based on the prototype shown in section Layout without any format- und styleinformationen
ltDOCTYPE htmlgtlthtml lang=engt
ltheadgtltmeta charset=utf-8gtltmeta name=viewport content=width=device-width initial-scale=10gtltmeta name=description content=Webshop Pencil AG fuumlr Bleistiftegtltmeta name=author content=Fabian AffoltergtlttitlegtWebshop Pencil AG | Homelttitlegt
ltheadgt
ltbodygtlt-- Header container--gtltdivgt
ltdivgtlt-- Logo and company name --gtltimg src=logologopnggtlth2gtWebshop Pencil AGlth2gtlt-- Navigation --gtltulgt
ltligtlta href=gtHomeltagtltligtltligtlta href=gtProdukteltagtltligtltligtlta href=gtUumlber unsltagtltligt
ltulgtlt-- Breadcrumb --gtltolgt
ltligtlta href=gtEbene 1ltagtltligtltligtlta href=gtEbene 2ltagtltligtltligtlta href=gtEbene 3ltagtltligt
ltolgtltdivgt
ltdivgtlt-- Header container--gt
lt-- Action container --gtltdivgt
lth1gtWochen-Aktionlth1gtltpgtDies ist eine super Aktion 10 Bleistifte fuumlr CHF 8ltpgt
ltdivgtlt-- Action container --gt
lt-- Selected products --gtltdivgt
ltpgtHier hat es zufaumlllige Produkteltpgtltdivgtlt-- Selected products --gt
lt-- Footer --gtltdivgt
ltpgtampcopy Pencil AG 2013ltpgtlt-- Footer --gtltdivgt
ltbodygtlthtmlgt
24 Main page 9
Shop Documentation Release 001
Loaded in a browser the initial draft of the main page looks like in the following screenshot
10 Kapitel 2 Web shop Design
KAPITEL 3
Style and design
31 Cascading Style Sheets
The design of the shop will be nothing fancy The approach which was choosen will reflect the points mentioned inthe Design principles section and makes heavy use of the bootstrap framework cascading style sheet Various changesto this CSS file ensure that it matche the needs of this project
32 Pages
The product page show the elements mentioned in the Product overview section
11
Shop Documentation Release 001
12 Kapitel 3 Style and design
KAPITEL 4
Dynamics
The webshop will be a PHP application at the end Those first steps are only covering the very basic stuff of PHP asan introduction
41 Setup
The setupyml playbook puts a simple PHP file in the root directory of the web server with the namephpinfophp This file displays PHP details
Achtung Remove this file before makeing the shop accessible by a public audience
42 Current year
The first PHP element in the webshop is showing the current year in the footer of every page With the help of thislittle piece of code there is no longer a need to update the year
ltphp echo date(Y) gt
43 Navigation Menu
The basic menu was built with the following snippet
ltphp$menu = array(rsquoHomersquo =gt rsquoindexphprsquo
rsquoProduktersquo =gt rsquoproductsphprsquorsquoUumlber unsrsquo =gt rsquoaboutphprsquo
)foreach($menu as $label =gt $link)
echo rsquoltligtlta href=rsquo $link rsquogtrsquo $label rsquoltagtltligtrsquo
gt
The issue with that snippet was that the CSS class was missing In regards to a future separation and reusability anadditional statements was added This way the label of the active page is highlighted
13
Shop Documentation Release 001
ltphp$menu = array(rsquoHomersquo =gt rsquoindexphprsquo
rsquoProduktersquo =gt rsquoproductsphprsquorsquoUumlber unsrsquo =gt rsquoaboutphprsquo
)foreach ($menu as $label =gt $link)
$url = trim($_SERVER[rsquoPHP_SELFrsquo] rsquorsquo)if ($link == $url)
echo rsquoltli class=activegtlta href=rsquo $link rsquogtrsquo $label rsquoltagtltligtrsquo else
echo rsquoltli class=gtlta href=rsquo $link rsquogtrsquo $label rsquoltagtltligtrsquo
gt
44 List of Products
The product overiew is a simple table The heading of the table is placed in an array
ltdivgtlttable class=table table-stripedgtltthead valign=bottomgtlttrgtltphp
$heading = array(rsquoTypersquo rsquoVariantrsquo rsquoColorrsquo rsquoHardnessrsquo rsquoPrice CHFrsquo)foreach ($heading as $element)
echo rsquoltth class=headgtrsquo$elementrsquoltthgtrsquon
gtlttrgtlttheadgtlttbody valign=topgtltphp
$products = array(array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquoHBrsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquoBrsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquo2Brsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquoFrsquo rsquo12rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquoHrsquo rsquo12rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquo2Hrsquo rsquo12rsquo)
)foreach ($products as $product =gt $details)
echo lttrgtforeach ($details as $detail)
echo lttdgt$detaillttdgtecho lttrgt
gtlttbodygtlttablegt
ltdivgt
14 Kapitel 4 Dynamics
Shop Documentation Release 001
45 Company details
The data for the About page are included out of a static and plain text file
ltphp$str = file_get_contents(companytxt)echo $str
gt
45 Company details 15
Shop Documentation Release 001
16 Kapitel 4 Dynamics
KAPITEL 5
External files
51 Navigation Menu
The menu is outsourced in the file menuphp
ltphpfunction menu()
$part1 = rsquoltul class=nav nav-tabsgtrsquon$part2 = rsquorsquo$part3 = rsquoltulgtrsquon Menu array with page title and assigned file$menu = array(rsquoHomersquo =gt rsquoindexphprsquo
rsquoProduktersquo =gt rsquoproductsphprsquorsquoUumlber unsrsquo =gt rsquoaboutphprsquo
)foreach ($menu as $label =gt $link)
For the CSS only the file name without is needed$url = trim($_SERVER[rsquoPHP_SELFrsquo] rsquorsquo)if ($link == $url)
$part2 = $part2ltli class=rsquoactiversquogtlta href=rsquo$linkrsquogt$labelltagtltligtn else
$part2 = $part2ltli class=rsquorsquogtlta href=rsquo$linkrsquogt$labelltagtltligtn
return $part1$part2$part3
gt
52 Header
The complete header part is loaded from the file headerphp
ltphpfunction head()
$start_page = indexphp$part1 = ltdivgtn$part2 = tlta class=rsquobrand-logorsquo href=rsquo$start_pagersquogtltagtn$part3 = tltp class=rsquobrand-namersquogtWebshop Pencil AGltpgtn$part4 = ltdivgtnreturn $part1$part2$part3$part4
17
Shop Documentation Release 001
gt
53 Footer
The same is done witht the page footers
ltphpfunction foot()
$class1 = rsquoltdiv class=footergtrsquon$class2 = rsquoltdivgtrsquon$text = ltpgtampcopy Pencil AG getYear()rsquoltpgtrsquonreturn $class1$text$class2
function getYear()return date(Y)
gt
18 Kapitel 5 External files
KAPITEL 6
Input processing
61 ldquoBuy Nowrdquo links
The ldquoBuy Nowrdquo links are attached to the Products page Every entry has itrsquos own link which lead to a detail page Thelinks are using hidden form elements to transfer the data
ltphp$products = array(array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquoHBrsquo rsquo1rsquo)
array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquoBrsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquo2Brsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquoFrsquo rsquo12rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquoHrsquo rsquo12rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquo2Hrsquo rsquo12rsquo)
)foreach ($products as $product =gt $details)
echo lttrgtnforeach ($details as $detail)
echo lttdgt$detaillttdgtnecho lttdgtnecho ltform action=rsquoproductphprsquo method=rsquogetrsquo name=rsquopencilrsquogtnecho ltinput type=rsquohiddenrsquo name=rsquotypersquo value=rsquo$details[0]rsquogtnecho ltinput type=rsquohiddenrsquo name=rsquooptionsrsquo value=rsquo$details[1]rsquogtnecho ltinput type=rsquohiddenrsquo name=rsquocolorrsquo value=rsquo$details[2]rsquogtnecho ltinput type=rsquohiddenrsquo name=rsquohardnessrsquo value=rsquo$details[3]rsquogtnecho ltinput type=rsquohiddenrsquo name=rsquopricersquo value=rsquo$details[4]rsquogtnecho ltinput type=rsquosubmitrsquo class=rsquobtn btn-defaultrsquo value=rsquoKauf michrsquogtnecho ltformgtnecho lttdgtnecho lttrgtn
gt
And the detail page contains the code fragement mentioned below
ltphp$type=$_GET[rsquotypersquo]$color=$_GET[rsquocolorrsquo]$hardness=$_GET[rsquohardnessrsquo]$options=$_GET[rsquooptionsrsquo]$price=$_GET[rsquopricersquo]echo I am a $type in $color and a hardness of $hardness I have $options as an option and my price is $price CHF
gt
19
Shop Documentation Release 001
Bemerkung The Products page was modified in the process of the development
62 Select options
The signupbilling page contains a dropdown element that all days of a month for the entry of the userrsquos birthday
ltselect name=daygtltoptiongtDayltoptiongt
ltphp$days = range(31 1)foreach ($days as $day)
echo rsquoltoption value=rsquo$dayrsquogtrsquo$dayrsquoltoptiongtrsquo
gtltselectgt
20 Kapitel 6 Input processing
KAPITEL 7
Javascript
Over the years Javascript became a very popular programming language The webshop is using Javascript at a coupleof places
71 Simple use case
Javascript makes it easy to access elements in the DOM Setting the focus is a nice way to support the user with inputform
ltscript language=javascriptgtfunction setFocus()
documentforms[login][username]focus()
ltscriptgtltheadgtltbody onload=setFocus()gt
Another one is to check if something was entered in an input field
function validateForm() var username = documentforms[rdquologinrdquo][rdquousernamerdquo]value if (username== null || username == ldquordquo)
documentforms[rdquologinrdquo][rdquousernamerdquo]stylebackgroundColor = ldquoFF9999rdquo docu-mentforms[rdquologinrdquo][rdquousernamerdquo]placeholder = ldquoPlease your usernamerdquo docu-mentforms[rdquologinrdquo][rdquousernamerdquo]focus() return false
A simple message is informing the user about an action which was taken against the database
echo ltscript type=textjavascriptgtalert(New entry $entry added successfully)windowlocation = tablesphp
ltscriptgt
The delete process is only executed if the user confirm to delete a record
ltform action=scriptsdelete-processphp onSubmit=return confirm(rsquoAre you sure to delete this entryrsquo) method=POSTgtltinput type=hidden name=table value=$sectiongtltinput type=hidden name=id value=$result-gtidgtltinput type=submit name=Submit value=Deletegt
ltformgt
For additional Javascript please check the source of the indexphp file and the reflsquowebservicelsquo_ section
21
Shop Documentation Release 001
22 Kapitel 7 Javascript
KAPITEL 8
Cookies and Sessions
The built-in support for sessions in PHP is handling all cookie manipulation to provide persistent variables that areaccessible from different pages and across multiple visits to the site
81 Cookies
A cookie is used to track the last time a visitor check the front page The cookie is set when a visitor arrives
function lastVisit($name $expire) $value = getDateDMY() - getTimeHM()setcookie($name $value time() + $expire rsquorsquo $_SERVER[rsquoSERVER_NAMErsquo] true true)
In the footer of the index page the details are presented
ltphpif(isset($_COOKIE[rsquoLastVisitrsquo]))
$last = $_COOKIE[rsquoLastVisitrsquo]echo You last visited us on $last
else echo This is your first visit
gt
82 Hit counter
As a simple show case for PHP sessions a hit counter for the front page is available
ltphpsession_start()
$_SESSION[rsquohitsrsquo] = $_SESSION[rsquohitsrsquo] + 1gt
Included in the footer it shous the users the total of visits
echo Total $_SESSION[rsquohitsrsquo] visits of this page
23
Shop Documentation Release 001
83 Language selection
84 User Accounts
24 Kapitel 8 Cookies and Sessions
KAPITEL 9
Database
The database backend for the webshop will be MariaDB which is the drop-in replacement for MySQL
For the setup please check the Development section in this documentation
91 Tables
The following tables are needed for the webshop to work
bull products
bull customers
bull pencils
bull colors
bull hardness
bull options
bull users
Please use the develwebshopsql to setup the database
92 PHP
Below you find the configuration file for a default installation of the webshop This file is a template and filled duringthe setup process
ltphp$host = localhost$user = root$password = webshop$dbase = webshop$connection = new mysqli($host $user $password $dbase)
if ($connection-gtconnect_errno) echo Failed to connect to MariaDBMySQL ($connection-gtconnect_errno) $connection-gtconnect_error
mysqli_report(MYSQLI_REPORT_ERROR)
gt
25
Shop Documentation Release 001
All connections to the database are done in the same way Below you find an example Everything is done in theobject-oriented style
ltphprequire_once(rsquoconfigdbconnectphprsquo)if ($connection-gtconnect_errno == 0)
$sql = SELECT FROM products$results = $connection-gtquery($sql)echo $results-gtnum_rows$results-gtclose()
else echo Database connection error
gt
26 Kapitel 9 Database
KAPITEL 10
Web service
Tow web services are integrated to take advantages of online available data sources
101 Map
Leafletjs a JavaScript library for working with interactive maps from OpenStreetMap (OSM) is implemented as ashow case for a simple web service
The basic steps to integrate a map is shown below
ltdiv id=map class=map style=width 600px height 400pxgtltdivgt
ltscript src=scriptsleafletjsgtltscriptgtltscript src=scriptsleaflet-providersjsgtltscriptgtltscriptgtvar map = Lmap(rsquomaprsquo
center [250472 -773255]zoom 12zoomControl true
)
var defaultLayer = LtileLayerprovider(rsquoOpenStreetMapMapnikrsquo)addTo(map)ltscriptgt
102 Weather
The OpenWeatherMap service provides free weather data and a forecast API for web applications
ltphp Details about the API httpbugsopenweathermaporgprojectsapiwikiApi_2_5_weather$url = rsquohttpapiopenweathermaporgdata25weatherq=Bernechampunit=metricsampmode=jsonrsquo
$json = file_get_contents($url)$data = json_decode($json)
$tempC = round((27315 - $data-gtmain-gttemp)100) 100$humidity = $data-gtmain-gthumidity$pressure = $data-gtmain-gtpressure
27
Shop Documentation Release 001
echo ltpgtTemperatur $tempC degCltbrgtnecho Luftfeuchtigkeit $humidity ltbrgtnecho Luftdruck $pressure Paltpgtn
gt
28 Kapitel 10 Web service
KAPITEL 11
Data export
111 PDF
FPDF is a PHP class that allows to generate PDF files with pure PHP As a showcase for that the product specificationsfor a given product are filled in a pdf and showed in the browser The user can then decide to download or print thefile
112 JSON
JavaScript Object Notation (JSON) is a lightweight data-interchange format The format is language independent andPHP support the encoding and the decoding JSON with json_encode($data) and json_decode($data)$rows = array()$sql = SELECT FROM products$results = $connection-gtquery($sql)while ($result = $results-gtfetch_object())
$rows[] = $result$results-gtclose()
Writing all rows to a JSON file$fp = fopen(rsquopencilsjsonrsquo rsquowrsquo)fwrite($fp json_encode($rows))fclose($fp)gt
and for reading it
ltphp$json = file_get_contents(rsquopencilsjsonrsquo)print_r(json_decode($json))
gt
29
Shop Documentation Release 001
30 Kapitel 11 Data export
KAPITEL 12
Messaging
Beside standard email messages the webshop supports sending MQ Telemetry Transport protocol (MQTT) messagesas an additional feature The MQTT messages are small
121 MQTT
Mosquitto-PHP is used as a PHP wrapper for MQTT Please check the Projectrsquos README for details about theinstallation and the setup
1211 Broker
Mosquitto is a message broker that implements the MQ Telemetry Transport protocol Check if mosquitto is run-ning
$ sudo systemctl status mosquittoservice
If not start it
$ systemctl start mosquittoservice
All messages are published to the topic webshop
1212 Publishing
After the installation of Mosquitto-PHP the snipplet shown below sends a single message
ltphpdefine(rsquoBROKERrsquo rsquolocalhostrsquo)define(rsquoPORTrsquo 1883)define(rsquoCLIENT_IDrsquo webshop_ + getmypid())$topic = webshop$subtopic = test$completeTopic = $topic$subtopic
$client = new MosquittoClient(CLIENT_ID)$client-gtconnect(BROKER PORT 60)
$message = Test message from webshop at date(Y-m-d His)$client-gtpublish($completeTopic $message 0 false)
gt
31
Shop Documentation Release 001
1213 Subscribing
To read the messages sent by the webshop a client is needed The Mosquitto broker contain a simple command-linetool for subscribing to various topics
$ mosquitto_sub -h localhost -t webshop
122 Email
This section doesnrsquot describe the installation and configuration of a local MTA There are enough resources thatcontains information about the setup of postfix for local delivery only
If you want to test the email feature add the following code in one of PHP pages
ltphp mail(rsquorootlocalhostrsquo rsquoTest message from webshoprsquo rsquoThe webshop is selling pencilsrsquo) gt
By default SELinux is running in Enforcing mode which is restrictive about about what a web server can do Toallow sending email the following SELinux boolean needs to changed
setsebool -P httpd_can_network_connect=1 setsebool -P httpd_can_sendmail=1
32 Kapitel 12 Messaging
KAPITEL 13
Localisation (L10n)
There are several ways to add localisation to a web site For small projects arrays with string can work but this is notvery efficient and user-friendly With Gettext is a toolset available that provide a framework to produce multi-lingualcontent in a wide area of programming languages
Make sure that the php-gettext package is available on your system If not install it
$ sudo yum -y install php-php-gettext
Check if gettext support is available
ltphpif (function_exists(gettext))
echo gettext is not installednelse
echo gettext is supportedn
gt
Make sure that all locales your want are available on the server
locale -a
The first step is to mark all string which should be translatable as shown below For further details please refer to theGettext documentation
echo _(rsquoSome textrsquo)
The next step is to extract all strings
xgettext --from-code=UTF-8 -o localewebshoppot php scriptsphp
To re-generate the file after an update join the strings
xgettext -j --from-code=UTF-8 -o localewebshoppot php scriptsphp
For every language a po file is needed for the transations Generate it with the command mentioned below
msginit --no-translator -l de_CH -o localede_CHpo -i localewebshoppot
Once created there are only updates of the message catalog needed in the futures
msgmerge -U localede_CHpo localewebshoppot
If you re finish create the mo file for the specific language
33
Shop Documentation Release 001
msgfmt -c -v -o localede_CHLC_MESSAGESwebshopmo localede_CHpo
34 Kapitel 13 Localisation (L10n)
KAPITEL 14
Templates
Beside other solutions Savant3 is a lightweight object-oriented template system for PHP This solution does not needa lot of additional configuration
141 Template
A simple template file looks like the one shown below
lthtmlgtltheadgt
lttitlegtltphp echo $this-gteprint($this-gttitle) gtlttitlegtltheadgtltbodygt
ltphp echo $this-gteprint($this-gtcontent) gtltbodygt
lthtmlgt
For a more detailed intro check this article on Zend Developer Zone
142 Content
To fill the template with data all wished variables needs to be defined in a seperate PHP file
ltphprequire_once rsquoscriptsSavant3phprsquo$tpl = new Savant3()
Create a title$title = Simple sample page
Create the content of the page$content = Some sample text to show
Assign values to the Savant instance$tpl-gttitle = $title$tpl-gtcontent = $content
Define the template source file to show$tpl-gtdisplay(rsquosimpletplphprsquo)
gt
35
Shop Documentation Release 001
The webshop contains a page (master)
36 Kapitel 14 Templates
KAPITEL 15
Development
This sections describes the configuration of the development and runtime environment for the web shop
151 Web server
Instead of Apache the project is running on Lighttpd The reasons are that Lighttpd provides faster setup easierconfiguration and better performance Lighttpd is running with FastCGI
The path of the web server is varwwwlighttpd and the SELinux configuration are still the defaults
The web server is running in SSL-only mode and the certificate is generated during the server setup process
152 Database server
For persistence storage the drop-in replacement MariaDB is used MySQL will work to but this is not tested phpMyAd-min is available under phpmyadmin on the web server beside the command-line tools for easy administration
The default credentials for phpMyAdmin are rootwebshop or the entry you made in the Ansible playbookdevelvariablessensitiveyml
153 Versions
The web shop is built with the below listed components and tested Other releases can be used and may work but thiswill not be tested Probably it will work with different releases
bull Operating system Fedora 20
bull Kernel 3135-202fc20x86_64
bull Lighttpd 1434
bull PHP 557
bull MariaDB 5534
For communication postfix and mosquitto are needed additionally
37
Shop Documentation Release 001
154 Setup infrastructure
1541 Configuration management
For the creation of reproducable and identical environment for the development and the run-time across differentsystems Ansible is used as configuration management solution All needed steps of the installation are automated Theconfiguration doesnrsquot differentiate between local or remote installations This matters only for the deployment of theweb content
For local development itrsquos possible to use an LX container
$ sudo ansible-playbook develcontaineryml
To get everything running some additional steps (check the network inside the container generate keys etc) areneeded After you are done check it
$ sudo ansible webshop -m setup
From the management system
$ sudo ssh-copy-id -i rootsshid_rsapub root[IP address of your managed node]
The configuration of Ansible itself (adding the system to etcansiblehosts and copying the SSH keys) isnot documented at this place There are various resources available like here All playbooks are located in the folderdevel Start the setup with the command shown below
$ sudo ansible-playbook develsetupyml
The used group name in etcansiblehosts is webshop
If the setup completes without errors then the web server is accessible and show a default page Please keep in mindthat the server is only accessible over https unencrypted traffic is not allowed
1542 DeploymentSetup website
For the simple deployment of the lastest version of the shop a playbook called deployyml is provided Thisplaybook put all files in place
$ sudo ansible-playbook develdeployyml
To full deploy the webshop all tables in the database must exist The file webshopsql contains all needed SQLcommands and sample data for the web application
Itrsquos possible to deploy the website manually but this is not recommended A couple of files are depending on templateswhich are created during the deployment
Itrsquos also not recommanded to clone everything into your webserver root This would save you the trouble of doing itby hand but third-party features are missing then Those missing parts are the template engine the pdf generation theconnection to Openstreetmap and probably other things not mentioned here
155 Git respository
All project relevante informations (Source code templates documentation etc) is located in a public Git repositoryon Github
38 Kapitel 15 Development
Shop Documentation Release 001
156 Documentation
The documentation is using reStructuredText as markup language For a local build Sphinx is needed Sphinx isavailable in the Fedora Package Collection and can be installed with yum or any other package management tool
yum -y install python-sphinx python-docutils
The source files of the documentation are located under docs
$ cd docs$ make html
The output is stored under docs_buildhtml
After every push to Github a hook launch a rebuild of the documentation The latest release will be published on Readthe Docs automatically
httpsshoprtfdorg
156 Documentation 39
Shop Documentation Release 001
40 Kapitel 15 Development
KAPITEL 16
Indices and tables
bull genindex
bull modindex
bull search
41
- Basics
-
- Products
- Personas
- Use cases
- Design principles
-
- Web shop Design
-
- General
- Layout
- Sitemap
- Main page
-
- Style and design
-
- Cascading Style Sheets
- Pages
-
- Dynamics
-
- Setup
- Current year
- Navigation Menu
- List of Products
- Company details
-
- External files
-
- Navigation Menu
- Header
- Footer
-
- Input processing
-
- ``Buy Now links
- Select options
-
- Javascript
-
- Simple use case
-
- Cookies and Sessions
-
- Cookies
- Hit counter
- Language selection
- User Accounts
-
- Database
-
- Tables
- PHP
-
- Web service
-
- Map
- Weather
-
- Data export
-
- JSON
-
- Messaging
-
- MQTT
-
- Localisation (L10n)
- Templates
-
- Template
- Content
-
- Development
-
- Web server
- Database server
- Versions
- Setup infrastructure
- Git respository
- Documentation
-
- Indices and tables
-
Shop Documentation Release 001
2 Inhaltsverzeichnis
KAPITEL 1
Basics
11 Products
The Web shop will be for selling pencils in various types
Categories
bull Standard pencils
bull Mechnical pencils
bull Special pencils
Variants or options
bull Color (red yellow black white etc)
bull Hardness (standard HB hard F H 2H soft B 2B)
bull Additional function (Eraser at the end Protection cap handle)
111 Product overview
(The product names are in German because the main language of the shop will not be English)
3
Shop Documentation Release 001
Type Variant Color Hardness Price CHFBleistift keine rot HB 1Bleistift keine rot B 1Bleistift keine rot 2B 1Bleistift keine gelb F 120Bleistift keine gelb H 120Bleistift keine gelb 2H 120Bleistift Gummi rot HB 110Schreiner-Bleistift keine rot HB 180Schreiner-Bleistift keine rot B 180Bleistift keine rot HB 05Bleistift Gummi rot HB 06Kuumlnstler-Bleistift Griff gelb 2B 2Kuumlnstler-Bleistift Griff rot 2B 2Kuumlnstler-Bleistift Griff schwarz 2B 2Minien-Bleistift keine weiss 4Minien-Bleistift keine blau 4Minien-Bleistift keine gelb 4Minien-Bleistift keine rot 4Minien-Bleistift keine silber 9Minien-Bleistift keine schwarz 9
12 Personas
The following personas are defined to interact with the web shop
121 Major customer
Eva is responsible for the ordering of office supplies in her joinery She is ordering twice a month a large amount ofvarious product for different users (management back office and production) Eva has a fix budget for the orders andshe knows her way around web shops
122 End user
Hugo is an architect and middle aged He is drawing sketches and technical drawings but also artistically demandingpieces by hand Thanks to the work with CAD he decovers the web and its advantages Before he bought all his toolsin a local stationery nowadays he is ordering stuff online
13 Use cases
The shop will be stripped-down to two use cases With those use cases are all major use cases with only little modifi-cations covered The use cases for the shop adimistration will be considered out of scope
131 Major customer
bull Ordering of a large amount of one single products or several products
bull Volume discount
4 Kapitel 1 Basics
Shop Documentation Release 001
bull Splitting of oders (ev delivery to different locations)
132 End user
bull Ordering of single products
bull Small quantities
14 Design principles
The below listed points are the fundation for the implementation of the design and the layout to the shop
bull Products should be in the spot light
bull Reduced to the essentials (typography colors fonts etc)
bull meaningful use of whitespaces
Instead of reinventing the wheel it should be considered to use a matured front-end framework like bootstrap for thelayout especially regarding responsive design
14 Design principles 5
Shop Documentation Release 001
6 Kapitel 1 Basics
KAPITEL 2
Web shop Design
21 General
The used company and all data are notional There is no exisiting connection to any existing company with the sameor similar name
211 Company name
The company name is Pencil AG
212 Address
The complete address of the company is
Pencil AGMusterstrasse 13000 BernSchweiz
213 Logo
The logo used in this project is borrowed from the Tango project icon set The file is out of the categories section thefile name of the origin file is applications-officesvg and is licensed under Public Domain
22 Layout
The layout is splitted in different sections The content of the elements especially of the main section (content) willbe definied by the later usage of the page
7
Shop Documentation Release 001
23 Sitemap
The sitemap shows the clustering of the shop at the beginning of the project
This doesnrsquot mean that everything will be done Static pages are easy to make and to maintain
8 Kapitel 2 Web shop Design
Shop Documentation Release 001
24 Main page
The first draft of the main page is based on the prototype shown in section Layout without any format- und styleinformationen
ltDOCTYPE htmlgtlthtml lang=engt
ltheadgtltmeta charset=utf-8gtltmeta name=viewport content=width=device-width initial-scale=10gtltmeta name=description content=Webshop Pencil AG fuumlr Bleistiftegtltmeta name=author content=Fabian AffoltergtlttitlegtWebshop Pencil AG | Homelttitlegt
ltheadgt
ltbodygtlt-- Header container--gtltdivgt
ltdivgtlt-- Logo and company name --gtltimg src=logologopnggtlth2gtWebshop Pencil AGlth2gtlt-- Navigation --gtltulgt
ltligtlta href=gtHomeltagtltligtltligtlta href=gtProdukteltagtltligtltligtlta href=gtUumlber unsltagtltligt
ltulgtlt-- Breadcrumb --gtltolgt
ltligtlta href=gtEbene 1ltagtltligtltligtlta href=gtEbene 2ltagtltligtltligtlta href=gtEbene 3ltagtltligt
ltolgtltdivgt
ltdivgtlt-- Header container--gt
lt-- Action container --gtltdivgt
lth1gtWochen-Aktionlth1gtltpgtDies ist eine super Aktion 10 Bleistifte fuumlr CHF 8ltpgt
ltdivgtlt-- Action container --gt
lt-- Selected products --gtltdivgt
ltpgtHier hat es zufaumlllige Produkteltpgtltdivgtlt-- Selected products --gt
lt-- Footer --gtltdivgt
ltpgtampcopy Pencil AG 2013ltpgtlt-- Footer --gtltdivgt
ltbodygtlthtmlgt
24 Main page 9
Shop Documentation Release 001
Loaded in a browser the initial draft of the main page looks like in the following screenshot
10 Kapitel 2 Web shop Design
KAPITEL 3
Style and design
31 Cascading Style Sheets
The design of the shop will be nothing fancy The approach which was choosen will reflect the points mentioned inthe Design principles section and makes heavy use of the bootstrap framework cascading style sheet Various changesto this CSS file ensure that it matche the needs of this project
32 Pages
The product page show the elements mentioned in the Product overview section
11
Shop Documentation Release 001
12 Kapitel 3 Style and design
KAPITEL 4
Dynamics
The webshop will be a PHP application at the end Those first steps are only covering the very basic stuff of PHP asan introduction
41 Setup
The setupyml playbook puts a simple PHP file in the root directory of the web server with the namephpinfophp This file displays PHP details
Achtung Remove this file before makeing the shop accessible by a public audience
42 Current year
The first PHP element in the webshop is showing the current year in the footer of every page With the help of thislittle piece of code there is no longer a need to update the year
ltphp echo date(Y) gt
43 Navigation Menu
The basic menu was built with the following snippet
ltphp$menu = array(rsquoHomersquo =gt rsquoindexphprsquo
rsquoProduktersquo =gt rsquoproductsphprsquorsquoUumlber unsrsquo =gt rsquoaboutphprsquo
)foreach($menu as $label =gt $link)
echo rsquoltligtlta href=rsquo $link rsquogtrsquo $label rsquoltagtltligtrsquo
gt
The issue with that snippet was that the CSS class was missing In regards to a future separation and reusability anadditional statements was added This way the label of the active page is highlighted
13
Shop Documentation Release 001
ltphp$menu = array(rsquoHomersquo =gt rsquoindexphprsquo
rsquoProduktersquo =gt rsquoproductsphprsquorsquoUumlber unsrsquo =gt rsquoaboutphprsquo
)foreach ($menu as $label =gt $link)
$url = trim($_SERVER[rsquoPHP_SELFrsquo] rsquorsquo)if ($link == $url)
echo rsquoltli class=activegtlta href=rsquo $link rsquogtrsquo $label rsquoltagtltligtrsquo else
echo rsquoltli class=gtlta href=rsquo $link rsquogtrsquo $label rsquoltagtltligtrsquo
gt
44 List of Products
The product overiew is a simple table The heading of the table is placed in an array
ltdivgtlttable class=table table-stripedgtltthead valign=bottomgtlttrgtltphp
$heading = array(rsquoTypersquo rsquoVariantrsquo rsquoColorrsquo rsquoHardnessrsquo rsquoPrice CHFrsquo)foreach ($heading as $element)
echo rsquoltth class=headgtrsquo$elementrsquoltthgtrsquon
gtlttrgtlttheadgtlttbody valign=topgtltphp
$products = array(array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquoHBrsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquoBrsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquo2Brsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquoFrsquo rsquo12rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquoHrsquo rsquo12rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquo2Hrsquo rsquo12rsquo)
)foreach ($products as $product =gt $details)
echo lttrgtforeach ($details as $detail)
echo lttdgt$detaillttdgtecho lttrgt
gtlttbodygtlttablegt
ltdivgt
14 Kapitel 4 Dynamics
Shop Documentation Release 001
45 Company details
The data for the About page are included out of a static and plain text file
ltphp$str = file_get_contents(companytxt)echo $str
gt
45 Company details 15
Shop Documentation Release 001
16 Kapitel 4 Dynamics
KAPITEL 5
External files
51 Navigation Menu
The menu is outsourced in the file menuphp
ltphpfunction menu()
$part1 = rsquoltul class=nav nav-tabsgtrsquon$part2 = rsquorsquo$part3 = rsquoltulgtrsquon Menu array with page title and assigned file$menu = array(rsquoHomersquo =gt rsquoindexphprsquo
rsquoProduktersquo =gt rsquoproductsphprsquorsquoUumlber unsrsquo =gt rsquoaboutphprsquo
)foreach ($menu as $label =gt $link)
For the CSS only the file name without is needed$url = trim($_SERVER[rsquoPHP_SELFrsquo] rsquorsquo)if ($link == $url)
$part2 = $part2ltli class=rsquoactiversquogtlta href=rsquo$linkrsquogt$labelltagtltligtn else
$part2 = $part2ltli class=rsquorsquogtlta href=rsquo$linkrsquogt$labelltagtltligtn
return $part1$part2$part3
gt
52 Header
The complete header part is loaded from the file headerphp
ltphpfunction head()
$start_page = indexphp$part1 = ltdivgtn$part2 = tlta class=rsquobrand-logorsquo href=rsquo$start_pagersquogtltagtn$part3 = tltp class=rsquobrand-namersquogtWebshop Pencil AGltpgtn$part4 = ltdivgtnreturn $part1$part2$part3$part4
17
Shop Documentation Release 001
gt
53 Footer
The same is done witht the page footers
ltphpfunction foot()
$class1 = rsquoltdiv class=footergtrsquon$class2 = rsquoltdivgtrsquon$text = ltpgtampcopy Pencil AG getYear()rsquoltpgtrsquonreturn $class1$text$class2
function getYear()return date(Y)
gt
18 Kapitel 5 External files
KAPITEL 6
Input processing
61 ldquoBuy Nowrdquo links
The ldquoBuy Nowrdquo links are attached to the Products page Every entry has itrsquos own link which lead to a detail page Thelinks are using hidden form elements to transfer the data
ltphp$products = array(array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquoHBrsquo rsquo1rsquo)
array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquoBrsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquo2Brsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquoFrsquo rsquo12rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquoHrsquo rsquo12rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquo2Hrsquo rsquo12rsquo)
)foreach ($products as $product =gt $details)
echo lttrgtnforeach ($details as $detail)
echo lttdgt$detaillttdgtnecho lttdgtnecho ltform action=rsquoproductphprsquo method=rsquogetrsquo name=rsquopencilrsquogtnecho ltinput type=rsquohiddenrsquo name=rsquotypersquo value=rsquo$details[0]rsquogtnecho ltinput type=rsquohiddenrsquo name=rsquooptionsrsquo value=rsquo$details[1]rsquogtnecho ltinput type=rsquohiddenrsquo name=rsquocolorrsquo value=rsquo$details[2]rsquogtnecho ltinput type=rsquohiddenrsquo name=rsquohardnessrsquo value=rsquo$details[3]rsquogtnecho ltinput type=rsquohiddenrsquo name=rsquopricersquo value=rsquo$details[4]rsquogtnecho ltinput type=rsquosubmitrsquo class=rsquobtn btn-defaultrsquo value=rsquoKauf michrsquogtnecho ltformgtnecho lttdgtnecho lttrgtn
gt
And the detail page contains the code fragement mentioned below
ltphp$type=$_GET[rsquotypersquo]$color=$_GET[rsquocolorrsquo]$hardness=$_GET[rsquohardnessrsquo]$options=$_GET[rsquooptionsrsquo]$price=$_GET[rsquopricersquo]echo I am a $type in $color and a hardness of $hardness I have $options as an option and my price is $price CHF
gt
19
Shop Documentation Release 001
Bemerkung The Products page was modified in the process of the development
62 Select options
The signupbilling page contains a dropdown element that all days of a month for the entry of the userrsquos birthday
ltselect name=daygtltoptiongtDayltoptiongt
ltphp$days = range(31 1)foreach ($days as $day)
echo rsquoltoption value=rsquo$dayrsquogtrsquo$dayrsquoltoptiongtrsquo
gtltselectgt
20 Kapitel 6 Input processing
KAPITEL 7
Javascript
Over the years Javascript became a very popular programming language The webshop is using Javascript at a coupleof places
71 Simple use case
Javascript makes it easy to access elements in the DOM Setting the focus is a nice way to support the user with inputform
ltscript language=javascriptgtfunction setFocus()
documentforms[login][username]focus()
ltscriptgtltheadgtltbody onload=setFocus()gt
Another one is to check if something was entered in an input field
function validateForm() var username = documentforms[rdquologinrdquo][rdquousernamerdquo]value if (username== null || username == ldquordquo)
documentforms[rdquologinrdquo][rdquousernamerdquo]stylebackgroundColor = ldquoFF9999rdquo docu-mentforms[rdquologinrdquo][rdquousernamerdquo]placeholder = ldquoPlease your usernamerdquo docu-mentforms[rdquologinrdquo][rdquousernamerdquo]focus() return false
A simple message is informing the user about an action which was taken against the database
echo ltscript type=textjavascriptgtalert(New entry $entry added successfully)windowlocation = tablesphp
ltscriptgt
The delete process is only executed if the user confirm to delete a record
ltform action=scriptsdelete-processphp onSubmit=return confirm(rsquoAre you sure to delete this entryrsquo) method=POSTgtltinput type=hidden name=table value=$sectiongtltinput type=hidden name=id value=$result-gtidgtltinput type=submit name=Submit value=Deletegt
ltformgt
For additional Javascript please check the source of the indexphp file and the reflsquowebservicelsquo_ section
21
Shop Documentation Release 001
22 Kapitel 7 Javascript
KAPITEL 8
Cookies and Sessions
The built-in support for sessions in PHP is handling all cookie manipulation to provide persistent variables that areaccessible from different pages and across multiple visits to the site
81 Cookies
A cookie is used to track the last time a visitor check the front page The cookie is set when a visitor arrives
function lastVisit($name $expire) $value = getDateDMY() - getTimeHM()setcookie($name $value time() + $expire rsquorsquo $_SERVER[rsquoSERVER_NAMErsquo] true true)
In the footer of the index page the details are presented
ltphpif(isset($_COOKIE[rsquoLastVisitrsquo]))
$last = $_COOKIE[rsquoLastVisitrsquo]echo You last visited us on $last
else echo This is your first visit
gt
82 Hit counter
As a simple show case for PHP sessions a hit counter for the front page is available
ltphpsession_start()
$_SESSION[rsquohitsrsquo] = $_SESSION[rsquohitsrsquo] + 1gt
Included in the footer it shous the users the total of visits
echo Total $_SESSION[rsquohitsrsquo] visits of this page
23
Shop Documentation Release 001
83 Language selection
84 User Accounts
24 Kapitel 8 Cookies and Sessions
KAPITEL 9
Database
The database backend for the webshop will be MariaDB which is the drop-in replacement for MySQL
For the setup please check the Development section in this documentation
91 Tables
The following tables are needed for the webshop to work
bull products
bull customers
bull pencils
bull colors
bull hardness
bull options
bull users
Please use the develwebshopsql to setup the database
92 PHP
Below you find the configuration file for a default installation of the webshop This file is a template and filled duringthe setup process
ltphp$host = localhost$user = root$password = webshop$dbase = webshop$connection = new mysqli($host $user $password $dbase)
if ($connection-gtconnect_errno) echo Failed to connect to MariaDBMySQL ($connection-gtconnect_errno) $connection-gtconnect_error
mysqli_report(MYSQLI_REPORT_ERROR)
gt
25
Shop Documentation Release 001
All connections to the database are done in the same way Below you find an example Everything is done in theobject-oriented style
ltphprequire_once(rsquoconfigdbconnectphprsquo)if ($connection-gtconnect_errno == 0)
$sql = SELECT FROM products$results = $connection-gtquery($sql)echo $results-gtnum_rows$results-gtclose()
else echo Database connection error
gt
26 Kapitel 9 Database
KAPITEL 10
Web service
Tow web services are integrated to take advantages of online available data sources
101 Map
Leafletjs a JavaScript library for working with interactive maps from OpenStreetMap (OSM) is implemented as ashow case for a simple web service
The basic steps to integrate a map is shown below
ltdiv id=map class=map style=width 600px height 400pxgtltdivgt
ltscript src=scriptsleafletjsgtltscriptgtltscript src=scriptsleaflet-providersjsgtltscriptgtltscriptgtvar map = Lmap(rsquomaprsquo
center [250472 -773255]zoom 12zoomControl true
)
var defaultLayer = LtileLayerprovider(rsquoOpenStreetMapMapnikrsquo)addTo(map)ltscriptgt
102 Weather
The OpenWeatherMap service provides free weather data and a forecast API for web applications
ltphp Details about the API httpbugsopenweathermaporgprojectsapiwikiApi_2_5_weather$url = rsquohttpapiopenweathermaporgdata25weatherq=Bernechampunit=metricsampmode=jsonrsquo
$json = file_get_contents($url)$data = json_decode($json)
$tempC = round((27315 - $data-gtmain-gttemp)100) 100$humidity = $data-gtmain-gthumidity$pressure = $data-gtmain-gtpressure
27
Shop Documentation Release 001
echo ltpgtTemperatur $tempC degCltbrgtnecho Luftfeuchtigkeit $humidity ltbrgtnecho Luftdruck $pressure Paltpgtn
gt
28 Kapitel 10 Web service
KAPITEL 11
Data export
111 PDF
FPDF is a PHP class that allows to generate PDF files with pure PHP As a showcase for that the product specificationsfor a given product are filled in a pdf and showed in the browser The user can then decide to download or print thefile
112 JSON
JavaScript Object Notation (JSON) is a lightweight data-interchange format The format is language independent andPHP support the encoding and the decoding JSON with json_encode($data) and json_decode($data)$rows = array()$sql = SELECT FROM products$results = $connection-gtquery($sql)while ($result = $results-gtfetch_object())
$rows[] = $result$results-gtclose()
Writing all rows to a JSON file$fp = fopen(rsquopencilsjsonrsquo rsquowrsquo)fwrite($fp json_encode($rows))fclose($fp)gt
and for reading it
ltphp$json = file_get_contents(rsquopencilsjsonrsquo)print_r(json_decode($json))
gt
29
Shop Documentation Release 001
30 Kapitel 11 Data export
KAPITEL 12
Messaging
Beside standard email messages the webshop supports sending MQ Telemetry Transport protocol (MQTT) messagesas an additional feature The MQTT messages are small
121 MQTT
Mosquitto-PHP is used as a PHP wrapper for MQTT Please check the Projectrsquos README for details about theinstallation and the setup
1211 Broker
Mosquitto is a message broker that implements the MQ Telemetry Transport protocol Check if mosquitto is run-ning
$ sudo systemctl status mosquittoservice
If not start it
$ systemctl start mosquittoservice
All messages are published to the topic webshop
1212 Publishing
After the installation of Mosquitto-PHP the snipplet shown below sends a single message
ltphpdefine(rsquoBROKERrsquo rsquolocalhostrsquo)define(rsquoPORTrsquo 1883)define(rsquoCLIENT_IDrsquo webshop_ + getmypid())$topic = webshop$subtopic = test$completeTopic = $topic$subtopic
$client = new MosquittoClient(CLIENT_ID)$client-gtconnect(BROKER PORT 60)
$message = Test message from webshop at date(Y-m-d His)$client-gtpublish($completeTopic $message 0 false)
gt
31
Shop Documentation Release 001
1213 Subscribing
To read the messages sent by the webshop a client is needed The Mosquitto broker contain a simple command-linetool for subscribing to various topics
$ mosquitto_sub -h localhost -t webshop
122 Email
This section doesnrsquot describe the installation and configuration of a local MTA There are enough resources thatcontains information about the setup of postfix for local delivery only
If you want to test the email feature add the following code in one of PHP pages
ltphp mail(rsquorootlocalhostrsquo rsquoTest message from webshoprsquo rsquoThe webshop is selling pencilsrsquo) gt
By default SELinux is running in Enforcing mode which is restrictive about about what a web server can do Toallow sending email the following SELinux boolean needs to changed
setsebool -P httpd_can_network_connect=1 setsebool -P httpd_can_sendmail=1
32 Kapitel 12 Messaging
KAPITEL 13
Localisation (L10n)
There are several ways to add localisation to a web site For small projects arrays with string can work but this is notvery efficient and user-friendly With Gettext is a toolset available that provide a framework to produce multi-lingualcontent in a wide area of programming languages
Make sure that the php-gettext package is available on your system If not install it
$ sudo yum -y install php-php-gettext
Check if gettext support is available
ltphpif (function_exists(gettext))
echo gettext is not installednelse
echo gettext is supportedn
gt
Make sure that all locales your want are available on the server
locale -a
The first step is to mark all string which should be translatable as shown below For further details please refer to theGettext documentation
echo _(rsquoSome textrsquo)
The next step is to extract all strings
xgettext --from-code=UTF-8 -o localewebshoppot php scriptsphp
To re-generate the file after an update join the strings
xgettext -j --from-code=UTF-8 -o localewebshoppot php scriptsphp
For every language a po file is needed for the transations Generate it with the command mentioned below
msginit --no-translator -l de_CH -o localede_CHpo -i localewebshoppot
Once created there are only updates of the message catalog needed in the futures
msgmerge -U localede_CHpo localewebshoppot
If you re finish create the mo file for the specific language
33
Shop Documentation Release 001
msgfmt -c -v -o localede_CHLC_MESSAGESwebshopmo localede_CHpo
34 Kapitel 13 Localisation (L10n)
KAPITEL 14
Templates
Beside other solutions Savant3 is a lightweight object-oriented template system for PHP This solution does not needa lot of additional configuration
141 Template
A simple template file looks like the one shown below
lthtmlgtltheadgt
lttitlegtltphp echo $this-gteprint($this-gttitle) gtlttitlegtltheadgtltbodygt
ltphp echo $this-gteprint($this-gtcontent) gtltbodygt
lthtmlgt
For a more detailed intro check this article on Zend Developer Zone
142 Content
To fill the template with data all wished variables needs to be defined in a seperate PHP file
ltphprequire_once rsquoscriptsSavant3phprsquo$tpl = new Savant3()
Create a title$title = Simple sample page
Create the content of the page$content = Some sample text to show
Assign values to the Savant instance$tpl-gttitle = $title$tpl-gtcontent = $content
Define the template source file to show$tpl-gtdisplay(rsquosimpletplphprsquo)
gt
35
Shop Documentation Release 001
The webshop contains a page (master)
36 Kapitel 14 Templates
KAPITEL 15
Development
This sections describes the configuration of the development and runtime environment for the web shop
151 Web server
Instead of Apache the project is running on Lighttpd The reasons are that Lighttpd provides faster setup easierconfiguration and better performance Lighttpd is running with FastCGI
The path of the web server is varwwwlighttpd and the SELinux configuration are still the defaults
The web server is running in SSL-only mode and the certificate is generated during the server setup process
152 Database server
For persistence storage the drop-in replacement MariaDB is used MySQL will work to but this is not tested phpMyAd-min is available under phpmyadmin on the web server beside the command-line tools for easy administration
The default credentials for phpMyAdmin are rootwebshop or the entry you made in the Ansible playbookdevelvariablessensitiveyml
153 Versions
The web shop is built with the below listed components and tested Other releases can be used and may work but thiswill not be tested Probably it will work with different releases
bull Operating system Fedora 20
bull Kernel 3135-202fc20x86_64
bull Lighttpd 1434
bull PHP 557
bull MariaDB 5534
For communication postfix and mosquitto are needed additionally
37
Shop Documentation Release 001
154 Setup infrastructure
1541 Configuration management
For the creation of reproducable and identical environment for the development and the run-time across differentsystems Ansible is used as configuration management solution All needed steps of the installation are automated Theconfiguration doesnrsquot differentiate between local or remote installations This matters only for the deployment of theweb content
For local development itrsquos possible to use an LX container
$ sudo ansible-playbook develcontaineryml
To get everything running some additional steps (check the network inside the container generate keys etc) areneeded After you are done check it
$ sudo ansible webshop -m setup
From the management system
$ sudo ssh-copy-id -i rootsshid_rsapub root[IP address of your managed node]
The configuration of Ansible itself (adding the system to etcansiblehosts and copying the SSH keys) isnot documented at this place There are various resources available like here All playbooks are located in the folderdevel Start the setup with the command shown below
$ sudo ansible-playbook develsetupyml
The used group name in etcansiblehosts is webshop
If the setup completes without errors then the web server is accessible and show a default page Please keep in mindthat the server is only accessible over https unencrypted traffic is not allowed
1542 DeploymentSetup website
For the simple deployment of the lastest version of the shop a playbook called deployyml is provided Thisplaybook put all files in place
$ sudo ansible-playbook develdeployyml
To full deploy the webshop all tables in the database must exist The file webshopsql contains all needed SQLcommands and sample data for the web application
Itrsquos possible to deploy the website manually but this is not recommended A couple of files are depending on templateswhich are created during the deployment
Itrsquos also not recommanded to clone everything into your webserver root This would save you the trouble of doing itby hand but third-party features are missing then Those missing parts are the template engine the pdf generation theconnection to Openstreetmap and probably other things not mentioned here
155 Git respository
All project relevante informations (Source code templates documentation etc) is located in a public Git repositoryon Github
38 Kapitel 15 Development
Shop Documentation Release 001
156 Documentation
The documentation is using reStructuredText as markup language For a local build Sphinx is needed Sphinx isavailable in the Fedora Package Collection and can be installed with yum or any other package management tool
yum -y install python-sphinx python-docutils
The source files of the documentation are located under docs
$ cd docs$ make html
The output is stored under docs_buildhtml
After every push to Github a hook launch a rebuild of the documentation The latest release will be published on Readthe Docs automatically
httpsshoprtfdorg
156 Documentation 39
Shop Documentation Release 001
40 Kapitel 15 Development
KAPITEL 16
Indices and tables
bull genindex
bull modindex
bull search
41
- Basics
-
- Products
- Personas
- Use cases
- Design principles
-
- Web shop Design
-
- General
- Layout
- Sitemap
- Main page
-
- Style and design
-
- Cascading Style Sheets
- Pages
-
- Dynamics
-
- Setup
- Current year
- Navigation Menu
- List of Products
- Company details
-
- External files
-
- Navigation Menu
- Header
- Footer
-
- Input processing
-
- ``Buy Now links
- Select options
-
- Javascript
-
- Simple use case
-
- Cookies and Sessions
-
- Cookies
- Hit counter
- Language selection
- User Accounts
-
- Database
-
- Tables
- PHP
-
- Web service
-
- Map
- Weather
-
- Data export
-
- JSON
-
- Messaging
-
- MQTT
-
- Localisation (L10n)
- Templates
-
- Template
- Content
-
- Development
-
- Web server
- Database server
- Versions
- Setup infrastructure
- Git respository
- Documentation
-
- Indices and tables
-
KAPITEL 1
Basics
11 Products
The Web shop will be for selling pencils in various types
Categories
bull Standard pencils
bull Mechnical pencils
bull Special pencils
Variants or options
bull Color (red yellow black white etc)
bull Hardness (standard HB hard F H 2H soft B 2B)
bull Additional function (Eraser at the end Protection cap handle)
111 Product overview
(The product names are in German because the main language of the shop will not be English)
3
Shop Documentation Release 001
Type Variant Color Hardness Price CHFBleistift keine rot HB 1Bleistift keine rot B 1Bleistift keine rot 2B 1Bleistift keine gelb F 120Bleistift keine gelb H 120Bleistift keine gelb 2H 120Bleistift Gummi rot HB 110Schreiner-Bleistift keine rot HB 180Schreiner-Bleistift keine rot B 180Bleistift keine rot HB 05Bleistift Gummi rot HB 06Kuumlnstler-Bleistift Griff gelb 2B 2Kuumlnstler-Bleistift Griff rot 2B 2Kuumlnstler-Bleistift Griff schwarz 2B 2Minien-Bleistift keine weiss 4Minien-Bleistift keine blau 4Minien-Bleistift keine gelb 4Minien-Bleistift keine rot 4Minien-Bleistift keine silber 9Minien-Bleistift keine schwarz 9
12 Personas
The following personas are defined to interact with the web shop
121 Major customer
Eva is responsible for the ordering of office supplies in her joinery She is ordering twice a month a large amount ofvarious product for different users (management back office and production) Eva has a fix budget for the orders andshe knows her way around web shops
122 End user
Hugo is an architect and middle aged He is drawing sketches and technical drawings but also artistically demandingpieces by hand Thanks to the work with CAD he decovers the web and its advantages Before he bought all his toolsin a local stationery nowadays he is ordering stuff online
13 Use cases
The shop will be stripped-down to two use cases With those use cases are all major use cases with only little modifi-cations covered The use cases for the shop adimistration will be considered out of scope
131 Major customer
bull Ordering of a large amount of one single products or several products
bull Volume discount
4 Kapitel 1 Basics
Shop Documentation Release 001
bull Splitting of oders (ev delivery to different locations)
132 End user
bull Ordering of single products
bull Small quantities
14 Design principles
The below listed points are the fundation for the implementation of the design and the layout to the shop
bull Products should be in the spot light
bull Reduced to the essentials (typography colors fonts etc)
bull meaningful use of whitespaces
Instead of reinventing the wheel it should be considered to use a matured front-end framework like bootstrap for thelayout especially regarding responsive design
14 Design principles 5
Shop Documentation Release 001
6 Kapitel 1 Basics
KAPITEL 2
Web shop Design
21 General
The used company and all data are notional There is no exisiting connection to any existing company with the sameor similar name
211 Company name
The company name is Pencil AG
212 Address
The complete address of the company is
Pencil AGMusterstrasse 13000 BernSchweiz
213 Logo
The logo used in this project is borrowed from the Tango project icon set The file is out of the categories section thefile name of the origin file is applications-officesvg and is licensed under Public Domain
22 Layout
The layout is splitted in different sections The content of the elements especially of the main section (content) willbe definied by the later usage of the page
7
Shop Documentation Release 001
23 Sitemap
The sitemap shows the clustering of the shop at the beginning of the project
This doesnrsquot mean that everything will be done Static pages are easy to make and to maintain
8 Kapitel 2 Web shop Design
Shop Documentation Release 001
24 Main page
The first draft of the main page is based on the prototype shown in section Layout without any format- und styleinformationen
ltDOCTYPE htmlgtlthtml lang=engt
ltheadgtltmeta charset=utf-8gtltmeta name=viewport content=width=device-width initial-scale=10gtltmeta name=description content=Webshop Pencil AG fuumlr Bleistiftegtltmeta name=author content=Fabian AffoltergtlttitlegtWebshop Pencil AG | Homelttitlegt
ltheadgt
ltbodygtlt-- Header container--gtltdivgt
ltdivgtlt-- Logo and company name --gtltimg src=logologopnggtlth2gtWebshop Pencil AGlth2gtlt-- Navigation --gtltulgt
ltligtlta href=gtHomeltagtltligtltligtlta href=gtProdukteltagtltligtltligtlta href=gtUumlber unsltagtltligt
ltulgtlt-- Breadcrumb --gtltolgt
ltligtlta href=gtEbene 1ltagtltligtltligtlta href=gtEbene 2ltagtltligtltligtlta href=gtEbene 3ltagtltligt
ltolgtltdivgt
ltdivgtlt-- Header container--gt
lt-- Action container --gtltdivgt
lth1gtWochen-Aktionlth1gtltpgtDies ist eine super Aktion 10 Bleistifte fuumlr CHF 8ltpgt
ltdivgtlt-- Action container --gt
lt-- Selected products --gtltdivgt
ltpgtHier hat es zufaumlllige Produkteltpgtltdivgtlt-- Selected products --gt
lt-- Footer --gtltdivgt
ltpgtampcopy Pencil AG 2013ltpgtlt-- Footer --gtltdivgt
ltbodygtlthtmlgt
24 Main page 9
Shop Documentation Release 001
Loaded in a browser the initial draft of the main page looks like in the following screenshot
10 Kapitel 2 Web shop Design
KAPITEL 3
Style and design
31 Cascading Style Sheets
The design of the shop will be nothing fancy The approach which was choosen will reflect the points mentioned inthe Design principles section and makes heavy use of the bootstrap framework cascading style sheet Various changesto this CSS file ensure that it matche the needs of this project
32 Pages
The product page show the elements mentioned in the Product overview section
11
Shop Documentation Release 001
12 Kapitel 3 Style and design
KAPITEL 4
Dynamics
The webshop will be a PHP application at the end Those first steps are only covering the very basic stuff of PHP asan introduction
41 Setup
The setupyml playbook puts a simple PHP file in the root directory of the web server with the namephpinfophp This file displays PHP details
Achtung Remove this file before makeing the shop accessible by a public audience
42 Current year
The first PHP element in the webshop is showing the current year in the footer of every page With the help of thislittle piece of code there is no longer a need to update the year
ltphp echo date(Y) gt
43 Navigation Menu
The basic menu was built with the following snippet
ltphp$menu = array(rsquoHomersquo =gt rsquoindexphprsquo
rsquoProduktersquo =gt rsquoproductsphprsquorsquoUumlber unsrsquo =gt rsquoaboutphprsquo
)foreach($menu as $label =gt $link)
echo rsquoltligtlta href=rsquo $link rsquogtrsquo $label rsquoltagtltligtrsquo
gt
The issue with that snippet was that the CSS class was missing In regards to a future separation and reusability anadditional statements was added This way the label of the active page is highlighted
13
Shop Documentation Release 001
ltphp$menu = array(rsquoHomersquo =gt rsquoindexphprsquo
rsquoProduktersquo =gt rsquoproductsphprsquorsquoUumlber unsrsquo =gt rsquoaboutphprsquo
)foreach ($menu as $label =gt $link)
$url = trim($_SERVER[rsquoPHP_SELFrsquo] rsquorsquo)if ($link == $url)
echo rsquoltli class=activegtlta href=rsquo $link rsquogtrsquo $label rsquoltagtltligtrsquo else
echo rsquoltli class=gtlta href=rsquo $link rsquogtrsquo $label rsquoltagtltligtrsquo
gt
44 List of Products
The product overiew is a simple table The heading of the table is placed in an array
ltdivgtlttable class=table table-stripedgtltthead valign=bottomgtlttrgtltphp
$heading = array(rsquoTypersquo rsquoVariantrsquo rsquoColorrsquo rsquoHardnessrsquo rsquoPrice CHFrsquo)foreach ($heading as $element)
echo rsquoltth class=headgtrsquo$elementrsquoltthgtrsquon
gtlttrgtlttheadgtlttbody valign=topgtltphp
$products = array(array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquoHBrsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquoBrsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquo2Brsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquoFrsquo rsquo12rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquoHrsquo rsquo12rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquo2Hrsquo rsquo12rsquo)
)foreach ($products as $product =gt $details)
echo lttrgtforeach ($details as $detail)
echo lttdgt$detaillttdgtecho lttrgt
gtlttbodygtlttablegt
ltdivgt
14 Kapitel 4 Dynamics
Shop Documentation Release 001
45 Company details
The data for the About page are included out of a static and plain text file
ltphp$str = file_get_contents(companytxt)echo $str
gt
45 Company details 15
Shop Documentation Release 001
16 Kapitel 4 Dynamics
KAPITEL 5
External files
51 Navigation Menu
The menu is outsourced in the file menuphp
ltphpfunction menu()
$part1 = rsquoltul class=nav nav-tabsgtrsquon$part2 = rsquorsquo$part3 = rsquoltulgtrsquon Menu array with page title and assigned file$menu = array(rsquoHomersquo =gt rsquoindexphprsquo
rsquoProduktersquo =gt rsquoproductsphprsquorsquoUumlber unsrsquo =gt rsquoaboutphprsquo
)foreach ($menu as $label =gt $link)
For the CSS only the file name without is needed$url = trim($_SERVER[rsquoPHP_SELFrsquo] rsquorsquo)if ($link == $url)
$part2 = $part2ltli class=rsquoactiversquogtlta href=rsquo$linkrsquogt$labelltagtltligtn else
$part2 = $part2ltli class=rsquorsquogtlta href=rsquo$linkrsquogt$labelltagtltligtn
return $part1$part2$part3
gt
52 Header
The complete header part is loaded from the file headerphp
ltphpfunction head()
$start_page = indexphp$part1 = ltdivgtn$part2 = tlta class=rsquobrand-logorsquo href=rsquo$start_pagersquogtltagtn$part3 = tltp class=rsquobrand-namersquogtWebshop Pencil AGltpgtn$part4 = ltdivgtnreturn $part1$part2$part3$part4
17
Shop Documentation Release 001
gt
53 Footer
The same is done witht the page footers
ltphpfunction foot()
$class1 = rsquoltdiv class=footergtrsquon$class2 = rsquoltdivgtrsquon$text = ltpgtampcopy Pencil AG getYear()rsquoltpgtrsquonreturn $class1$text$class2
function getYear()return date(Y)
gt
18 Kapitel 5 External files
KAPITEL 6
Input processing
61 ldquoBuy Nowrdquo links
The ldquoBuy Nowrdquo links are attached to the Products page Every entry has itrsquos own link which lead to a detail page Thelinks are using hidden form elements to transfer the data
ltphp$products = array(array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquoHBrsquo rsquo1rsquo)
array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquoBrsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquo2Brsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquoFrsquo rsquo12rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquoHrsquo rsquo12rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquo2Hrsquo rsquo12rsquo)
)foreach ($products as $product =gt $details)
echo lttrgtnforeach ($details as $detail)
echo lttdgt$detaillttdgtnecho lttdgtnecho ltform action=rsquoproductphprsquo method=rsquogetrsquo name=rsquopencilrsquogtnecho ltinput type=rsquohiddenrsquo name=rsquotypersquo value=rsquo$details[0]rsquogtnecho ltinput type=rsquohiddenrsquo name=rsquooptionsrsquo value=rsquo$details[1]rsquogtnecho ltinput type=rsquohiddenrsquo name=rsquocolorrsquo value=rsquo$details[2]rsquogtnecho ltinput type=rsquohiddenrsquo name=rsquohardnessrsquo value=rsquo$details[3]rsquogtnecho ltinput type=rsquohiddenrsquo name=rsquopricersquo value=rsquo$details[4]rsquogtnecho ltinput type=rsquosubmitrsquo class=rsquobtn btn-defaultrsquo value=rsquoKauf michrsquogtnecho ltformgtnecho lttdgtnecho lttrgtn
gt
And the detail page contains the code fragement mentioned below
ltphp$type=$_GET[rsquotypersquo]$color=$_GET[rsquocolorrsquo]$hardness=$_GET[rsquohardnessrsquo]$options=$_GET[rsquooptionsrsquo]$price=$_GET[rsquopricersquo]echo I am a $type in $color and a hardness of $hardness I have $options as an option and my price is $price CHF
gt
19
Shop Documentation Release 001
Bemerkung The Products page was modified in the process of the development
62 Select options
The signupbilling page contains a dropdown element that all days of a month for the entry of the userrsquos birthday
ltselect name=daygtltoptiongtDayltoptiongt
ltphp$days = range(31 1)foreach ($days as $day)
echo rsquoltoption value=rsquo$dayrsquogtrsquo$dayrsquoltoptiongtrsquo
gtltselectgt
20 Kapitel 6 Input processing
KAPITEL 7
Javascript
Over the years Javascript became a very popular programming language The webshop is using Javascript at a coupleof places
71 Simple use case
Javascript makes it easy to access elements in the DOM Setting the focus is a nice way to support the user with inputform
ltscript language=javascriptgtfunction setFocus()
documentforms[login][username]focus()
ltscriptgtltheadgtltbody onload=setFocus()gt
Another one is to check if something was entered in an input field
function validateForm() var username = documentforms[rdquologinrdquo][rdquousernamerdquo]value if (username== null || username == ldquordquo)
documentforms[rdquologinrdquo][rdquousernamerdquo]stylebackgroundColor = ldquoFF9999rdquo docu-mentforms[rdquologinrdquo][rdquousernamerdquo]placeholder = ldquoPlease your usernamerdquo docu-mentforms[rdquologinrdquo][rdquousernamerdquo]focus() return false
A simple message is informing the user about an action which was taken against the database
echo ltscript type=textjavascriptgtalert(New entry $entry added successfully)windowlocation = tablesphp
ltscriptgt
The delete process is only executed if the user confirm to delete a record
ltform action=scriptsdelete-processphp onSubmit=return confirm(rsquoAre you sure to delete this entryrsquo) method=POSTgtltinput type=hidden name=table value=$sectiongtltinput type=hidden name=id value=$result-gtidgtltinput type=submit name=Submit value=Deletegt
ltformgt
For additional Javascript please check the source of the indexphp file and the reflsquowebservicelsquo_ section
21
Shop Documentation Release 001
22 Kapitel 7 Javascript
KAPITEL 8
Cookies and Sessions
The built-in support for sessions in PHP is handling all cookie manipulation to provide persistent variables that areaccessible from different pages and across multiple visits to the site
81 Cookies
A cookie is used to track the last time a visitor check the front page The cookie is set when a visitor arrives
function lastVisit($name $expire) $value = getDateDMY() - getTimeHM()setcookie($name $value time() + $expire rsquorsquo $_SERVER[rsquoSERVER_NAMErsquo] true true)
In the footer of the index page the details are presented
ltphpif(isset($_COOKIE[rsquoLastVisitrsquo]))
$last = $_COOKIE[rsquoLastVisitrsquo]echo You last visited us on $last
else echo This is your first visit
gt
82 Hit counter
As a simple show case for PHP sessions a hit counter for the front page is available
ltphpsession_start()
$_SESSION[rsquohitsrsquo] = $_SESSION[rsquohitsrsquo] + 1gt
Included in the footer it shous the users the total of visits
echo Total $_SESSION[rsquohitsrsquo] visits of this page
23
Shop Documentation Release 001
83 Language selection
84 User Accounts
24 Kapitel 8 Cookies and Sessions
KAPITEL 9
Database
The database backend for the webshop will be MariaDB which is the drop-in replacement for MySQL
For the setup please check the Development section in this documentation
91 Tables
The following tables are needed for the webshop to work
bull products
bull customers
bull pencils
bull colors
bull hardness
bull options
bull users
Please use the develwebshopsql to setup the database
92 PHP
Below you find the configuration file for a default installation of the webshop This file is a template and filled duringthe setup process
ltphp$host = localhost$user = root$password = webshop$dbase = webshop$connection = new mysqli($host $user $password $dbase)
if ($connection-gtconnect_errno) echo Failed to connect to MariaDBMySQL ($connection-gtconnect_errno) $connection-gtconnect_error
mysqli_report(MYSQLI_REPORT_ERROR)
gt
25
Shop Documentation Release 001
All connections to the database are done in the same way Below you find an example Everything is done in theobject-oriented style
ltphprequire_once(rsquoconfigdbconnectphprsquo)if ($connection-gtconnect_errno == 0)
$sql = SELECT FROM products$results = $connection-gtquery($sql)echo $results-gtnum_rows$results-gtclose()
else echo Database connection error
gt
26 Kapitel 9 Database
KAPITEL 10
Web service
Tow web services are integrated to take advantages of online available data sources
101 Map
Leafletjs a JavaScript library for working with interactive maps from OpenStreetMap (OSM) is implemented as ashow case for a simple web service
The basic steps to integrate a map is shown below
ltdiv id=map class=map style=width 600px height 400pxgtltdivgt
ltscript src=scriptsleafletjsgtltscriptgtltscript src=scriptsleaflet-providersjsgtltscriptgtltscriptgtvar map = Lmap(rsquomaprsquo
center [250472 -773255]zoom 12zoomControl true
)
var defaultLayer = LtileLayerprovider(rsquoOpenStreetMapMapnikrsquo)addTo(map)ltscriptgt
102 Weather
The OpenWeatherMap service provides free weather data and a forecast API for web applications
ltphp Details about the API httpbugsopenweathermaporgprojectsapiwikiApi_2_5_weather$url = rsquohttpapiopenweathermaporgdata25weatherq=Bernechampunit=metricsampmode=jsonrsquo
$json = file_get_contents($url)$data = json_decode($json)
$tempC = round((27315 - $data-gtmain-gttemp)100) 100$humidity = $data-gtmain-gthumidity$pressure = $data-gtmain-gtpressure
27
Shop Documentation Release 001
echo ltpgtTemperatur $tempC degCltbrgtnecho Luftfeuchtigkeit $humidity ltbrgtnecho Luftdruck $pressure Paltpgtn
gt
28 Kapitel 10 Web service
KAPITEL 11
Data export
111 PDF
FPDF is a PHP class that allows to generate PDF files with pure PHP As a showcase for that the product specificationsfor a given product are filled in a pdf and showed in the browser The user can then decide to download or print thefile
112 JSON
JavaScript Object Notation (JSON) is a lightweight data-interchange format The format is language independent andPHP support the encoding and the decoding JSON with json_encode($data) and json_decode($data)$rows = array()$sql = SELECT FROM products$results = $connection-gtquery($sql)while ($result = $results-gtfetch_object())
$rows[] = $result$results-gtclose()
Writing all rows to a JSON file$fp = fopen(rsquopencilsjsonrsquo rsquowrsquo)fwrite($fp json_encode($rows))fclose($fp)gt
and for reading it
ltphp$json = file_get_contents(rsquopencilsjsonrsquo)print_r(json_decode($json))
gt
29
Shop Documentation Release 001
30 Kapitel 11 Data export
KAPITEL 12
Messaging
Beside standard email messages the webshop supports sending MQ Telemetry Transport protocol (MQTT) messagesas an additional feature The MQTT messages are small
121 MQTT
Mosquitto-PHP is used as a PHP wrapper for MQTT Please check the Projectrsquos README for details about theinstallation and the setup
1211 Broker
Mosquitto is a message broker that implements the MQ Telemetry Transport protocol Check if mosquitto is run-ning
$ sudo systemctl status mosquittoservice
If not start it
$ systemctl start mosquittoservice
All messages are published to the topic webshop
1212 Publishing
After the installation of Mosquitto-PHP the snipplet shown below sends a single message
ltphpdefine(rsquoBROKERrsquo rsquolocalhostrsquo)define(rsquoPORTrsquo 1883)define(rsquoCLIENT_IDrsquo webshop_ + getmypid())$topic = webshop$subtopic = test$completeTopic = $topic$subtopic
$client = new MosquittoClient(CLIENT_ID)$client-gtconnect(BROKER PORT 60)
$message = Test message from webshop at date(Y-m-d His)$client-gtpublish($completeTopic $message 0 false)
gt
31
Shop Documentation Release 001
1213 Subscribing
To read the messages sent by the webshop a client is needed The Mosquitto broker contain a simple command-linetool for subscribing to various topics
$ mosquitto_sub -h localhost -t webshop
122 Email
This section doesnrsquot describe the installation and configuration of a local MTA There are enough resources thatcontains information about the setup of postfix for local delivery only
If you want to test the email feature add the following code in one of PHP pages
ltphp mail(rsquorootlocalhostrsquo rsquoTest message from webshoprsquo rsquoThe webshop is selling pencilsrsquo) gt
By default SELinux is running in Enforcing mode which is restrictive about about what a web server can do Toallow sending email the following SELinux boolean needs to changed
setsebool -P httpd_can_network_connect=1 setsebool -P httpd_can_sendmail=1
32 Kapitel 12 Messaging
KAPITEL 13
Localisation (L10n)
There are several ways to add localisation to a web site For small projects arrays with string can work but this is notvery efficient and user-friendly With Gettext is a toolset available that provide a framework to produce multi-lingualcontent in a wide area of programming languages
Make sure that the php-gettext package is available on your system If not install it
$ sudo yum -y install php-php-gettext
Check if gettext support is available
ltphpif (function_exists(gettext))
echo gettext is not installednelse
echo gettext is supportedn
gt
Make sure that all locales your want are available on the server
locale -a
The first step is to mark all string which should be translatable as shown below For further details please refer to theGettext documentation
echo _(rsquoSome textrsquo)
The next step is to extract all strings
xgettext --from-code=UTF-8 -o localewebshoppot php scriptsphp
To re-generate the file after an update join the strings
xgettext -j --from-code=UTF-8 -o localewebshoppot php scriptsphp
For every language a po file is needed for the transations Generate it with the command mentioned below
msginit --no-translator -l de_CH -o localede_CHpo -i localewebshoppot
Once created there are only updates of the message catalog needed in the futures
msgmerge -U localede_CHpo localewebshoppot
If you re finish create the mo file for the specific language
33
Shop Documentation Release 001
msgfmt -c -v -o localede_CHLC_MESSAGESwebshopmo localede_CHpo
34 Kapitel 13 Localisation (L10n)
KAPITEL 14
Templates
Beside other solutions Savant3 is a lightweight object-oriented template system for PHP This solution does not needa lot of additional configuration
141 Template
A simple template file looks like the one shown below
lthtmlgtltheadgt
lttitlegtltphp echo $this-gteprint($this-gttitle) gtlttitlegtltheadgtltbodygt
ltphp echo $this-gteprint($this-gtcontent) gtltbodygt
lthtmlgt
For a more detailed intro check this article on Zend Developer Zone
142 Content
To fill the template with data all wished variables needs to be defined in a seperate PHP file
ltphprequire_once rsquoscriptsSavant3phprsquo$tpl = new Savant3()
Create a title$title = Simple sample page
Create the content of the page$content = Some sample text to show
Assign values to the Savant instance$tpl-gttitle = $title$tpl-gtcontent = $content
Define the template source file to show$tpl-gtdisplay(rsquosimpletplphprsquo)
gt
35
Shop Documentation Release 001
The webshop contains a page (master)
36 Kapitel 14 Templates
KAPITEL 15
Development
This sections describes the configuration of the development and runtime environment for the web shop
151 Web server
Instead of Apache the project is running on Lighttpd The reasons are that Lighttpd provides faster setup easierconfiguration and better performance Lighttpd is running with FastCGI
The path of the web server is varwwwlighttpd and the SELinux configuration are still the defaults
The web server is running in SSL-only mode and the certificate is generated during the server setup process
152 Database server
For persistence storage the drop-in replacement MariaDB is used MySQL will work to but this is not tested phpMyAd-min is available under phpmyadmin on the web server beside the command-line tools for easy administration
The default credentials for phpMyAdmin are rootwebshop or the entry you made in the Ansible playbookdevelvariablessensitiveyml
153 Versions
The web shop is built with the below listed components and tested Other releases can be used and may work but thiswill not be tested Probably it will work with different releases
bull Operating system Fedora 20
bull Kernel 3135-202fc20x86_64
bull Lighttpd 1434
bull PHP 557
bull MariaDB 5534
For communication postfix and mosquitto are needed additionally
37
Shop Documentation Release 001
154 Setup infrastructure
1541 Configuration management
For the creation of reproducable and identical environment for the development and the run-time across differentsystems Ansible is used as configuration management solution All needed steps of the installation are automated Theconfiguration doesnrsquot differentiate between local or remote installations This matters only for the deployment of theweb content
For local development itrsquos possible to use an LX container
$ sudo ansible-playbook develcontaineryml
To get everything running some additional steps (check the network inside the container generate keys etc) areneeded After you are done check it
$ sudo ansible webshop -m setup
From the management system
$ sudo ssh-copy-id -i rootsshid_rsapub root[IP address of your managed node]
The configuration of Ansible itself (adding the system to etcansiblehosts and copying the SSH keys) isnot documented at this place There are various resources available like here All playbooks are located in the folderdevel Start the setup with the command shown below
$ sudo ansible-playbook develsetupyml
The used group name in etcansiblehosts is webshop
If the setup completes without errors then the web server is accessible and show a default page Please keep in mindthat the server is only accessible over https unencrypted traffic is not allowed
1542 DeploymentSetup website
For the simple deployment of the lastest version of the shop a playbook called deployyml is provided Thisplaybook put all files in place
$ sudo ansible-playbook develdeployyml
To full deploy the webshop all tables in the database must exist The file webshopsql contains all needed SQLcommands and sample data for the web application
Itrsquos possible to deploy the website manually but this is not recommended A couple of files are depending on templateswhich are created during the deployment
Itrsquos also not recommanded to clone everything into your webserver root This would save you the trouble of doing itby hand but third-party features are missing then Those missing parts are the template engine the pdf generation theconnection to Openstreetmap and probably other things not mentioned here
155 Git respository
All project relevante informations (Source code templates documentation etc) is located in a public Git repositoryon Github
38 Kapitel 15 Development
Shop Documentation Release 001
156 Documentation
The documentation is using reStructuredText as markup language For a local build Sphinx is needed Sphinx isavailable in the Fedora Package Collection and can be installed with yum or any other package management tool
yum -y install python-sphinx python-docutils
The source files of the documentation are located under docs
$ cd docs$ make html
The output is stored under docs_buildhtml
After every push to Github a hook launch a rebuild of the documentation The latest release will be published on Readthe Docs automatically
httpsshoprtfdorg
156 Documentation 39
Shop Documentation Release 001
40 Kapitel 15 Development
KAPITEL 16
Indices and tables
bull genindex
bull modindex
bull search
41
- Basics
-
- Products
- Personas
- Use cases
- Design principles
-
- Web shop Design
-
- General
- Layout
- Sitemap
- Main page
-
- Style and design
-
- Cascading Style Sheets
- Pages
-
- Dynamics
-
- Setup
- Current year
- Navigation Menu
- List of Products
- Company details
-
- External files
-
- Navigation Menu
- Header
- Footer
-
- Input processing
-
- ``Buy Now links
- Select options
-
- Javascript
-
- Simple use case
-
- Cookies and Sessions
-
- Cookies
- Hit counter
- Language selection
- User Accounts
-
- Database
-
- Tables
- PHP
-
- Web service
-
- Map
- Weather
-
- Data export
-
- JSON
-
- Messaging
-
- MQTT
-
- Localisation (L10n)
- Templates
-
- Template
- Content
-
- Development
-
- Web server
- Database server
- Versions
- Setup infrastructure
- Git respository
- Documentation
-
- Indices and tables
-
Shop Documentation Release 001
Type Variant Color Hardness Price CHFBleistift keine rot HB 1Bleistift keine rot B 1Bleistift keine rot 2B 1Bleistift keine gelb F 120Bleistift keine gelb H 120Bleistift keine gelb 2H 120Bleistift Gummi rot HB 110Schreiner-Bleistift keine rot HB 180Schreiner-Bleistift keine rot B 180Bleistift keine rot HB 05Bleistift Gummi rot HB 06Kuumlnstler-Bleistift Griff gelb 2B 2Kuumlnstler-Bleistift Griff rot 2B 2Kuumlnstler-Bleistift Griff schwarz 2B 2Minien-Bleistift keine weiss 4Minien-Bleistift keine blau 4Minien-Bleistift keine gelb 4Minien-Bleistift keine rot 4Minien-Bleistift keine silber 9Minien-Bleistift keine schwarz 9
12 Personas
The following personas are defined to interact with the web shop
121 Major customer
Eva is responsible for the ordering of office supplies in her joinery She is ordering twice a month a large amount ofvarious product for different users (management back office and production) Eva has a fix budget for the orders andshe knows her way around web shops
122 End user
Hugo is an architect and middle aged He is drawing sketches and technical drawings but also artistically demandingpieces by hand Thanks to the work with CAD he decovers the web and its advantages Before he bought all his toolsin a local stationery nowadays he is ordering stuff online
13 Use cases
The shop will be stripped-down to two use cases With those use cases are all major use cases with only little modifi-cations covered The use cases for the shop adimistration will be considered out of scope
131 Major customer
bull Ordering of a large amount of one single products or several products
bull Volume discount
4 Kapitel 1 Basics
Shop Documentation Release 001
bull Splitting of oders (ev delivery to different locations)
132 End user
bull Ordering of single products
bull Small quantities
14 Design principles
The below listed points are the fundation for the implementation of the design and the layout to the shop
bull Products should be in the spot light
bull Reduced to the essentials (typography colors fonts etc)
bull meaningful use of whitespaces
Instead of reinventing the wheel it should be considered to use a matured front-end framework like bootstrap for thelayout especially regarding responsive design
14 Design principles 5
Shop Documentation Release 001
6 Kapitel 1 Basics
KAPITEL 2
Web shop Design
21 General
The used company and all data are notional There is no exisiting connection to any existing company with the sameor similar name
211 Company name
The company name is Pencil AG
212 Address
The complete address of the company is
Pencil AGMusterstrasse 13000 BernSchweiz
213 Logo
The logo used in this project is borrowed from the Tango project icon set The file is out of the categories section thefile name of the origin file is applications-officesvg and is licensed under Public Domain
22 Layout
The layout is splitted in different sections The content of the elements especially of the main section (content) willbe definied by the later usage of the page
7
Shop Documentation Release 001
23 Sitemap
The sitemap shows the clustering of the shop at the beginning of the project
This doesnrsquot mean that everything will be done Static pages are easy to make and to maintain
8 Kapitel 2 Web shop Design
Shop Documentation Release 001
24 Main page
The first draft of the main page is based on the prototype shown in section Layout without any format- und styleinformationen
ltDOCTYPE htmlgtlthtml lang=engt
ltheadgtltmeta charset=utf-8gtltmeta name=viewport content=width=device-width initial-scale=10gtltmeta name=description content=Webshop Pencil AG fuumlr Bleistiftegtltmeta name=author content=Fabian AffoltergtlttitlegtWebshop Pencil AG | Homelttitlegt
ltheadgt
ltbodygtlt-- Header container--gtltdivgt
ltdivgtlt-- Logo and company name --gtltimg src=logologopnggtlth2gtWebshop Pencil AGlth2gtlt-- Navigation --gtltulgt
ltligtlta href=gtHomeltagtltligtltligtlta href=gtProdukteltagtltligtltligtlta href=gtUumlber unsltagtltligt
ltulgtlt-- Breadcrumb --gtltolgt
ltligtlta href=gtEbene 1ltagtltligtltligtlta href=gtEbene 2ltagtltligtltligtlta href=gtEbene 3ltagtltligt
ltolgtltdivgt
ltdivgtlt-- Header container--gt
lt-- Action container --gtltdivgt
lth1gtWochen-Aktionlth1gtltpgtDies ist eine super Aktion 10 Bleistifte fuumlr CHF 8ltpgt
ltdivgtlt-- Action container --gt
lt-- Selected products --gtltdivgt
ltpgtHier hat es zufaumlllige Produkteltpgtltdivgtlt-- Selected products --gt
lt-- Footer --gtltdivgt
ltpgtampcopy Pencil AG 2013ltpgtlt-- Footer --gtltdivgt
ltbodygtlthtmlgt
24 Main page 9
Shop Documentation Release 001
Loaded in a browser the initial draft of the main page looks like in the following screenshot
10 Kapitel 2 Web shop Design
KAPITEL 3
Style and design
31 Cascading Style Sheets
The design of the shop will be nothing fancy The approach which was choosen will reflect the points mentioned inthe Design principles section and makes heavy use of the bootstrap framework cascading style sheet Various changesto this CSS file ensure that it matche the needs of this project
32 Pages
The product page show the elements mentioned in the Product overview section
11
Shop Documentation Release 001
12 Kapitel 3 Style and design
KAPITEL 4
Dynamics
The webshop will be a PHP application at the end Those first steps are only covering the very basic stuff of PHP asan introduction
41 Setup
The setupyml playbook puts a simple PHP file in the root directory of the web server with the namephpinfophp This file displays PHP details
Achtung Remove this file before makeing the shop accessible by a public audience
42 Current year
The first PHP element in the webshop is showing the current year in the footer of every page With the help of thislittle piece of code there is no longer a need to update the year
ltphp echo date(Y) gt
43 Navigation Menu
The basic menu was built with the following snippet
ltphp$menu = array(rsquoHomersquo =gt rsquoindexphprsquo
rsquoProduktersquo =gt rsquoproductsphprsquorsquoUumlber unsrsquo =gt rsquoaboutphprsquo
)foreach($menu as $label =gt $link)
echo rsquoltligtlta href=rsquo $link rsquogtrsquo $label rsquoltagtltligtrsquo
gt
The issue with that snippet was that the CSS class was missing In regards to a future separation and reusability anadditional statements was added This way the label of the active page is highlighted
13
Shop Documentation Release 001
ltphp$menu = array(rsquoHomersquo =gt rsquoindexphprsquo
rsquoProduktersquo =gt rsquoproductsphprsquorsquoUumlber unsrsquo =gt rsquoaboutphprsquo
)foreach ($menu as $label =gt $link)
$url = trim($_SERVER[rsquoPHP_SELFrsquo] rsquorsquo)if ($link == $url)
echo rsquoltli class=activegtlta href=rsquo $link rsquogtrsquo $label rsquoltagtltligtrsquo else
echo rsquoltli class=gtlta href=rsquo $link rsquogtrsquo $label rsquoltagtltligtrsquo
gt
44 List of Products
The product overiew is a simple table The heading of the table is placed in an array
ltdivgtlttable class=table table-stripedgtltthead valign=bottomgtlttrgtltphp
$heading = array(rsquoTypersquo rsquoVariantrsquo rsquoColorrsquo rsquoHardnessrsquo rsquoPrice CHFrsquo)foreach ($heading as $element)
echo rsquoltth class=headgtrsquo$elementrsquoltthgtrsquon
gtlttrgtlttheadgtlttbody valign=topgtltphp
$products = array(array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquoHBrsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquoBrsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquo2Brsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquoFrsquo rsquo12rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquoHrsquo rsquo12rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquo2Hrsquo rsquo12rsquo)
)foreach ($products as $product =gt $details)
echo lttrgtforeach ($details as $detail)
echo lttdgt$detaillttdgtecho lttrgt
gtlttbodygtlttablegt
ltdivgt
14 Kapitel 4 Dynamics
Shop Documentation Release 001
45 Company details
The data for the About page are included out of a static and plain text file
ltphp$str = file_get_contents(companytxt)echo $str
gt
45 Company details 15
Shop Documentation Release 001
16 Kapitel 4 Dynamics
KAPITEL 5
External files
51 Navigation Menu
The menu is outsourced in the file menuphp
ltphpfunction menu()
$part1 = rsquoltul class=nav nav-tabsgtrsquon$part2 = rsquorsquo$part3 = rsquoltulgtrsquon Menu array with page title and assigned file$menu = array(rsquoHomersquo =gt rsquoindexphprsquo
rsquoProduktersquo =gt rsquoproductsphprsquorsquoUumlber unsrsquo =gt rsquoaboutphprsquo
)foreach ($menu as $label =gt $link)
For the CSS only the file name without is needed$url = trim($_SERVER[rsquoPHP_SELFrsquo] rsquorsquo)if ($link == $url)
$part2 = $part2ltli class=rsquoactiversquogtlta href=rsquo$linkrsquogt$labelltagtltligtn else
$part2 = $part2ltli class=rsquorsquogtlta href=rsquo$linkrsquogt$labelltagtltligtn
return $part1$part2$part3
gt
52 Header
The complete header part is loaded from the file headerphp
ltphpfunction head()
$start_page = indexphp$part1 = ltdivgtn$part2 = tlta class=rsquobrand-logorsquo href=rsquo$start_pagersquogtltagtn$part3 = tltp class=rsquobrand-namersquogtWebshop Pencil AGltpgtn$part4 = ltdivgtnreturn $part1$part2$part3$part4
17
Shop Documentation Release 001
gt
53 Footer
The same is done witht the page footers
ltphpfunction foot()
$class1 = rsquoltdiv class=footergtrsquon$class2 = rsquoltdivgtrsquon$text = ltpgtampcopy Pencil AG getYear()rsquoltpgtrsquonreturn $class1$text$class2
function getYear()return date(Y)
gt
18 Kapitel 5 External files
KAPITEL 6
Input processing
61 ldquoBuy Nowrdquo links
The ldquoBuy Nowrdquo links are attached to the Products page Every entry has itrsquos own link which lead to a detail page Thelinks are using hidden form elements to transfer the data
ltphp$products = array(array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquoHBrsquo rsquo1rsquo)
array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquoBrsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquo2Brsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquoFrsquo rsquo12rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquoHrsquo rsquo12rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquo2Hrsquo rsquo12rsquo)
)foreach ($products as $product =gt $details)
echo lttrgtnforeach ($details as $detail)
echo lttdgt$detaillttdgtnecho lttdgtnecho ltform action=rsquoproductphprsquo method=rsquogetrsquo name=rsquopencilrsquogtnecho ltinput type=rsquohiddenrsquo name=rsquotypersquo value=rsquo$details[0]rsquogtnecho ltinput type=rsquohiddenrsquo name=rsquooptionsrsquo value=rsquo$details[1]rsquogtnecho ltinput type=rsquohiddenrsquo name=rsquocolorrsquo value=rsquo$details[2]rsquogtnecho ltinput type=rsquohiddenrsquo name=rsquohardnessrsquo value=rsquo$details[3]rsquogtnecho ltinput type=rsquohiddenrsquo name=rsquopricersquo value=rsquo$details[4]rsquogtnecho ltinput type=rsquosubmitrsquo class=rsquobtn btn-defaultrsquo value=rsquoKauf michrsquogtnecho ltformgtnecho lttdgtnecho lttrgtn
gt
And the detail page contains the code fragement mentioned below
ltphp$type=$_GET[rsquotypersquo]$color=$_GET[rsquocolorrsquo]$hardness=$_GET[rsquohardnessrsquo]$options=$_GET[rsquooptionsrsquo]$price=$_GET[rsquopricersquo]echo I am a $type in $color and a hardness of $hardness I have $options as an option and my price is $price CHF
gt
19
Shop Documentation Release 001
Bemerkung The Products page was modified in the process of the development
62 Select options
The signupbilling page contains a dropdown element that all days of a month for the entry of the userrsquos birthday
ltselect name=daygtltoptiongtDayltoptiongt
ltphp$days = range(31 1)foreach ($days as $day)
echo rsquoltoption value=rsquo$dayrsquogtrsquo$dayrsquoltoptiongtrsquo
gtltselectgt
20 Kapitel 6 Input processing
KAPITEL 7
Javascript
Over the years Javascript became a very popular programming language The webshop is using Javascript at a coupleof places
71 Simple use case
Javascript makes it easy to access elements in the DOM Setting the focus is a nice way to support the user with inputform
ltscript language=javascriptgtfunction setFocus()
documentforms[login][username]focus()
ltscriptgtltheadgtltbody onload=setFocus()gt
Another one is to check if something was entered in an input field
function validateForm() var username = documentforms[rdquologinrdquo][rdquousernamerdquo]value if (username== null || username == ldquordquo)
documentforms[rdquologinrdquo][rdquousernamerdquo]stylebackgroundColor = ldquoFF9999rdquo docu-mentforms[rdquologinrdquo][rdquousernamerdquo]placeholder = ldquoPlease your usernamerdquo docu-mentforms[rdquologinrdquo][rdquousernamerdquo]focus() return false
A simple message is informing the user about an action which was taken against the database
echo ltscript type=textjavascriptgtalert(New entry $entry added successfully)windowlocation = tablesphp
ltscriptgt
The delete process is only executed if the user confirm to delete a record
ltform action=scriptsdelete-processphp onSubmit=return confirm(rsquoAre you sure to delete this entryrsquo) method=POSTgtltinput type=hidden name=table value=$sectiongtltinput type=hidden name=id value=$result-gtidgtltinput type=submit name=Submit value=Deletegt
ltformgt
For additional Javascript please check the source of the indexphp file and the reflsquowebservicelsquo_ section
21
Shop Documentation Release 001
22 Kapitel 7 Javascript
KAPITEL 8
Cookies and Sessions
The built-in support for sessions in PHP is handling all cookie manipulation to provide persistent variables that areaccessible from different pages and across multiple visits to the site
81 Cookies
A cookie is used to track the last time a visitor check the front page The cookie is set when a visitor arrives
function lastVisit($name $expire) $value = getDateDMY() - getTimeHM()setcookie($name $value time() + $expire rsquorsquo $_SERVER[rsquoSERVER_NAMErsquo] true true)
In the footer of the index page the details are presented
ltphpif(isset($_COOKIE[rsquoLastVisitrsquo]))
$last = $_COOKIE[rsquoLastVisitrsquo]echo You last visited us on $last
else echo This is your first visit
gt
82 Hit counter
As a simple show case for PHP sessions a hit counter for the front page is available
ltphpsession_start()
$_SESSION[rsquohitsrsquo] = $_SESSION[rsquohitsrsquo] + 1gt
Included in the footer it shous the users the total of visits
echo Total $_SESSION[rsquohitsrsquo] visits of this page
23
Shop Documentation Release 001
83 Language selection
84 User Accounts
24 Kapitel 8 Cookies and Sessions
KAPITEL 9
Database
The database backend for the webshop will be MariaDB which is the drop-in replacement for MySQL
For the setup please check the Development section in this documentation
91 Tables
The following tables are needed for the webshop to work
bull products
bull customers
bull pencils
bull colors
bull hardness
bull options
bull users
Please use the develwebshopsql to setup the database
92 PHP
Below you find the configuration file for a default installation of the webshop This file is a template and filled duringthe setup process
ltphp$host = localhost$user = root$password = webshop$dbase = webshop$connection = new mysqli($host $user $password $dbase)
if ($connection-gtconnect_errno) echo Failed to connect to MariaDBMySQL ($connection-gtconnect_errno) $connection-gtconnect_error
mysqli_report(MYSQLI_REPORT_ERROR)
gt
25
Shop Documentation Release 001
All connections to the database are done in the same way Below you find an example Everything is done in theobject-oriented style
ltphprequire_once(rsquoconfigdbconnectphprsquo)if ($connection-gtconnect_errno == 0)
$sql = SELECT FROM products$results = $connection-gtquery($sql)echo $results-gtnum_rows$results-gtclose()
else echo Database connection error
gt
26 Kapitel 9 Database
KAPITEL 10
Web service
Tow web services are integrated to take advantages of online available data sources
101 Map
Leafletjs a JavaScript library for working with interactive maps from OpenStreetMap (OSM) is implemented as ashow case for a simple web service
The basic steps to integrate a map is shown below
ltdiv id=map class=map style=width 600px height 400pxgtltdivgt
ltscript src=scriptsleafletjsgtltscriptgtltscript src=scriptsleaflet-providersjsgtltscriptgtltscriptgtvar map = Lmap(rsquomaprsquo
center [250472 -773255]zoom 12zoomControl true
)
var defaultLayer = LtileLayerprovider(rsquoOpenStreetMapMapnikrsquo)addTo(map)ltscriptgt
102 Weather
The OpenWeatherMap service provides free weather data and a forecast API for web applications
ltphp Details about the API httpbugsopenweathermaporgprojectsapiwikiApi_2_5_weather$url = rsquohttpapiopenweathermaporgdata25weatherq=Bernechampunit=metricsampmode=jsonrsquo
$json = file_get_contents($url)$data = json_decode($json)
$tempC = round((27315 - $data-gtmain-gttemp)100) 100$humidity = $data-gtmain-gthumidity$pressure = $data-gtmain-gtpressure
27
Shop Documentation Release 001
echo ltpgtTemperatur $tempC degCltbrgtnecho Luftfeuchtigkeit $humidity ltbrgtnecho Luftdruck $pressure Paltpgtn
gt
28 Kapitel 10 Web service
KAPITEL 11
Data export
111 PDF
FPDF is a PHP class that allows to generate PDF files with pure PHP As a showcase for that the product specificationsfor a given product are filled in a pdf and showed in the browser The user can then decide to download or print thefile
112 JSON
JavaScript Object Notation (JSON) is a lightweight data-interchange format The format is language independent andPHP support the encoding and the decoding JSON with json_encode($data) and json_decode($data)$rows = array()$sql = SELECT FROM products$results = $connection-gtquery($sql)while ($result = $results-gtfetch_object())
$rows[] = $result$results-gtclose()
Writing all rows to a JSON file$fp = fopen(rsquopencilsjsonrsquo rsquowrsquo)fwrite($fp json_encode($rows))fclose($fp)gt
and for reading it
ltphp$json = file_get_contents(rsquopencilsjsonrsquo)print_r(json_decode($json))
gt
29
Shop Documentation Release 001
30 Kapitel 11 Data export
KAPITEL 12
Messaging
Beside standard email messages the webshop supports sending MQ Telemetry Transport protocol (MQTT) messagesas an additional feature The MQTT messages are small
121 MQTT
Mosquitto-PHP is used as a PHP wrapper for MQTT Please check the Projectrsquos README for details about theinstallation and the setup
1211 Broker
Mosquitto is a message broker that implements the MQ Telemetry Transport protocol Check if mosquitto is run-ning
$ sudo systemctl status mosquittoservice
If not start it
$ systemctl start mosquittoservice
All messages are published to the topic webshop
1212 Publishing
After the installation of Mosquitto-PHP the snipplet shown below sends a single message
ltphpdefine(rsquoBROKERrsquo rsquolocalhostrsquo)define(rsquoPORTrsquo 1883)define(rsquoCLIENT_IDrsquo webshop_ + getmypid())$topic = webshop$subtopic = test$completeTopic = $topic$subtopic
$client = new MosquittoClient(CLIENT_ID)$client-gtconnect(BROKER PORT 60)
$message = Test message from webshop at date(Y-m-d His)$client-gtpublish($completeTopic $message 0 false)
gt
31
Shop Documentation Release 001
1213 Subscribing
To read the messages sent by the webshop a client is needed The Mosquitto broker contain a simple command-linetool for subscribing to various topics
$ mosquitto_sub -h localhost -t webshop
122 Email
This section doesnrsquot describe the installation and configuration of a local MTA There are enough resources thatcontains information about the setup of postfix for local delivery only
If you want to test the email feature add the following code in one of PHP pages
ltphp mail(rsquorootlocalhostrsquo rsquoTest message from webshoprsquo rsquoThe webshop is selling pencilsrsquo) gt
By default SELinux is running in Enforcing mode which is restrictive about about what a web server can do Toallow sending email the following SELinux boolean needs to changed
setsebool -P httpd_can_network_connect=1 setsebool -P httpd_can_sendmail=1
32 Kapitel 12 Messaging
KAPITEL 13
Localisation (L10n)
There are several ways to add localisation to a web site For small projects arrays with string can work but this is notvery efficient and user-friendly With Gettext is a toolset available that provide a framework to produce multi-lingualcontent in a wide area of programming languages
Make sure that the php-gettext package is available on your system If not install it
$ sudo yum -y install php-php-gettext
Check if gettext support is available
ltphpif (function_exists(gettext))
echo gettext is not installednelse
echo gettext is supportedn
gt
Make sure that all locales your want are available on the server
locale -a
The first step is to mark all string which should be translatable as shown below For further details please refer to theGettext documentation
echo _(rsquoSome textrsquo)
The next step is to extract all strings
xgettext --from-code=UTF-8 -o localewebshoppot php scriptsphp
To re-generate the file after an update join the strings
xgettext -j --from-code=UTF-8 -o localewebshoppot php scriptsphp
For every language a po file is needed for the transations Generate it with the command mentioned below
msginit --no-translator -l de_CH -o localede_CHpo -i localewebshoppot
Once created there are only updates of the message catalog needed in the futures
msgmerge -U localede_CHpo localewebshoppot
If you re finish create the mo file for the specific language
33
Shop Documentation Release 001
msgfmt -c -v -o localede_CHLC_MESSAGESwebshopmo localede_CHpo
34 Kapitel 13 Localisation (L10n)
KAPITEL 14
Templates
Beside other solutions Savant3 is a lightweight object-oriented template system for PHP This solution does not needa lot of additional configuration
141 Template
A simple template file looks like the one shown below
lthtmlgtltheadgt
lttitlegtltphp echo $this-gteprint($this-gttitle) gtlttitlegtltheadgtltbodygt
ltphp echo $this-gteprint($this-gtcontent) gtltbodygt
lthtmlgt
For a more detailed intro check this article on Zend Developer Zone
142 Content
To fill the template with data all wished variables needs to be defined in a seperate PHP file
ltphprequire_once rsquoscriptsSavant3phprsquo$tpl = new Savant3()
Create a title$title = Simple sample page
Create the content of the page$content = Some sample text to show
Assign values to the Savant instance$tpl-gttitle = $title$tpl-gtcontent = $content
Define the template source file to show$tpl-gtdisplay(rsquosimpletplphprsquo)
gt
35
Shop Documentation Release 001
The webshop contains a page (master)
36 Kapitel 14 Templates
KAPITEL 15
Development
This sections describes the configuration of the development and runtime environment for the web shop
151 Web server
Instead of Apache the project is running on Lighttpd The reasons are that Lighttpd provides faster setup easierconfiguration and better performance Lighttpd is running with FastCGI
The path of the web server is varwwwlighttpd and the SELinux configuration are still the defaults
The web server is running in SSL-only mode and the certificate is generated during the server setup process
152 Database server
For persistence storage the drop-in replacement MariaDB is used MySQL will work to but this is not tested phpMyAd-min is available under phpmyadmin on the web server beside the command-line tools for easy administration
The default credentials for phpMyAdmin are rootwebshop or the entry you made in the Ansible playbookdevelvariablessensitiveyml
153 Versions
The web shop is built with the below listed components and tested Other releases can be used and may work but thiswill not be tested Probably it will work with different releases
bull Operating system Fedora 20
bull Kernel 3135-202fc20x86_64
bull Lighttpd 1434
bull PHP 557
bull MariaDB 5534
For communication postfix and mosquitto are needed additionally
37
Shop Documentation Release 001
154 Setup infrastructure
1541 Configuration management
For the creation of reproducable and identical environment for the development and the run-time across differentsystems Ansible is used as configuration management solution All needed steps of the installation are automated Theconfiguration doesnrsquot differentiate between local or remote installations This matters only for the deployment of theweb content
For local development itrsquos possible to use an LX container
$ sudo ansible-playbook develcontaineryml
To get everything running some additional steps (check the network inside the container generate keys etc) areneeded After you are done check it
$ sudo ansible webshop -m setup
From the management system
$ sudo ssh-copy-id -i rootsshid_rsapub root[IP address of your managed node]
The configuration of Ansible itself (adding the system to etcansiblehosts and copying the SSH keys) isnot documented at this place There are various resources available like here All playbooks are located in the folderdevel Start the setup with the command shown below
$ sudo ansible-playbook develsetupyml
The used group name in etcansiblehosts is webshop
If the setup completes without errors then the web server is accessible and show a default page Please keep in mindthat the server is only accessible over https unencrypted traffic is not allowed
1542 DeploymentSetup website
For the simple deployment of the lastest version of the shop a playbook called deployyml is provided Thisplaybook put all files in place
$ sudo ansible-playbook develdeployyml
To full deploy the webshop all tables in the database must exist The file webshopsql contains all needed SQLcommands and sample data for the web application
Itrsquos possible to deploy the website manually but this is not recommended A couple of files are depending on templateswhich are created during the deployment
Itrsquos also not recommanded to clone everything into your webserver root This would save you the trouble of doing itby hand but third-party features are missing then Those missing parts are the template engine the pdf generation theconnection to Openstreetmap and probably other things not mentioned here
155 Git respository
All project relevante informations (Source code templates documentation etc) is located in a public Git repositoryon Github
38 Kapitel 15 Development
Shop Documentation Release 001
156 Documentation
The documentation is using reStructuredText as markup language For a local build Sphinx is needed Sphinx isavailable in the Fedora Package Collection and can be installed with yum or any other package management tool
yum -y install python-sphinx python-docutils
The source files of the documentation are located under docs
$ cd docs$ make html
The output is stored under docs_buildhtml
After every push to Github a hook launch a rebuild of the documentation The latest release will be published on Readthe Docs automatically
httpsshoprtfdorg
156 Documentation 39
Shop Documentation Release 001
40 Kapitel 15 Development
KAPITEL 16
Indices and tables
bull genindex
bull modindex
bull search
41
- Basics
-
- Products
- Personas
- Use cases
- Design principles
-
- Web shop Design
-
- General
- Layout
- Sitemap
- Main page
-
- Style and design
-
- Cascading Style Sheets
- Pages
-
- Dynamics
-
- Setup
- Current year
- Navigation Menu
- List of Products
- Company details
-
- External files
-
- Navigation Menu
- Header
- Footer
-
- Input processing
-
- ``Buy Now links
- Select options
-
- Javascript
-
- Simple use case
-
- Cookies and Sessions
-
- Cookies
- Hit counter
- Language selection
- User Accounts
-
- Database
-
- Tables
- PHP
-
- Web service
-
- Map
- Weather
-
- Data export
-
- JSON
-
- Messaging
-
- MQTT
-
- Localisation (L10n)
- Templates
-
- Template
- Content
-
- Development
-
- Web server
- Database server
- Versions
- Setup infrastructure
- Git respository
- Documentation
-
- Indices and tables
-
Shop Documentation Release 001
bull Splitting of oders (ev delivery to different locations)
132 End user
bull Ordering of single products
bull Small quantities
14 Design principles
The below listed points are the fundation for the implementation of the design and the layout to the shop
bull Products should be in the spot light
bull Reduced to the essentials (typography colors fonts etc)
bull meaningful use of whitespaces
Instead of reinventing the wheel it should be considered to use a matured front-end framework like bootstrap for thelayout especially regarding responsive design
14 Design principles 5
Shop Documentation Release 001
6 Kapitel 1 Basics
KAPITEL 2
Web shop Design
21 General
The used company and all data are notional There is no exisiting connection to any existing company with the sameor similar name
211 Company name
The company name is Pencil AG
212 Address
The complete address of the company is
Pencil AGMusterstrasse 13000 BernSchweiz
213 Logo
The logo used in this project is borrowed from the Tango project icon set The file is out of the categories section thefile name of the origin file is applications-officesvg and is licensed under Public Domain
22 Layout
The layout is splitted in different sections The content of the elements especially of the main section (content) willbe definied by the later usage of the page
7
Shop Documentation Release 001
23 Sitemap
The sitemap shows the clustering of the shop at the beginning of the project
This doesnrsquot mean that everything will be done Static pages are easy to make and to maintain
8 Kapitel 2 Web shop Design
Shop Documentation Release 001
24 Main page
The first draft of the main page is based on the prototype shown in section Layout without any format- und styleinformationen
ltDOCTYPE htmlgtlthtml lang=engt
ltheadgtltmeta charset=utf-8gtltmeta name=viewport content=width=device-width initial-scale=10gtltmeta name=description content=Webshop Pencil AG fuumlr Bleistiftegtltmeta name=author content=Fabian AffoltergtlttitlegtWebshop Pencil AG | Homelttitlegt
ltheadgt
ltbodygtlt-- Header container--gtltdivgt
ltdivgtlt-- Logo and company name --gtltimg src=logologopnggtlth2gtWebshop Pencil AGlth2gtlt-- Navigation --gtltulgt
ltligtlta href=gtHomeltagtltligtltligtlta href=gtProdukteltagtltligtltligtlta href=gtUumlber unsltagtltligt
ltulgtlt-- Breadcrumb --gtltolgt
ltligtlta href=gtEbene 1ltagtltligtltligtlta href=gtEbene 2ltagtltligtltligtlta href=gtEbene 3ltagtltligt
ltolgtltdivgt
ltdivgtlt-- Header container--gt
lt-- Action container --gtltdivgt
lth1gtWochen-Aktionlth1gtltpgtDies ist eine super Aktion 10 Bleistifte fuumlr CHF 8ltpgt
ltdivgtlt-- Action container --gt
lt-- Selected products --gtltdivgt
ltpgtHier hat es zufaumlllige Produkteltpgtltdivgtlt-- Selected products --gt
lt-- Footer --gtltdivgt
ltpgtampcopy Pencil AG 2013ltpgtlt-- Footer --gtltdivgt
ltbodygtlthtmlgt
24 Main page 9
Shop Documentation Release 001
Loaded in a browser the initial draft of the main page looks like in the following screenshot
10 Kapitel 2 Web shop Design
KAPITEL 3
Style and design
31 Cascading Style Sheets
The design of the shop will be nothing fancy The approach which was choosen will reflect the points mentioned inthe Design principles section and makes heavy use of the bootstrap framework cascading style sheet Various changesto this CSS file ensure that it matche the needs of this project
32 Pages
The product page show the elements mentioned in the Product overview section
11
Shop Documentation Release 001
12 Kapitel 3 Style and design
KAPITEL 4
Dynamics
The webshop will be a PHP application at the end Those first steps are only covering the very basic stuff of PHP asan introduction
41 Setup
The setupyml playbook puts a simple PHP file in the root directory of the web server with the namephpinfophp This file displays PHP details
Achtung Remove this file before makeing the shop accessible by a public audience
42 Current year
The first PHP element in the webshop is showing the current year in the footer of every page With the help of thislittle piece of code there is no longer a need to update the year
ltphp echo date(Y) gt
43 Navigation Menu
The basic menu was built with the following snippet
ltphp$menu = array(rsquoHomersquo =gt rsquoindexphprsquo
rsquoProduktersquo =gt rsquoproductsphprsquorsquoUumlber unsrsquo =gt rsquoaboutphprsquo
)foreach($menu as $label =gt $link)
echo rsquoltligtlta href=rsquo $link rsquogtrsquo $label rsquoltagtltligtrsquo
gt
The issue with that snippet was that the CSS class was missing In regards to a future separation and reusability anadditional statements was added This way the label of the active page is highlighted
13
Shop Documentation Release 001
ltphp$menu = array(rsquoHomersquo =gt rsquoindexphprsquo
rsquoProduktersquo =gt rsquoproductsphprsquorsquoUumlber unsrsquo =gt rsquoaboutphprsquo
)foreach ($menu as $label =gt $link)
$url = trim($_SERVER[rsquoPHP_SELFrsquo] rsquorsquo)if ($link == $url)
echo rsquoltli class=activegtlta href=rsquo $link rsquogtrsquo $label rsquoltagtltligtrsquo else
echo rsquoltli class=gtlta href=rsquo $link rsquogtrsquo $label rsquoltagtltligtrsquo
gt
44 List of Products
The product overiew is a simple table The heading of the table is placed in an array
ltdivgtlttable class=table table-stripedgtltthead valign=bottomgtlttrgtltphp
$heading = array(rsquoTypersquo rsquoVariantrsquo rsquoColorrsquo rsquoHardnessrsquo rsquoPrice CHFrsquo)foreach ($heading as $element)
echo rsquoltth class=headgtrsquo$elementrsquoltthgtrsquon
gtlttrgtlttheadgtlttbody valign=topgtltphp
$products = array(array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquoHBrsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquoBrsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquo2Brsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquoFrsquo rsquo12rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquoHrsquo rsquo12rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquo2Hrsquo rsquo12rsquo)
)foreach ($products as $product =gt $details)
echo lttrgtforeach ($details as $detail)
echo lttdgt$detaillttdgtecho lttrgt
gtlttbodygtlttablegt
ltdivgt
14 Kapitel 4 Dynamics
Shop Documentation Release 001
45 Company details
The data for the About page are included out of a static and plain text file
ltphp$str = file_get_contents(companytxt)echo $str
gt
45 Company details 15
Shop Documentation Release 001
16 Kapitel 4 Dynamics
KAPITEL 5
External files
51 Navigation Menu
The menu is outsourced in the file menuphp
ltphpfunction menu()
$part1 = rsquoltul class=nav nav-tabsgtrsquon$part2 = rsquorsquo$part3 = rsquoltulgtrsquon Menu array with page title and assigned file$menu = array(rsquoHomersquo =gt rsquoindexphprsquo
rsquoProduktersquo =gt rsquoproductsphprsquorsquoUumlber unsrsquo =gt rsquoaboutphprsquo
)foreach ($menu as $label =gt $link)
For the CSS only the file name without is needed$url = trim($_SERVER[rsquoPHP_SELFrsquo] rsquorsquo)if ($link == $url)
$part2 = $part2ltli class=rsquoactiversquogtlta href=rsquo$linkrsquogt$labelltagtltligtn else
$part2 = $part2ltli class=rsquorsquogtlta href=rsquo$linkrsquogt$labelltagtltligtn
return $part1$part2$part3
gt
52 Header
The complete header part is loaded from the file headerphp
ltphpfunction head()
$start_page = indexphp$part1 = ltdivgtn$part2 = tlta class=rsquobrand-logorsquo href=rsquo$start_pagersquogtltagtn$part3 = tltp class=rsquobrand-namersquogtWebshop Pencil AGltpgtn$part4 = ltdivgtnreturn $part1$part2$part3$part4
17
Shop Documentation Release 001
gt
53 Footer
The same is done witht the page footers
ltphpfunction foot()
$class1 = rsquoltdiv class=footergtrsquon$class2 = rsquoltdivgtrsquon$text = ltpgtampcopy Pencil AG getYear()rsquoltpgtrsquonreturn $class1$text$class2
function getYear()return date(Y)
gt
18 Kapitel 5 External files
KAPITEL 6
Input processing
61 ldquoBuy Nowrdquo links
The ldquoBuy Nowrdquo links are attached to the Products page Every entry has itrsquos own link which lead to a detail page Thelinks are using hidden form elements to transfer the data
ltphp$products = array(array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquoHBrsquo rsquo1rsquo)
array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquoBrsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquo2Brsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquoFrsquo rsquo12rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquoHrsquo rsquo12rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquo2Hrsquo rsquo12rsquo)
)foreach ($products as $product =gt $details)
echo lttrgtnforeach ($details as $detail)
echo lttdgt$detaillttdgtnecho lttdgtnecho ltform action=rsquoproductphprsquo method=rsquogetrsquo name=rsquopencilrsquogtnecho ltinput type=rsquohiddenrsquo name=rsquotypersquo value=rsquo$details[0]rsquogtnecho ltinput type=rsquohiddenrsquo name=rsquooptionsrsquo value=rsquo$details[1]rsquogtnecho ltinput type=rsquohiddenrsquo name=rsquocolorrsquo value=rsquo$details[2]rsquogtnecho ltinput type=rsquohiddenrsquo name=rsquohardnessrsquo value=rsquo$details[3]rsquogtnecho ltinput type=rsquohiddenrsquo name=rsquopricersquo value=rsquo$details[4]rsquogtnecho ltinput type=rsquosubmitrsquo class=rsquobtn btn-defaultrsquo value=rsquoKauf michrsquogtnecho ltformgtnecho lttdgtnecho lttrgtn
gt
And the detail page contains the code fragement mentioned below
ltphp$type=$_GET[rsquotypersquo]$color=$_GET[rsquocolorrsquo]$hardness=$_GET[rsquohardnessrsquo]$options=$_GET[rsquooptionsrsquo]$price=$_GET[rsquopricersquo]echo I am a $type in $color and a hardness of $hardness I have $options as an option and my price is $price CHF
gt
19
Shop Documentation Release 001
Bemerkung The Products page was modified in the process of the development
62 Select options
The signupbilling page contains a dropdown element that all days of a month for the entry of the userrsquos birthday
ltselect name=daygtltoptiongtDayltoptiongt
ltphp$days = range(31 1)foreach ($days as $day)
echo rsquoltoption value=rsquo$dayrsquogtrsquo$dayrsquoltoptiongtrsquo
gtltselectgt
20 Kapitel 6 Input processing
KAPITEL 7
Javascript
Over the years Javascript became a very popular programming language The webshop is using Javascript at a coupleof places
71 Simple use case
Javascript makes it easy to access elements in the DOM Setting the focus is a nice way to support the user with inputform
ltscript language=javascriptgtfunction setFocus()
documentforms[login][username]focus()
ltscriptgtltheadgtltbody onload=setFocus()gt
Another one is to check if something was entered in an input field
function validateForm() var username = documentforms[rdquologinrdquo][rdquousernamerdquo]value if (username== null || username == ldquordquo)
documentforms[rdquologinrdquo][rdquousernamerdquo]stylebackgroundColor = ldquoFF9999rdquo docu-mentforms[rdquologinrdquo][rdquousernamerdquo]placeholder = ldquoPlease your usernamerdquo docu-mentforms[rdquologinrdquo][rdquousernamerdquo]focus() return false
A simple message is informing the user about an action which was taken against the database
echo ltscript type=textjavascriptgtalert(New entry $entry added successfully)windowlocation = tablesphp
ltscriptgt
The delete process is only executed if the user confirm to delete a record
ltform action=scriptsdelete-processphp onSubmit=return confirm(rsquoAre you sure to delete this entryrsquo) method=POSTgtltinput type=hidden name=table value=$sectiongtltinput type=hidden name=id value=$result-gtidgtltinput type=submit name=Submit value=Deletegt
ltformgt
For additional Javascript please check the source of the indexphp file and the reflsquowebservicelsquo_ section
21
Shop Documentation Release 001
22 Kapitel 7 Javascript
KAPITEL 8
Cookies and Sessions
The built-in support for sessions in PHP is handling all cookie manipulation to provide persistent variables that areaccessible from different pages and across multiple visits to the site
81 Cookies
A cookie is used to track the last time a visitor check the front page The cookie is set when a visitor arrives
function lastVisit($name $expire) $value = getDateDMY() - getTimeHM()setcookie($name $value time() + $expire rsquorsquo $_SERVER[rsquoSERVER_NAMErsquo] true true)
In the footer of the index page the details are presented
ltphpif(isset($_COOKIE[rsquoLastVisitrsquo]))
$last = $_COOKIE[rsquoLastVisitrsquo]echo You last visited us on $last
else echo This is your first visit
gt
82 Hit counter
As a simple show case for PHP sessions a hit counter for the front page is available
ltphpsession_start()
$_SESSION[rsquohitsrsquo] = $_SESSION[rsquohitsrsquo] + 1gt
Included in the footer it shous the users the total of visits
echo Total $_SESSION[rsquohitsrsquo] visits of this page
23
Shop Documentation Release 001
83 Language selection
84 User Accounts
24 Kapitel 8 Cookies and Sessions
KAPITEL 9
Database
The database backend for the webshop will be MariaDB which is the drop-in replacement for MySQL
For the setup please check the Development section in this documentation
91 Tables
The following tables are needed for the webshop to work
bull products
bull customers
bull pencils
bull colors
bull hardness
bull options
bull users
Please use the develwebshopsql to setup the database
92 PHP
Below you find the configuration file for a default installation of the webshop This file is a template and filled duringthe setup process
ltphp$host = localhost$user = root$password = webshop$dbase = webshop$connection = new mysqli($host $user $password $dbase)
if ($connection-gtconnect_errno) echo Failed to connect to MariaDBMySQL ($connection-gtconnect_errno) $connection-gtconnect_error
mysqli_report(MYSQLI_REPORT_ERROR)
gt
25
Shop Documentation Release 001
All connections to the database are done in the same way Below you find an example Everything is done in theobject-oriented style
ltphprequire_once(rsquoconfigdbconnectphprsquo)if ($connection-gtconnect_errno == 0)
$sql = SELECT FROM products$results = $connection-gtquery($sql)echo $results-gtnum_rows$results-gtclose()
else echo Database connection error
gt
26 Kapitel 9 Database
KAPITEL 10
Web service
Tow web services are integrated to take advantages of online available data sources
101 Map
Leafletjs a JavaScript library for working with interactive maps from OpenStreetMap (OSM) is implemented as ashow case for a simple web service
The basic steps to integrate a map is shown below
ltdiv id=map class=map style=width 600px height 400pxgtltdivgt
ltscript src=scriptsleafletjsgtltscriptgtltscript src=scriptsleaflet-providersjsgtltscriptgtltscriptgtvar map = Lmap(rsquomaprsquo
center [250472 -773255]zoom 12zoomControl true
)
var defaultLayer = LtileLayerprovider(rsquoOpenStreetMapMapnikrsquo)addTo(map)ltscriptgt
102 Weather
The OpenWeatherMap service provides free weather data and a forecast API for web applications
ltphp Details about the API httpbugsopenweathermaporgprojectsapiwikiApi_2_5_weather$url = rsquohttpapiopenweathermaporgdata25weatherq=Bernechampunit=metricsampmode=jsonrsquo
$json = file_get_contents($url)$data = json_decode($json)
$tempC = round((27315 - $data-gtmain-gttemp)100) 100$humidity = $data-gtmain-gthumidity$pressure = $data-gtmain-gtpressure
27
Shop Documentation Release 001
echo ltpgtTemperatur $tempC degCltbrgtnecho Luftfeuchtigkeit $humidity ltbrgtnecho Luftdruck $pressure Paltpgtn
gt
28 Kapitel 10 Web service
KAPITEL 11
Data export
111 PDF
FPDF is a PHP class that allows to generate PDF files with pure PHP As a showcase for that the product specificationsfor a given product are filled in a pdf and showed in the browser The user can then decide to download or print thefile
112 JSON
JavaScript Object Notation (JSON) is a lightweight data-interchange format The format is language independent andPHP support the encoding and the decoding JSON with json_encode($data) and json_decode($data)$rows = array()$sql = SELECT FROM products$results = $connection-gtquery($sql)while ($result = $results-gtfetch_object())
$rows[] = $result$results-gtclose()
Writing all rows to a JSON file$fp = fopen(rsquopencilsjsonrsquo rsquowrsquo)fwrite($fp json_encode($rows))fclose($fp)gt
and for reading it
ltphp$json = file_get_contents(rsquopencilsjsonrsquo)print_r(json_decode($json))
gt
29
Shop Documentation Release 001
30 Kapitel 11 Data export
KAPITEL 12
Messaging
Beside standard email messages the webshop supports sending MQ Telemetry Transport protocol (MQTT) messagesas an additional feature The MQTT messages are small
121 MQTT
Mosquitto-PHP is used as a PHP wrapper for MQTT Please check the Projectrsquos README for details about theinstallation and the setup
1211 Broker
Mosquitto is a message broker that implements the MQ Telemetry Transport protocol Check if mosquitto is run-ning
$ sudo systemctl status mosquittoservice
If not start it
$ systemctl start mosquittoservice
All messages are published to the topic webshop
1212 Publishing
After the installation of Mosquitto-PHP the snipplet shown below sends a single message
ltphpdefine(rsquoBROKERrsquo rsquolocalhostrsquo)define(rsquoPORTrsquo 1883)define(rsquoCLIENT_IDrsquo webshop_ + getmypid())$topic = webshop$subtopic = test$completeTopic = $topic$subtopic
$client = new MosquittoClient(CLIENT_ID)$client-gtconnect(BROKER PORT 60)
$message = Test message from webshop at date(Y-m-d His)$client-gtpublish($completeTopic $message 0 false)
gt
31
Shop Documentation Release 001
1213 Subscribing
To read the messages sent by the webshop a client is needed The Mosquitto broker contain a simple command-linetool for subscribing to various topics
$ mosquitto_sub -h localhost -t webshop
122 Email
This section doesnrsquot describe the installation and configuration of a local MTA There are enough resources thatcontains information about the setup of postfix for local delivery only
If you want to test the email feature add the following code in one of PHP pages
ltphp mail(rsquorootlocalhostrsquo rsquoTest message from webshoprsquo rsquoThe webshop is selling pencilsrsquo) gt
By default SELinux is running in Enforcing mode which is restrictive about about what a web server can do Toallow sending email the following SELinux boolean needs to changed
setsebool -P httpd_can_network_connect=1 setsebool -P httpd_can_sendmail=1
32 Kapitel 12 Messaging
KAPITEL 13
Localisation (L10n)
There are several ways to add localisation to a web site For small projects arrays with string can work but this is notvery efficient and user-friendly With Gettext is a toolset available that provide a framework to produce multi-lingualcontent in a wide area of programming languages
Make sure that the php-gettext package is available on your system If not install it
$ sudo yum -y install php-php-gettext
Check if gettext support is available
ltphpif (function_exists(gettext))
echo gettext is not installednelse
echo gettext is supportedn
gt
Make sure that all locales your want are available on the server
locale -a
The first step is to mark all string which should be translatable as shown below For further details please refer to theGettext documentation
echo _(rsquoSome textrsquo)
The next step is to extract all strings
xgettext --from-code=UTF-8 -o localewebshoppot php scriptsphp
To re-generate the file after an update join the strings
xgettext -j --from-code=UTF-8 -o localewebshoppot php scriptsphp
For every language a po file is needed for the transations Generate it with the command mentioned below
msginit --no-translator -l de_CH -o localede_CHpo -i localewebshoppot
Once created there are only updates of the message catalog needed in the futures
msgmerge -U localede_CHpo localewebshoppot
If you re finish create the mo file for the specific language
33
Shop Documentation Release 001
msgfmt -c -v -o localede_CHLC_MESSAGESwebshopmo localede_CHpo
34 Kapitel 13 Localisation (L10n)
KAPITEL 14
Templates
Beside other solutions Savant3 is a lightweight object-oriented template system for PHP This solution does not needa lot of additional configuration
141 Template
A simple template file looks like the one shown below
lthtmlgtltheadgt
lttitlegtltphp echo $this-gteprint($this-gttitle) gtlttitlegtltheadgtltbodygt
ltphp echo $this-gteprint($this-gtcontent) gtltbodygt
lthtmlgt
For a more detailed intro check this article on Zend Developer Zone
142 Content
To fill the template with data all wished variables needs to be defined in a seperate PHP file
ltphprequire_once rsquoscriptsSavant3phprsquo$tpl = new Savant3()
Create a title$title = Simple sample page
Create the content of the page$content = Some sample text to show
Assign values to the Savant instance$tpl-gttitle = $title$tpl-gtcontent = $content
Define the template source file to show$tpl-gtdisplay(rsquosimpletplphprsquo)
gt
35
Shop Documentation Release 001
The webshop contains a page (master)
36 Kapitel 14 Templates
KAPITEL 15
Development
This sections describes the configuration of the development and runtime environment for the web shop
151 Web server
Instead of Apache the project is running on Lighttpd The reasons are that Lighttpd provides faster setup easierconfiguration and better performance Lighttpd is running with FastCGI
The path of the web server is varwwwlighttpd and the SELinux configuration are still the defaults
The web server is running in SSL-only mode and the certificate is generated during the server setup process
152 Database server
For persistence storage the drop-in replacement MariaDB is used MySQL will work to but this is not tested phpMyAd-min is available under phpmyadmin on the web server beside the command-line tools for easy administration
The default credentials for phpMyAdmin are rootwebshop or the entry you made in the Ansible playbookdevelvariablessensitiveyml
153 Versions
The web shop is built with the below listed components and tested Other releases can be used and may work but thiswill not be tested Probably it will work with different releases
bull Operating system Fedora 20
bull Kernel 3135-202fc20x86_64
bull Lighttpd 1434
bull PHP 557
bull MariaDB 5534
For communication postfix and mosquitto are needed additionally
37
Shop Documentation Release 001
154 Setup infrastructure
1541 Configuration management
For the creation of reproducable and identical environment for the development and the run-time across differentsystems Ansible is used as configuration management solution All needed steps of the installation are automated Theconfiguration doesnrsquot differentiate between local or remote installations This matters only for the deployment of theweb content
For local development itrsquos possible to use an LX container
$ sudo ansible-playbook develcontaineryml
To get everything running some additional steps (check the network inside the container generate keys etc) areneeded After you are done check it
$ sudo ansible webshop -m setup
From the management system
$ sudo ssh-copy-id -i rootsshid_rsapub root[IP address of your managed node]
The configuration of Ansible itself (adding the system to etcansiblehosts and copying the SSH keys) isnot documented at this place There are various resources available like here All playbooks are located in the folderdevel Start the setup with the command shown below
$ sudo ansible-playbook develsetupyml
The used group name in etcansiblehosts is webshop
If the setup completes without errors then the web server is accessible and show a default page Please keep in mindthat the server is only accessible over https unencrypted traffic is not allowed
1542 DeploymentSetup website
For the simple deployment of the lastest version of the shop a playbook called deployyml is provided Thisplaybook put all files in place
$ sudo ansible-playbook develdeployyml
To full deploy the webshop all tables in the database must exist The file webshopsql contains all needed SQLcommands and sample data for the web application
Itrsquos possible to deploy the website manually but this is not recommended A couple of files are depending on templateswhich are created during the deployment
Itrsquos also not recommanded to clone everything into your webserver root This would save you the trouble of doing itby hand but third-party features are missing then Those missing parts are the template engine the pdf generation theconnection to Openstreetmap and probably other things not mentioned here
155 Git respository
All project relevante informations (Source code templates documentation etc) is located in a public Git repositoryon Github
38 Kapitel 15 Development
Shop Documentation Release 001
156 Documentation
The documentation is using reStructuredText as markup language For a local build Sphinx is needed Sphinx isavailable in the Fedora Package Collection and can be installed with yum or any other package management tool
yum -y install python-sphinx python-docutils
The source files of the documentation are located under docs
$ cd docs$ make html
The output is stored under docs_buildhtml
After every push to Github a hook launch a rebuild of the documentation The latest release will be published on Readthe Docs automatically
httpsshoprtfdorg
156 Documentation 39
Shop Documentation Release 001
40 Kapitel 15 Development
KAPITEL 16
Indices and tables
bull genindex
bull modindex
bull search
41
- Basics
-
- Products
- Personas
- Use cases
- Design principles
-
- Web shop Design
-
- General
- Layout
- Sitemap
- Main page
-
- Style and design
-
- Cascading Style Sheets
- Pages
-
- Dynamics
-
- Setup
- Current year
- Navigation Menu
- List of Products
- Company details
-
- External files
-
- Navigation Menu
- Header
- Footer
-
- Input processing
-
- ``Buy Now links
- Select options
-
- Javascript
-
- Simple use case
-
- Cookies and Sessions
-
- Cookies
- Hit counter
- Language selection
- User Accounts
-
- Database
-
- Tables
- PHP
-
- Web service
-
- Map
- Weather
-
- Data export
-
- JSON
-
- Messaging
-
- MQTT
-
- Localisation (L10n)
- Templates
-
- Template
- Content
-
- Development
-
- Web server
- Database server
- Versions
- Setup infrastructure
- Git respository
- Documentation
-
- Indices and tables
-
Shop Documentation Release 001
6 Kapitel 1 Basics
KAPITEL 2
Web shop Design
21 General
The used company and all data are notional There is no exisiting connection to any existing company with the sameor similar name
211 Company name
The company name is Pencil AG
212 Address
The complete address of the company is
Pencil AGMusterstrasse 13000 BernSchweiz
213 Logo
The logo used in this project is borrowed from the Tango project icon set The file is out of the categories section thefile name of the origin file is applications-officesvg and is licensed under Public Domain
22 Layout
The layout is splitted in different sections The content of the elements especially of the main section (content) willbe definied by the later usage of the page
7
Shop Documentation Release 001
23 Sitemap
The sitemap shows the clustering of the shop at the beginning of the project
This doesnrsquot mean that everything will be done Static pages are easy to make and to maintain
8 Kapitel 2 Web shop Design
Shop Documentation Release 001
24 Main page
The first draft of the main page is based on the prototype shown in section Layout without any format- und styleinformationen
ltDOCTYPE htmlgtlthtml lang=engt
ltheadgtltmeta charset=utf-8gtltmeta name=viewport content=width=device-width initial-scale=10gtltmeta name=description content=Webshop Pencil AG fuumlr Bleistiftegtltmeta name=author content=Fabian AffoltergtlttitlegtWebshop Pencil AG | Homelttitlegt
ltheadgt
ltbodygtlt-- Header container--gtltdivgt
ltdivgtlt-- Logo and company name --gtltimg src=logologopnggtlth2gtWebshop Pencil AGlth2gtlt-- Navigation --gtltulgt
ltligtlta href=gtHomeltagtltligtltligtlta href=gtProdukteltagtltligtltligtlta href=gtUumlber unsltagtltligt
ltulgtlt-- Breadcrumb --gtltolgt
ltligtlta href=gtEbene 1ltagtltligtltligtlta href=gtEbene 2ltagtltligtltligtlta href=gtEbene 3ltagtltligt
ltolgtltdivgt
ltdivgtlt-- Header container--gt
lt-- Action container --gtltdivgt
lth1gtWochen-Aktionlth1gtltpgtDies ist eine super Aktion 10 Bleistifte fuumlr CHF 8ltpgt
ltdivgtlt-- Action container --gt
lt-- Selected products --gtltdivgt
ltpgtHier hat es zufaumlllige Produkteltpgtltdivgtlt-- Selected products --gt
lt-- Footer --gtltdivgt
ltpgtampcopy Pencil AG 2013ltpgtlt-- Footer --gtltdivgt
ltbodygtlthtmlgt
24 Main page 9
Shop Documentation Release 001
Loaded in a browser the initial draft of the main page looks like in the following screenshot
10 Kapitel 2 Web shop Design
KAPITEL 3
Style and design
31 Cascading Style Sheets
The design of the shop will be nothing fancy The approach which was choosen will reflect the points mentioned inthe Design principles section and makes heavy use of the bootstrap framework cascading style sheet Various changesto this CSS file ensure that it matche the needs of this project
32 Pages
The product page show the elements mentioned in the Product overview section
11
Shop Documentation Release 001
12 Kapitel 3 Style and design
KAPITEL 4
Dynamics
The webshop will be a PHP application at the end Those first steps are only covering the very basic stuff of PHP asan introduction
41 Setup
The setupyml playbook puts a simple PHP file in the root directory of the web server with the namephpinfophp This file displays PHP details
Achtung Remove this file before makeing the shop accessible by a public audience
42 Current year
The first PHP element in the webshop is showing the current year in the footer of every page With the help of thislittle piece of code there is no longer a need to update the year
ltphp echo date(Y) gt
43 Navigation Menu
The basic menu was built with the following snippet
ltphp$menu = array(rsquoHomersquo =gt rsquoindexphprsquo
rsquoProduktersquo =gt rsquoproductsphprsquorsquoUumlber unsrsquo =gt rsquoaboutphprsquo
)foreach($menu as $label =gt $link)
echo rsquoltligtlta href=rsquo $link rsquogtrsquo $label rsquoltagtltligtrsquo
gt
The issue with that snippet was that the CSS class was missing In regards to a future separation and reusability anadditional statements was added This way the label of the active page is highlighted
13
Shop Documentation Release 001
ltphp$menu = array(rsquoHomersquo =gt rsquoindexphprsquo
rsquoProduktersquo =gt rsquoproductsphprsquorsquoUumlber unsrsquo =gt rsquoaboutphprsquo
)foreach ($menu as $label =gt $link)
$url = trim($_SERVER[rsquoPHP_SELFrsquo] rsquorsquo)if ($link == $url)
echo rsquoltli class=activegtlta href=rsquo $link rsquogtrsquo $label rsquoltagtltligtrsquo else
echo rsquoltli class=gtlta href=rsquo $link rsquogtrsquo $label rsquoltagtltligtrsquo
gt
44 List of Products
The product overiew is a simple table The heading of the table is placed in an array
ltdivgtlttable class=table table-stripedgtltthead valign=bottomgtlttrgtltphp
$heading = array(rsquoTypersquo rsquoVariantrsquo rsquoColorrsquo rsquoHardnessrsquo rsquoPrice CHFrsquo)foreach ($heading as $element)
echo rsquoltth class=headgtrsquo$elementrsquoltthgtrsquon
gtlttrgtlttheadgtlttbody valign=topgtltphp
$products = array(array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquoHBrsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquoBrsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquo2Brsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquoFrsquo rsquo12rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquoHrsquo rsquo12rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquo2Hrsquo rsquo12rsquo)
)foreach ($products as $product =gt $details)
echo lttrgtforeach ($details as $detail)
echo lttdgt$detaillttdgtecho lttrgt
gtlttbodygtlttablegt
ltdivgt
14 Kapitel 4 Dynamics
Shop Documentation Release 001
45 Company details
The data for the About page are included out of a static and plain text file
ltphp$str = file_get_contents(companytxt)echo $str
gt
45 Company details 15
Shop Documentation Release 001
16 Kapitel 4 Dynamics
KAPITEL 5
External files
51 Navigation Menu
The menu is outsourced in the file menuphp
ltphpfunction menu()
$part1 = rsquoltul class=nav nav-tabsgtrsquon$part2 = rsquorsquo$part3 = rsquoltulgtrsquon Menu array with page title and assigned file$menu = array(rsquoHomersquo =gt rsquoindexphprsquo
rsquoProduktersquo =gt rsquoproductsphprsquorsquoUumlber unsrsquo =gt rsquoaboutphprsquo
)foreach ($menu as $label =gt $link)
For the CSS only the file name without is needed$url = trim($_SERVER[rsquoPHP_SELFrsquo] rsquorsquo)if ($link == $url)
$part2 = $part2ltli class=rsquoactiversquogtlta href=rsquo$linkrsquogt$labelltagtltligtn else
$part2 = $part2ltli class=rsquorsquogtlta href=rsquo$linkrsquogt$labelltagtltligtn
return $part1$part2$part3
gt
52 Header
The complete header part is loaded from the file headerphp
ltphpfunction head()
$start_page = indexphp$part1 = ltdivgtn$part2 = tlta class=rsquobrand-logorsquo href=rsquo$start_pagersquogtltagtn$part3 = tltp class=rsquobrand-namersquogtWebshop Pencil AGltpgtn$part4 = ltdivgtnreturn $part1$part2$part3$part4
17
Shop Documentation Release 001
gt
53 Footer
The same is done witht the page footers
ltphpfunction foot()
$class1 = rsquoltdiv class=footergtrsquon$class2 = rsquoltdivgtrsquon$text = ltpgtampcopy Pencil AG getYear()rsquoltpgtrsquonreturn $class1$text$class2
function getYear()return date(Y)
gt
18 Kapitel 5 External files
KAPITEL 6
Input processing
61 ldquoBuy Nowrdquo links
The ldquoBuy Nowrdquo links are attached to the Products page Every entry has itrsquos own link which lead to a detail page Thelinks are using hidden form elements to transfer the data
ltphp$products = array(array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquoHBrsquo rsquo1rsquo)
array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquoBrsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquo2Brsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquoFrsquo rsquo12rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquoHrsquo rsquo12rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquo2Hrsquo rsquo12rsquo)
)foreach ($products as $product =gt $details)
echo lttrgtnforeach ($details as $detail)
echo lttdgt$detaillttdgtnecho lttdgtnecho ltform action=rsquoproductphprsquo method=rsquogetrsquo name=rsquopencilrsquogtnecho ltinput type=rsquohiddenrsquo name=rsquotypersquo value=rsquo$details[0]rsquogtnecho ltinput type=rsquohiddenrsquo name=rsquooptionsrsquo value=rsquo$details[1]rsquogtnecho ltinput type=rsquohiddenrsquo name=rsquocolorrsquo value=rsquo$details[2]rsquogtnecho ltinput type=rsquohiddenrsquo name=rsquohardnessrsquo value=rsquo$details[3]rsquogtnecho ltinput type=rsquohiddenrsquo name=rsquopricersquo value=rsquo$details[4]rsquogtnecho ltinput type=rsquosubmitrsquo class=rsquobtn btn-defaultrsquo value=rsquoKauf michrsquogtnecho ltformgtnecho lttdgtnecho lttrgtn
gt
And the detail page contains the code fragement mentioned below
ltphp$type=$_GET[rsquotypersquo]$color=$_GET[rsquocolorrsquo]$hardness=$_GET[rsquohardnessrsquo]$options=$_GET[rsquooptionsrsquo]$price=$_GET[rsquopricersquo]echo I am a $type in $color and a hardness of $hardness I have $options as an option and my price is $price CHF
gt
19
Shop Documentation Release 001
Bemerkung The Products page was modified in the process of the development
62 Select options
The signupbilling page contains a dropdown element that all days of a month for the entry of the userrsquos birthday
ltselect name=daygtltoptiongtDayltoptiongt
ltphp$days = range(31 1)foreach ($days as $day)
echo rsquoltoption value=rsquo$dayrsquogtrsquo$dayrsquoltoptiongtrsquo
gtltselectgt
20 Kapitel 6 Input processing
KAPITEL 7
Javascript
Over the years Javascript became a very popular programming language The webshop is using Javascript at a coupleof places
71 Simple use case
Javascript makes it easy to access elements in the DOM Setting the focus is a nice way to support the user with inputform
ltscript language=javascriptgtfunction setFocus()
documentforms[login][username]focus()
ltscriptgtltheadgtltbody onload=setFocus()gt
Another one is to check if something was entered in an input field
function validateForm() var username = documentforms[rdquologinrdquo][rdquousernamerdquo]value if (username== null || username == ldquordquo)
documentforms[rdquologinrdquo][rdquousernamerdquo]stylebackgroundColor = ldquoFF9999rdquo docu-mentforms[rdquologinrdquo][rdquousernamerdquo]placeholder = ldquoPlease your usernamerdquo docu-mentforms[rdquologinrdquo][rdquousernamerdquo]focus() return false
A simple message is informing the user about an action which was taken against the database
echo ltscript type=textjavascriptgtalert(New entry $entry added successfully)windowlocation = tablesphp
ltscriptgt
The delete process is only executed if the user confirm to delete a record
ltform action=scriptsdelete-processphp onSubmit=return confirm(rsquoAre you sure to delete this entryrsquo) method=POSTgtltinput type=hidden name=table value=$sectiongtltinput type=hidden name=id value=$result-gtidgtltinput type=submit name=Submit value=Deletegt
ltformgt
For additional Javascript please check the source of the indexphp file and the reflsquowebservicelsquo_ section
21
Shop Documentation Release 001
22 Kapitel 7 Javascript
KAPITEL 8
Cookies and Sessions
The built-in support for sessions in PHP is handling all cookie manipulation to provide persistent variables that areaccessible from different pages and across multiple visits to the site
81 Cookies
A cookie is used to track the last time a visitor check the front page The cookie is set when a visitor arrives
function lastVisit($name $expire) $value = getDateDMY() - getTimeHM()setcookie($name $value time() + $expire rsquorsquo $_SERVER[rsquoSERVER_NAMErsquo] true true)
In the footer of the index page the details are presented
ltphpif(isset($_COOKIE[rsquoLastVisitrsquo]))
$last = $_COOKIE[rsquoLastVisitrsquo]echo You last visited us on $last
else echo This is your first visit
gt
82 Hit counter
As a simple show case for PHP sessions a hit counter for the front page is available
ltphpsession_start()
$_SESSION[rsquohitsrsquo] = $_SESSION[rsquohitsrsquo] + 1gt
Included in the footer it shous the users the total of visits
echo Total $_SESSION[rsquohitsrsquo] visits of this page
23
Shop Documentation Release 001
83 Language selection
84 User Accounts
24 Kapitel 8 Cookies and Sessions
KAPITEL 9
Database
The database backend for the webshop will be MariaDB which is the drop-in replacement for MySQL
For the setup please check the Development section in this documentation
91 Tables
The following tables are needed for the webshop to work
bull products
bull customers
bull pencils
bull colors
bull hardness
bull options
bull users
Please use the develwebshopsql to setup the database
92 PHP
Below you find the configuration file for a default installation of the webshop This file is a template and filled duringthe setup process
ltphp$host = localhost$user = root$password = webshop$dbase = webshop$connection = new mysqli($host $user $password $dbase)
if ($connection-gtconnect_errno) echo Failed to connect to MariaDBMySQL ($connection-gtconnect_errno) $connection-gtconnect_error
mysqli_report(MYSQLI_REPORT_ERROR)
gt
25
Shop Documentation Release 001
All connections to the database are done in the same way Below you find an example Everything is done in theobject-oriented style
ltphprequire_once(rsquoconfigdbconnectphprsquo)if ($connection-gtconnect_errno == 0)
$sql = SELECT FROM products$results = $connection-gtquery($sql)echo $results-gtnum_rows$results-gtclose()
else echo Database connection error
gt
26 Kapitel 9 Database
KAPITEL 10
Web service
Tow web services are integrated to take advantages of online available data sources
101 Map
Leafletjs a JavaScript library for working with interactive maps from OpenStreetMap (OSM) is implemented as ashow case for a simple web service
The basic steps to integrate a map is shown below
ltdiv id=map class=map style=width 600px height 400pxgtltdivgt
ltscript src=scriptsleafletjsgtltscriptgtltscript src=scriptsleaflet-providersjsgtltscriptgtltscriptgtvar map = Lmap(rsquomaprsquo
center [250472 -773255]zoom 12zoomControl true
)
var defaultLayer = LtileLayerprovider(rsquoOpenStreetMapMapnikrsquo)addTo(map)ltscriptgt
102 Weather
The OpenWeatherMap service provides free weather data and a forecast API for web applications
ltphp Details about the API httpbugsopenweathermaporgprojectsapiwikiApi_2_5_weather$url = rsquohttpapiopenweathermaporgdata25weatherq=Bernechampunit=metricsampmode=jsonrsquo
$json = file_get_contents($url)$data = json_decode($json)
$tempC = round((27315 - $data-gtmain-gttemp)100) 100$humidity = $data-gtmain-gthumidity$pressure = $data-gtmain-gtpressure
27
Shop Documentation Release 001
echo ltpgtTemperatur $tempC degCltbrgtnecho Luftfeuchtigkeit $humidity ltbrgtnecho Luftdruck $pressure Paltpgtn
gt
28 Kapitel 10 Web service
KAPITEL 11
Data export
111 PDF
FPDF is a PHP class that allows to generate PDF files with pure PHP As a showcase for that the product specificationsfor a given product are filled in a pdf and showed in the browser The user can then decide to download or print thefile
112 JSON
JavaScript Object Notation (JSON) is a lightweight data-interchange format The format is language independent andPHP support the encoding and the decoding JSON with json_encode($data) and json_decode($data)$rows = array()$sql = SELECT FROM products$results = $connection-gtquery($sql)while ($result = $results-gtfetch_object())
$rows[] = $result$results-gtclose()
Writing all rows to a JSON file$fp = fopen(rsquopencilsjsonrsquo rsquowrsquo)fwrite($fp json_encode($rows))fclose($fp)gt
and for reading it
ltphp$json = file_get_contents(rsquopencilsjsonrsquo)print_r(json_decode($json))
gt
29
Shop Documentation Release 001
30 Kapitel 11 Data export
KAPITEL 12
Messaging
Beside standard email messages the webshop supports sending MQ Telemetry Transport protocol (MQTT) messagesas an additional feature The MQTT messages are small
121 MQTT
Mosquitto-PHP is used as a PHP wrapper for MQTT Please check the Projectrsquos README for details about theinstallation and the setup
1211 Broker
Mosquitto is a message broker that implements the MQ Telemetry Transport protocol Check if mosquitto is run-ning
$ sudo systemctl status mosquittoservice
If not start it
$ systemctl start mosquittoservice
All messages are published to the topic webshop
1212 Publishing
After the installation of Mosquitto-PHP the snipplet shown below sends a single message
ltphpdefine(rsquoBROKERrsquo rsquolocalhostrsquo)define(rsquoPORTrsquo 1883)define(rsquoCLIENT_IDrsquo webshop_ + getmypid())$topic = webshop$subtopic = test$completeTopic = $topic$subtopic
$client = new MosquittoClient(CLIENT_ID)$client-gtconnect(BROKER PORT 60)
$message = Test message from webshop at date(Y-m-d His)$client-gtpublish($completeTopic $message 0 false)
gt
31
Shop Documentation Release 001
1213 Subscribing
To read the messages sent by the webshop a client is needed The Mosquitto broker contain a simple command-linetool for subscribing to various topics
$ mosquitto_sub -h localhost -t webshop
122 Email
This section doesnrsquot describe the installation and configuration of a local MTA There are enough resources thatcontains information about the setup of postfix for local delivery only
If you want to test the email feature add the following code in one of PHP pages
ltphp mail(rsquorootlocalhostrsquo rsquoTest message from webshoprsquo rsquoThe webshop is selling pencilsrsquo) gt
By default SELinux is running in Enforcing mode which is restrictive about about what a web server can do Toallow sending email the following SELinux boolean needs to changed
setsebool -P httpd_can_network_connect=1 setsebool -P httpd_can_sendmail=1
32 Kapitel 12 Messaging
KAPITEL 13
Localisation (L10n)
There are several ways to add localisation to a web site For small projects arrays with string can work but this is notvery efficient and user-friendly With Gettext is a toolset available that provide a framework to produce multi-lingualcontent in a wide area of programming languages
Make sure that the php-gettext package is available on your system If not install it
$ sudo yum -y install php-php-gettext
Check if gettext support is available
ltphpif (function_exists(gettext))
echo gettext is not installednelse
echo gettext is supportedn
gt
Make sure that all locales your want are available on the server
locale -a
The first step is to mark all string which should be translatable as shown below For further details please refer to theGettext documentation
echo _(rsquoSome textrsquo)
The next step is to extract all strings
xgettext --from-code=UTF-8 -o localewebshoppot php scriptsphp
To re-generate the file after an update join the strings
xgettext -j --from-code=UTF-8 -o localewebshoppot php scriptsphp
For every language a po file is needed for the transations Generate it with the command mentioned below
msginit --no-translator -l de_CH -o localede_CHpo -i localewebshoppot
Once created there are only updates of the message catalog needed in the futures
msgmerge -U localede_CHpo localewebshoppot
If you re finish create the mo file for the specific language
33
Shop Documentation Release 001
msgfmt -c -v -o localede_CHLC_MESSAGESwebshopmo localede_CHpo
34 Kapitel 13 Localisation (L10n)
KAPITEL 14
Templates
Beside other solutions Savant3 is a lightweight object-oriented template system for PHP This solution does not needa lot of additional configuration
141 Template
A simple template file looks like the one shown below
lthtmlgtltheadgt
lttitlegtltphp echo $this-gteprint($this-gttitle) gtlttitlegtltheadgtltbodygt
ltphp echo $this-gteprint($this-gtcontent) gtltbodygt
lthtmlgt
For a more detailed intro check this article on Zend Developer Zone
142 Content
To fill the template with data all wished variables needs to be defined in a seperate PHP file
ltphprequire_once rsquoscriptsSavant3phprsquo$tpl = new Savant3()
Create a title$title = Simple sample page
Create the content of the page$content = Some sample text to show
Assign values to the Savant instance$tpl-gttitle = $title$tpl-gtcontent = $content
Define the template source file to show$tpl-gtdisplay(rsquosimpletplphprsquo)
gt
35
Shop Documentation Release 001
The webshop contains a page (master)
36 Kapitel 14 Templates
KAPITEL 15
Development
This sections describes the configuration of the development and runtime environment for the web shop
151 Web server
Instead of Apache the project is running on Lighttpd The reasons are that Lighttpd provides faster setup easierconfiguration and better performance Lighttpd is running with FastCGI
The path of the web server is varwwwlighttpd and the SELinux configuration are still the defaults
The web server is running in SSL-only mode and the certificate is generated during the server setup process
152 Database server
For persistence storage the drop-in replacement MariaDB is used MySQL will work to but this is not tested phpMyAd-min is available under phpmyadmin on the web server beside the command-line tools for easy administration
The default credentials for phpMyAdmin are rootwebshop or the entry you made in the Ansible playbookdevelvariablessensitiveyml
153 Versions
The web shop is built with the below listed components and tested Other releases can be used and may work but thiswill not be tested Probably it will work with different releases
bull Operating system Fedora 20
bull Kernel 3135-202fc20x86_64
bull Lighttpd 1434
bull PHP 557
bull MariaDB 5534
For communication postfix and mosquitto are needed additionally
37
Shop Documentation Release 001
154 Setup infrastructure
1541 Configuration management
For the creation of reproducable and identical environment for the development and the run-time across differentsystems Ansible is used as configuration management solution All needed steps of the installation are automated Theconfiguration doesnrsquot differentiate between local or remote installations This matters only for the deployment of theweb content
For local development itrsquos possible to use an LX container
$ sudo ansible-playbook develcontaineryml
To get everything running some additional steps (check the network inside the container generate keys etc) areneeded After you are done check it
$ sudo ansible webshop -m setup
From the management system
$ sudo ssh-copy-id -i rootsshid_rsapub root[IP address of your managed node]
The configuration of Ansible itself (adding the system to etcansiblehosts and copying the SSH keys) isnot documented at this place There are various resources available like here All playbooks are located in the folderdevel Start the setup with the command shown below
$ sudo ansible-playbook develsetupyml
The used group name in etcansiblehosts is webshop
If the setup completes without errors then the web server is accessible and show a default page Please keep in mindthat the server is only accessible over https unencrypted traffic is not allowed
1542 DeploymentSetup website
For the simple deployment of the lastest version of the shop a playbook called deployyml is provided Thisplaybook put all files in place
$ sudo ansible-playbook develdeployyml
To full deploy the webshop all tables in the database must exist The file webshopsql contains all needed SQLcommands and sample data for the web application
Itrsquos possible to deploy the website manually but this is not recommended A couple of files are depending on templateswhich are created during the deployment
Itrsquos also not recommanded to clone everything into your webserver root This would save you the trouble of doing itby hand but third-party features are missing then Those missing parts are the template engine the pdf generation theconnection to Openstreetmap and probably other things not mentioned here
155 Git respository
All project relevante informations (Source code templates documentation etc) is located in a public Git repositoryon Github
38 Kapitel 15 Development
Shop Documentation Release 001
156 Documentation
The documentation is using reStructuredText as markup language For a local build Sphinx is needed Sphinx isavailable in the Fedora Package Collection and can be installed with yum or any other package management tool
yum -y install python-sphinx python-docutils
The source files of the documentation are located under docs
$ cd docs$ make html
The output is stored under docs_buildhtml
After every push to Github a hook launch a rebuild of the documentation The latest release will be published on Readthe Docs automatically
httpsshoprtfdorg
156 Documentation 39
Shop Documentation Release 001
40 Kapitel 15 Development
KAPITEL 16
Indices and tables
bull genindex
bull modindex
bull search
41
- Basics
-
- Products
- Personas
- Use cases
- Design principles
-
- Web shop Design
-
- General
- Layout
- Sitemap
- Main page
-
- Style and design
-
- Cascading Style Sheets
- Pages
-
- Dynamics
-
- Setup
- Current year
- Navigation Menu
- List of Products
- Company details
-
- External files
-
- Navigation Menu
- Header
- Footer
-
- Input processing
-
- ``Buy Now links
- Select options
-
- Javascript
-
- Simple use case
-
- Cookies and Sessions
-
- Cookies
- Hit counter
- Language selection
- User Accounts
-
- Database
-
- Tables
- PHP
-
- Web service
-
- Map
- Weather
-
- Data export
-
- JSON
-
- Messaging
-
- MQTT
-
- Localisation (L10n)
- Templates
-
- Template
- Content
-
- Development
-
- Web server
- Database server
- Versions
- Setup infrastructure
- Git respository
- Documentation
-
- Indices and tables
-
KAPITEL 2
Web shop Design
21 General
The used company and all data are notional There is no exisiting connection to any existing company with the sameor similar name
211 Company name
The company name is Pencil AG
212 Address
The complete address of the company is
Pencil AGMusterstrasse 13000 BernSchweiz
213 Logo
The logo used in this project is borrowed from the Tango project icon set The file is out of the categories section thefile name of the origin file is applications-officesvg and is licensed under Public Domain
22 Layout
The layout is splitted in different sections The content of the elements especially of the main section (content) willbe definied by the later usage of the page
7
Shop Documentation Release 001
23 Sitemap
The sitemap shows the clustering of the shop at the beginning of the project
This doesnrsquot mean that everything will be done Static pages are easy to make and to maintain
8 Kapitel 2 Web shop Design
Shop Documentation Release 001
24 Main page
The first draft of the main page is based on the prototype shown in section Layout without any format- und styleinformationen
ltDOCTYPE htmlgtlthtml lang=engt
ltheadgtltmeta charset=utf-8gtltmeta name=viewport content=width=device-width initial-scale=10gtltmeta name=description content=Webshop Pencil AG fuumlr Bleistiftegtltmeta name=author content=Fabian AffoltergtlttitlegtWebshop Pencil AG | Homelttitlegt
ltheadgt
ltbodygtlt-- Header container--gtltdivgt
ltdivgtlt-- Logo and company name --gtltimg src=logologopnggtlth2gtWebshop Pencil AGlth2gtlt-- Navigation --gtltulgt
ltligtlta href=gtHomeltagtltligtltligtlta href=gtProdukteltagtltligtltligtlta href=gtUumlber unsltagtltligt
ltulgtlt-- Breadcrumb --gtltolgt
ltligtlta href=gtEbene 1ltagtltligtltligtlta href=gtEbene 2ltagtltligtltligtlta href=gtEbene 3ltagtltligt
ltolgtltdivgt
ltdivgtlt-- Header container--gt
lt-- Action container --gtltdivgt
lth1gtWochen-Aktionlth1gtltpgtDies ist eine super Aktion 10 Bleistifte fuumlr CHF 8ltpgt
ltdivgtlt-- Action container --gt
lt-- Selected products --gtltdivgt
ltpgtHier hat es zufaumlllige Produkteltpgtltdivgtlt-- Selected products --gt
lt-- Footer --gtltdivgt
ltpgtampcopy Pencil AG 2013ltpgtlt-- Footer --gtltdivgt
ltbodygtlthtmlgt
24 Main page 9
Shop Documentation Release 001
Loaded in a browser the initial draft of the main page looks like in the following screenshot
10 Kapitel 2 Web shop Design
KAPITEL 3
Style and design
31 Cascading Style Sheets
The design of the shop will be nothing fancy The approach which was choosen will reflect the points mentioned inthe Design principles section and makes heavy use of the bootstrap framework cascading style sheet Various changesto this CSS file ensure that it matche the needs of this project
32 Pages
The product page show the elements mentioned in the Product overview section
11
Shop Documentation Release 001
12 Kapitel 3 Style and design
KAPITEL 4
Dynamics
The webshop will be a PHP application at the end Those first steps are only covering the very basic stuff of PHP asan introduction
41 Setup
The setupyml playbook puts a simple PHP file in the root directory of the web server with the namephpinfophp This file displays PHP details
Achtung Remove this file before makeing the shop accessible by a public audience
42 Current year
The first PHP element in the webshop is showing the current year in the footer of every page With the help of thislittle piece of code there is no longer a need to update the year
ltphp echo date(Y) gt
43 Navigation Menu
The basic menu was built with the following snippet
ltphp$menu = array(rsquoHomersquo =gt rsquoindexphprsquo
rsquoProduktersquo =gt rsquoproductsphprsquorsquoUumlber unsrsquo =gt rsquoaboutphprsquo
)foreach($menu as $label =gt $link)
echo rsquoltligtlta href=rsquo $link rsquogtrsquo $label rsquoltagtltligtrsquo
gt
The issue with that snippet was that the CSS class was missing In regards to a future separation and reusability anadditional statements was added This way the label of the active page is highlighted
13
Shop Documentation Release 001
ltphp$menu = array(rsquoHomersquo =gt rsquoindexphprsquo
rsquoProduktersquo =gt rsquoproductsphprsquorsquoUumlber unsrsquo =gt rsquoaboutphprsquo
)foreach ($menu as $label =gt $link)
$url = trim($_SERVER[rsquoPHP_SELFrsquo] rsquorsquo)if ($link == $url)
echo rsquoltli class=activegtlta href=rsquo $link rsquogtrsquo $label rsquoltagtltligtrsquo else
echo rsquoltli class=gtlta href=rsquo $link rsquogtrsquo $label rsquoltagtltligtrsquo
gt
44 List of Products
The product overiew is a simple table The heading of the table is placed in an array
ltdivgtlttable class=table table-stripedgtltthead valign=bottomgtlttrgtltphp
$heading = array(rsquoTypersquo rsquoVariantrsquo rsquoColorrsquo rsquoHardnessrsquo rsquoPrice CHFrsquo)foreach ($heading as $element)
echo rsquoltth class=headgtrsquo$elementrsquoltthgtrsquon
gtlttrgtlttheadgtlttbody valign=topgtltphp
$products = array(array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquoHBrsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquoBrsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquo2Brsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquoFrsquo rsquo12rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquoHrsquo rsquo12rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquo2Hrsquo rsquo12rsquo)
)foreach ($products as $product =gt $details)
echo lttrgtforeach ($details as $detail)
echo lttdgt$detaillttdgtecho lttrgt
gtlttbodygtlttablegt
ltdivgt
14 Kapitel 4 Dynamics
Shop Documentation Release 001
45 Company details
The data for the About page are included out of a static and plain text file
ltphp$str = file_get_contents(companytxt)echo $str
gt
45 Company details 15
Shop Documentation Release 001
16 Kapitel 4 Dynamics
KAPITEL 5
External files
51 Navigation Menu
The menu is outsourced in the file menuphp
ltphpfunction menu()
$part1 = rsquoltul class=nav nav-tabsgtrsquon$part2 = rsquorsquo$part3 = rsquoltulgtrsquon Menu array with page title and assigned file$menu = array(rsquoHomersquo =gt rsquoindexphprsquo
rsquoProduktersquo =gt rsquoproductsphprsquorsquoUumlber unsrsquo =gt rsquoaboutphprsquo
)foreach ($menu as $label =gt $link)
For the CSS only the file name without is needed$url = trim($_SERVER[rsquoPHP_SELFrsquo] rsquorsquo)if ($link == $url)
$part2 = $part2ltli class=rsquoactiversquogtlta href=rsquo$linkrsquogt$labelltagtltligtn else
$part2 = $part2ltli class=rsquorsquogtlta href=rsquo$linkrsquogt$labelltagtltligtn
return $part1$part2$part3
gt
52 Header
The complete header part is loaded from the file headerphp
ltphpfunction head()
$start_page = indexphp$part1 = ltdivgtn$part2 = tlta class=rsquobrand-logorsquo href=rsquo$start_pagersquogtltagtn$part3 = tltp class=rsquobrand-namersquogtWebshop Pencil AGltpgtn$part4 = ltdivgtnreturn $part1$part2$part3$part4
17
Shop Documentation Release 001
gt
53 Footer
The same is done witht the page footers
ltphpfunction foot()
$class1 = rsquoltdiv class=footergtrsquon$class2 = rsquoltdivgtrsquon$text = ltpgtampcopy Pencil AG getYear()rsquoltpgtrsquonreturn $class1$text$class2
function getYear()return date(Y)
gt
18 Kapitel 5 External files
KAPITEL 6
Input processing
61 ldquoBuy Nowrdquo links
The ldquoBuy Nowrdquo links are attached to the Products page Every entry has itrsquos own link which lead to a detail page Thelinks are using hidden form elements to transfer the data
ltphp$products = array(array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquoHBrsquo rsquo1rsquo)
array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquoBrsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquo2Brsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquoFrsquo rsquo12rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquoHrsquo rsquo12rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquo2Hrsquo rsquo12rsquo)
)foreach ($products as $product =gt $details)
echo lttrgtnforeach ($details as $detail)
echo lttdgt$detaillttdgtnecho lttdgtnecho ltform action=rsquoproductphprsquo method=rsquogetrsquo name=rsquopencilrsquogtnecho ltinput type=rsquohiddenrsquo name=rsquotypersquo value=rsquo$details[0]rsquogtnecho ltinput type=rsquohiddenrsquo name=rsquooptionsrsquo value=rsquo$details[1]rsquogtnecho ltinput type=rsquohiddenrsquo name=rsquocolorrsquo value=rsquo$details[2]rsquogtnecho ltinput type=rsquohiddenrsquo name=rsquohardnessrsquo value=rsquo$details[3]rsquogtnecho ltinput type=rsquohiddenrsquo name=rsquopricersquo value=rsquo$details[4]rsquogtnecho ltinput type=rsquosubmitrsquo class=rsquobtn btn-defaultrsquo value=rsquoKauf michrsquogtnecho ltformgtnecho lttdgtnecho lttrgtn
gt
And the detail page contains the code fragement mentioned below
ltphp$type=$_GET[rsquotypersquo]$color=$_GET[rsquocolorrsquo]$hardness=$_GET[rsquohardnessrsquo]$options=$_GET[rsquooptionsrsquo]$price=$_GET[rsquopricersquo]echo I am a $type in $color and a hardness of $hardness I have $options as an option and my price is $price CHF
gt
19
Shop Documentation Release 001
Bemerkung The Products page was modified in the process of the development
62 Select options
The signupbilling page contains a dropdown element that all days of a month for the entry of the userrsquos birthday
ltselect name=daygtltoptiongtDayltoptiongt
ltphp$days = range(31 1)foreach ($days as $day)
echo rsquoltoption value=rsquo$dayrsquogtrsquo$dayrsquoltoptiongtrsquo
gtltselectgt
20 Kapitel 6 Input processing
KAPITEL 7
Javascript
Over the years Javascript became a very popular programming language The webshop is using Javascript at a coupleof places
71 Simple use case
Javascript makes it easy to access elements in the DOM Setting the focus is a nice way to support the user with inputform
ltscript language=javascriptgtfunction setFocus()
documentforms[login][username]focus()
ltscriptgtltheadgtltbody onload=setFocus()gt
Another one is to check if something was entered in an input field
function validateForm() var username = documentforms[rdquologinrdquo][rdquousernamerdquo]value if (username== null || username == ldquordquo)
documentforms[rdquologinrdquo][rdquousernamerdquo]stylebackgroundColor = ldquoFF9999rdquo docu-mentforms[rdquologinrdquo][rdquousernamerdquo]placeholder = ldquoPlease your usernamerdquo docu-mentforms[rdquologinrdquo][rdquousernamerdquo]focus() return false
A simple message is informing the user about an action which was taken against the database
echo ltscript type=textjavascriptgtalert(New entry $entry added successfully)windowlocation = tablesphp
ltscriptgt
The delete process is only executed if the user confirm to delete a record
ltform action=scriptsdelete-processphp onSubmit=return confirm(rsquoAre you sure to delete this entryrsquo) method=POSTgtltinput type=hidden name=table value=$sectiongtltinput type=hidden name=id value=$result-gtidgtltinput type=submit name=Submit value=Deletegt
ltformgt
For additional Javascript please check the source of the indexphp file and the reflsquowebservicelsquo_ section
21
Shop Documentation Release 001
22 Kapitel 7 Javascript
KAPITEL 8
Cookies and Sessions
The built-in support for sessions in PHP is handling all cookie manipulation to provide persistent variables that areaccessible from different pages and across multiple visits to the site
81 Cookies
A cookie is used to track the last time a visitor check the front page The cookie is set when a visitor arrives
function lastVisit($name $expire) $value = getDateDMY() - getTimeHM()setcookie($name $value time() + $expire rsquorsquo $_SERVER[rsquoSERVER_NAMErsquo] true true)
In the footer of the index page the details are presented
ltphpif(isset($_COOKIE[rsquoLastVisitrsquo]))
$last = $_COOKIE[rsquoLastVisitrsquo]echo You last visited us on $last
else echo This is your first visit
gt
82 Hit counter
As a simple show case for PHP sessions a hit counter for the front page is available
ltphpsession_start()
$_SESSION[rsquohitsrsquo] = $_SESSION[rsquohitsrsquo] + 1gt
Included in the footer it shous the users the total of visits
echo Total $_SESSION[rsquohitsrsquo] visits of this page
23
Shop Documentation Release 001
83 Language selection
84 User Accounts
24 Kapitel 8 Cookies and Sessions
KAPITEL 9
Database
The database backend for the webshop will be MariaDB which is the drop-in replacement for MySQL
For the setup please check the Development section in this documentation
91 Tables
The following tables are needed for the webshop to work
bull products
bull customers
bull pencils
bull colors
bull hardness
bull options
bull users
Please use the develwebshopsql to setup the database
92 PHP
Below you find the configuration file for a default installation of the webshop This file is a template and filled duringthe setup process
ltphp$host = localhost$user = root$password = webshop$dbase = webshop$connection = new mysqli($host $user $password $dbase)
if ($connection-gtconnect_errno) echo Failed to connect to MariaDBMySQL ($connection-gtconnect_errno) $connection-gtconnect_error
mysqli_report(MYSQLI_REPORT_ERROR)
gt
25
Shop Documentation Release 001
All connections to the database are done in the same way Below you find an example Everything is done in theobject-oriented style
ltphprequire_once(rsquoconfigdbconnectphprsquo)if ($connection-gtconnect_errno == 0)
$sql = SELECT FROM products$results = $connection-gtquery($sql)echo $results-gtnum_rows$results-gtclose()
else echo Database connection error
gt
26 Kapitel 9 Database
KAPITEL 10
Web service
Tow web services are integrated to take advantages of online available data sources
101 Map
Leafletjs a JavaScript library for working with interactive maps from OpenStreetMap (OSM) is implemented as ashow case for a simple web service
The basic steps to integrate a map is shown below
ltdiv id=map class=map style=width 600px height 400pxgtltdivgt
ltscript src=scriptsleafletjsgtltscriptgtltscript src=scriptsleaflet-providersjsgtltscriptgtltscriptgtvar map = Lmap(rsquomaprsquo
center [250472 -773255]zoom 12zoomControl true
)
var defaultLayer = LtileLayerprovider(rsquoOpenStreetMapMapnikrsquo)addTo(map)ltscriptgt
102 Weather
The OpenWeatherMap service provides free weather data and a forecast API for web applications
ltphp Details about the API httpbugsopenweathermaporgprojectsapiwikiApi_2_5_weather$url = rsquohttpapiopenweathermaporgdata25weatherq=Bernechampunit=metricsampmode=jsonrsquo
$json = file_get_contents($url)$data = json_decode($json)
$tempC = round((27315 - $data-gtmain-gttemp)100) 100$humidity = $data-gtmain-gthumidity$pressure = $data-gtmain-gtpressure
27
Shop Documentation Release 001
echo ltpgtTemperatur $tempC degCltbrgtnecho Luftfeuchtigkeit $humidity ltbrgtnecho Luftdruck $pressure Paltpgtn
gt
28 Kapitel 10 Web service
KAPITEL 11
Data export
111 PDF
FPDF is a PHP class that allows to generate PDF files with pure PHP As a showcase for that the product specificationsfor a given product are filled in a pdf and showed in the browser The user can then decide to download or print thefile
112 JSON
JavaScript Object Notation (JSON) is a lightweight data-interchange format The format is language independent andPHP support the encoding and the decoding JSON with json_encode($data) and json_decode($data)$rows = array()$sql = SELECT FROM products$results = $connection-gtquery($sql)while ($result = $results-gtfetch_object())
$rows[] = $result$results-gtclose()
Writing all rows to a JSON file$fp = fopen(rsquopencilsjsonrsquo rsquowrsquo)fwrite($fp json_encode($rows))fclose($fp)gt
and for reading it
ltphp$json = file_get_contents(rsquopencilsjsonrsquo)print_r(json_decode($json))
gt
29
Shop Documentation Release 001
30 Kapitel 11 Data export
KAPITEL 12
Messaging
Beside standard email messages the webshop supports sending MQ Telemetry Transport protocol (MQTT) messagesas an additional feature The MQTT messages are small
121 MQTT
Mosquitto-PHP is used as a PHP wrapper for MQTT Please check the Projectrsquos README for details about theinstallation and the setup
1211 Broker
Mosquitto is a message broker that implements the MQ Telemetry Transport protocol Check if mosquitto is run-ning
$ sudo systemctl status mosquittoservice
If not start it
$ systemctl start mosquittoservice
All messages are published to the topic webshop
1212 Publishing
After the installation of Mosquitto-PHP the snipplet shown below sends a single message
ltphpdefine(rsquoBROKERrsquo rsquolocalhostrsquo)define(rsquoPORTrsquo 1883)define(rsquoCLIENT_IDrsquo webshop_ + getmypid())$topic = webshop$subtopic = test$completeTopic = $topic$subtopic
$client = new MosquittoClient(CLIENT_ID)$client-gtconnect(BROKER PORT 60)
$message = Test message from webshop at date(Y-m-d His)$client-gtpublish($completeTopic $message 0 false)
gt
31
Shop Documentation Release 001
1213 Subscribing
To read the messages sent by the webshop a client is needed The Mosquitto broker contain a simple command-linetool for subscribing to various topics
$ mosquitto_sub -h localhost -t webshop
122 Email
This section doesnrsquot describe the installation and configuration of a local MTA There are enough resources thatcontains information about the setup of postfix for local delivery only
If you want to test the email feature add the following code in one of PHP pages
ltphp mail(rsquorootlocalhostrsquo rsquoTest message from webshoprsquo rsquoThe webshop is selling pencilsrsquo) gt
By default SELinux is running in Enforcing mode which is restrictive about about what a web server can do Toallow sending email the following SELinux boolean needs to changed
setsebool -P httpd_can_network_connect=1 setsebool -P httpd_can_sendmail=1
32 Kapitel 12 Messaging
KAPITEL 13
Localisation (L10n)
There are several ways to add localisation to a web site For small projects arrays with string can work but this is notvery efficient and user-friendly With Gettext is a toolset available that provide a framework to produce multi-lingualcontent in a wide area of programming languages
Make sure that the php-gettext package is available on your system If not install it
$ sudo yum -y install php-php-gettext
Check if gettext support is available
ltphpif (function_exists(gettext))
echo gettext is not installednelse
echo gettext is supportedn
gt
Make sure that all locales your want are available on the server
locale -a
The first step is to mark all string which should be translatable as shown below For further details please refer to theGettext documentation
echo _(rsquoSome textrsquo)
The next step is to extract all strings
xgettext --from-code=UTF-8 -o localewebshoppot php scriptsphp
To re-generate the file after an update join the strings
xgettext -j --from-code=UTF-8 -o localewebshoppot php scriptsphp
For every language a po file is needed for the transations Generate it with the command mentioned below
msginit --no-translator -l de_CH -o localede_CHpo -i localewebshoppot
Once created there are only updates of the message catalog needed in the futures
msgmerge -U localede_CHpo localewebshoppot
If you re finish create the mo file for the specific language
33
Shop Documentation Release 001
msgfmt -c -v -o localede_CHLC_MESSAGESwebshopmo localede_CHpo
34 Kapitel 13 Localisation (L10n)
KAPITEL 14
Templates
Beside other solutions Savant3 is a lightweight object-oriented template system for PHP This solution does not needa lot of additional configuration
141 Template
A simple template file looks like the one shown below
lthtmlgtltheadgt
lttitlegtltphp echo $this-gteprint($this-gttitle) gtlttitlegtltheadgtltbodygt
ltphp echo $this-gteprint($this-gtcontent) gtltbodygt
lthtmlgt
For a more detailed intro check this article on Zend Developer Zone
142 Content
To fill the template with data all wished variables needs to be defined in a seperate PHP file
ltphprequire_once rsquoscriptsSavant3phprsquo$tpl = new Savant3()
Create a title$title = Simple sample page
Create the content of the page$content = Some sample text to show
Assign values to the Savant instance$tpl-gttitle = $title$tpl-gtcontent = $content
Define the template source file to show$tpl-gtdisplay(rsquosimpletplphprsquo)
gt
35
Shop Documentation Release 001
The webshop contains a page (master)
36 Kapitel 14 Templates
KAPITEL 15
Development
This sections describes the configuration of the development and runtime environment for the web shop
151 Web server
Instead of Apache the project is running on Lighttpd The reasons are that Lighttpd provides faster setup easierconfiguration and better performance Lighttpd is running with FastCGI
The path of the web server is varwwwlighttpd and the SELinux configuration are still the defaults
The web server is running in SSL-only mode and the certificate is generated during the server setup process
152 Database server
For persistence storage the drop-in replacement MariaDB is used MySQL will work to but this is not tested phpMyAd-min is available under phpmyadmin on the web server beside the command-line tools for easy administration
The default credentials for phpMyAdmin are rootwebshop or the entry you made in the Ansible playbookdevelvariablessensitiveyml
153 Versions
The web shop is built with the below listed components and tested Other releases can be used and may work but thiswill not be tested Probably it will work with different releases
bull Operating system Fedora 20
bull Kernel 3135-202fc20x86_64
bull Lighttpd 1434
bull PHP 557
bull MariaDB 5534
For communication postfix and mosquitto are needed additionally
37
Shop Documentation Release 001
154 Setup infrastructure
1541 Configuration management
For the creation of reproducable and identical environment for the development and the run-time across differentsystems Ansible is used as configuration management solution All needed steps of the installation are automated Theconfiguration doesnrsquot differentiate between local or remote installations This matters only for the deployment of theweb content
For local development itrsquos possible to use an LX container
$ sudo ansible-playbook develcontaineryml
To get everything running some additional steps (check the network inside the container generate keys etc) areneeded After you are done check it
$ sudo ansible webshop -m setup
From the management system
$ sudo ssh-copy-id -i rootsshid_rsapub root[IP address of your managed node]
The configuration of Ansible itself (adding the system to etcansiblehosts and copying the SSH keys) isnot documented at this place There are various resources available like here All playbooks are located in the folderdevel Start the setup with the command shown below
$ sudo ansible-playbook develsetupyml
The used group name in etcansiblehosts is webshop
If the setup completes without errors then the web server is accessible and show a default page Please keep in mindthat the server is only accessible over https unencrypted traffic is not allowed
1542 DeploymentSetup website
For the simple deployment of the lastest version of the shop a playbook called deployyml is provided Thisplaybook put all files in place
$ sudo ansible-playbook develdeployyml
To full deploy the webshop all tables in the database must exist The file webshopsql contains all needed SQLcommands and sample data for the web application
Itrsquos possible to deploy the website manually but this is not recommended A couple of files are depending on templateswhich are created during the deployment
Itrsquos also not recommanded to clone everything into your webserver root This would save you the trouble of doing itby hand but third-party features are missing then Those missing parts are the template engine the pdf generation theconnection to Openstreetmap and probably other things not mentioned here
155 Git respository
All project relevante informations (Source code templates documentation etc) is located in a public Git repositoryon Github
38 Kapitel 15 Development
Shop Documentation Release 001
156 Documentation
The documentation is using reStructuredText as markup language For a local build Sphinx is needed Sphinx isavailable in the Fedora Package Collection and can be installed with yum or any other package management tool
yum -y install python-sphinx python-docutils
The source files of the documentation are located under docs
$ cd docs$ make html
The output is stored under docs_buildhtml
After every push to Github a hook launch a rebuild of the documentation The latest release will be published on Readthe Docs automatically
httpsshoprtfdorg
156 Documentation 39
Shop Documentation Release 001
40 Kapitel 15 Development
KAPITEL 16
Indices and tables
bull genindex
bull modindex
bull search
41
- Basics
-
- Products
- Personas
- Use cases
- Design principles
-
- Web shop Design
-
- General
- Layout
- Sitemap
- Main page
-
- Style and design
-
- Cascading Style Sheets
- Pages
-
- Dynamics
-
- Setup
- Current year
- Navigation Menu
- List of Products
- Company details
-
- External files
-
- Navigation Menu
- Header
- Footer
-
- Input processing
-
- ``Buy Now links
- Select options
-
- Javascript
-
- Simple use case
-
- Cookies and Sessions
-
- Cookies
- Hit counter
- Language selection
- User Accounts
-
- Database
-
- Tables
- PHP
-
- Web service
-
- Map
- Weather
-
- Data export
-
- JSON
-
- Messaging
-
- MQTT
-
- Localisation (L10n)
- Templates
-
- Template
- Content
-
- Development
-
- Web server
- Database server
- Versions
- Setup infrastructure
- Git respository
- Documentation
-
- Indices and tables
-
Shop Documentation Release 001
23 Sitemap
The sitemap shows the clustering of the shop at the beginning of the project
This doesnrsquot mean that everything will be done Static pages are easy to make and to maintain
8 Kapitel 2 Web shop Design
Shop Documentation Release 001
24 Main page
The first draft of the main page is based on the prototype shown in section Layout without any format- und styleinformationen
ltDOCTYPE htmlgtlthtml lang=engt
ltheadgtltmeta charset=utf-8gtltmeta name=viewport content=width=device-width initial-scale=10gtltmeta name=description content=Webshop Pencil AG fuumlr Bleistiftegtltmeta name=author content=Fabian AffoltergtlttitlegtWebshop Pencil AG | Homelttitlegt
ltheadgt
ltbodygtlt-- Header container--gtltdivgt
ltdivgtlt-- Logo and company name --gtltimg src=logologopnggtlth2gtWebshop Pencil AGlth2gtlt-- Navigation --gtltulgt
ltligtlta href=gtHomeltagtltligtltligtlta href=gtProdukteltagtltligtltligtlta href=gtUumlber unsltagtltligt
ltulgtlt-- Breadcrumb --gtltolgt
ltligtlta href=gtEbene 1ltagtltligtltligtlta href=gtEbene 2ltagtltligtltligtlta href=gtEbene 3ltagtltligt
ltolgtltdivgt
ltdivgtlt-- Header container--gt
lt-- Action container --gtltdivgt
lth1gtWochen-Aktionlth1gtltpgtDies ist eine super Aktion 10 Bleistifte fuumlr CHF 8ltpgt
ltdivgtlt-- Action container --gt
lt-- Selected products --gtltdivgt
ltpgtHier hat es zufaumlllige Produkteltpgtltdivgtlt-- Selected products --gt
lt-- Footer --gtltdivgt
ltpgtampcopy Pencil AG 2013ltpgtlt-- Footer --gtltdivgt
ltbodygtlthtmlgt
24 Main page 9
Shop Documentation Release 001
Loaded in a browser the initial draft of the main page looks like in the following screenshot
10 Kapitel 2 Web shop Design
KAPITEL 3
Style and design
31 Cascading Style Sheets
The design of the shop will be nothing fancy The approach which was choosen will reflect the points mentioned inthe Design principles section and makes heavy use of the bootstrap framework cascading style sheet Various changesto this CSS file ensure that it matche the needs of this project
32 Pages
The product page show the elements mentioned in the Product overview section
11
Shop Documentation Release 001
12 Kapitel 3 Style and design
KAPITEL 4
Dynamics
The webshop will be a PHP application at the end Those first steps are only covering the very basic stuff of PHP asan introduction
41 Setup
The setupyml playbook puts a simple PHP file in the root directory of the web server with the namephpinfophp This file displays PHP details
Achtung Remove this file before makeing the shop accessible by a public audience
42 Current year
The first PHP element in the webshop is showing the current year in the footer of every page With the help of thislittle piece of code there is no longer a need to update the year
ltphp echo date(Y) gt
43 Navigation Menu
The basic menu was built with the following snippet
ltphp$menu = array(rsquoHomersquo =gt rsquoindexphprsquo
rsquoProduktersquo =gt rsquoproductsphprsquorsquoUumlber unsrsquo =gt rsquoaboutphprsquo
)foreach($menu as $label =gt $link)
echo rsquoltligtlta href=rsquo $link rsquogtrsquo $label rsquoltagtltligtrsquo
gt
The issue with that snippet was that the CSS class was missing In regards to a future separation and reusability anadditional statements was added This way the label of the active page is highlighted
13
Shop Documentation Release 001
ltphp$menu = array(rsquoHomersquo =gt rsquoindexphprsquo
rsquoProduktersquo =gt rsquoproductsphprsquorsquoUumlber unsrsquo =gt rsquoaboutphprsquo
)foreach ($menu as $label =gt $link)
$url = trim($_SERVER[rsquoPHP_SELFrsquo] rsquorsquo)if ($link == $url)
echo rsquoltli class=activegtlta href=rsquo $link rsquogtrsquo $label rsquoltagtltligtrsquo else
echo rsquoltli class=gtlta href=rsquo $link rsquogtrsquo $label rsquoltagtltligtrsquo
gt
44 List of Products
The product overiew is a simple table The heading of the table is placed in an array
ltdivgtlttable class=table table-stripedgtltthead valign=bottomgtlttrgtltphp
$heading = array(rsquoTypersquo rsquoVariantrsquo rsquoColorrsquo rsquoHardnessrsquo rsquoPrice CHFrsquo)foreach ($heading as $element)
echo rsquoltth class=headgtrsquo$elementrsquoltthgtrsquon
gtlttrgtlttheadgtlttbody valign=topgtltphp
$products = array(array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquoHBrsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquoBrsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquo2Brsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquoFrsquo rsquo12rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquoHrsquo rsquo12rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquo2Hrsquo rsquo12rsquo)
)foreach ($products as $product =gt $details)
echo lttrgtforeach ($details as $detail)
echo lttdgt$detaillttdgtecho lttrgt
gtlttbodygtlttablegt
ltdivgt
14 Kapitel 4 Dynamics
Shop Documentation Release 001
45 Company details
The data for the About page are included out of a static and plain text file
ltphp$str = file_get_contents(companytxt)echo $str
gt
45 Company details 15
Shop Documentation Release 001
16 Kapitel 4 Dynamics
KAPITEL 5
External files
51 Navigation Menu
The menu is outsourced in the file menuphp
ltphpfunction menu()
$part1 = rsquoltul class=nav nav-tabsgtrsquon$part2 = rsquorsquo$part3 = rsquoltulgtrsquon Menu array with page title and assigned file$menu = array(rsquoHomersquo =gt rsquoindexphprsquo
rsquoProduktersquo =gt rsquoproductsphprsquorsquoUumlber unsrsquo =gt rsquoaboutphprsquo
)foreach ($menu as $label =gt $link)
For the CSS only the file name without is needed$url = trim($_SERVER[rsquoPHP_SELFrsquo] rsquorsquo)if ($link == $url)
$part2 = $part2ltli class=rsquoactiversquogtlta href=rsquo$linkrsquogt$labelltagtltligtn else
$part2 = $part2ltli class=rsquorsquogtlta href=rsquo$linkrsquogt$labelltagtltligtn
return $part1$part2$part3
gt
52 Header
The complete header part is loaded from the file headerphp
ltphpfunction head()
$start_page = indexphp$part1 = ltdivgtn$part2 = tlta class=rsquobrand-logorsquo href=rsquo$start_pagersquogtltagtn$part3 = tltp class=rsquobrand-namersquogtWebshop Pencil AGltpgtn$part4 = ltdivgtnreturn $part1$part2$part3$part4
17
Shop Documentation Release 001
gt
53 Footer
The same is done witht the page footers
ltphpfunction foot()
$class1 = rsquoltdiv class=footergtrsquon$class2 = rsquoltdivgtrsquon$text = ltpgtampcopy Pencil AG getYear()rsquoltpgtrsquonreturn $class1$text$class2
function getYear()return date(Y)
gt
18 Kapitel 5 External files
KAPITEL 6
Input processing
61 ldquoBuy Nowrdquo links
The ldquoBuy Nowrdquo links are attached to the Products page Every entry has itrsquos own link which lead to a detail page Thelinks are using hidden form elements to transfer the data
ltphp$products = array(array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquoHBrsquo rsquo1rsquo)
array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquoBrsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquo2Brsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquoFrsquo rsquo12rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquoHrsquo rsquo12rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquo2Hrsquo rsquo12rsquo)
)foreach ($products as $product =gt $details)
echo lttrgtnforeach ($details as $detail)
echo lttdgt$detaillttdgtnecho lttdgtnecho ltform action=rsquoproductphprsquo method=rsquogetrsquo name=rsquopencilrsquogtnecho ltinput type=rsquohiddenrsquo name=rsquotypersquo value=rsquo$details[0]rsquogtnecho ltinput type=rsquohiddenrsquo name=rsquooptionsrsquo value=rsquo$details[1]rsquogtnecho ltinput type=rsquohiddenrsquo name=rsquocolorrsquo value=rsquo$details[2]rsquogtnecho ltinput type=rsquohiddenrsquo name=rsquohardnessrsquo value=rsquo$details[3]rsquogtnecho ltinput type=rsquohiddenrsquo name=rsquopricersquo value=rsquo$details[4]rsquogtnecho ltinput type=rsquosubmitrsquo class=rsquobtn btn-defaultrsquo value=rsquoKauf michrsquogtnecho ltformgtnecho lttdgtnecho lttrgtn
gt
And the detail page contains the code fragement mentioned below
ltphp$type=$_GET[rsquotypersquo]$color=$_GET[rsquocolorrsquo]$hardness=$_GET[rsquohardnessrsquo]$options=$_GET[rsquooptionsrsquo]$price=$_GET[rsquopricersquo]echo I am a $type in $color and a hardness of $hardness I have $options as an option and my price is $price CHF
gt
19
Shop Documentation Release 001
Bemerkung The Products page was modified in the process of the development
62 Select options
The signupbilling page contains a dropdown element that all days of a month for the entry of the userrsquos birthday
ltselect name=daygtltoptiongtDayltoptiongt
ltphp$days = range(31 1)foreach ($days as $day)
echo rsquoltoption value=rsquo$dayrsquogtrsquo$dayrsquoltoptiongtrsquo
gtltselectgt
20 Kapitel 6 Input processing
KAPITEL 7
Javascript
Over the years Javascript became a very popular programming language The webshop is using Javascript at a coupleof places
71 Simple use case
Javascript makes it easy to access elements in the DOM Setting the focus is a nice way to support the user with inputform
ltscript language=javascriptgtfunction setFocus()
documentforms[login][username]focus()
ltscriptgtltheadgtltbody onload=setFocus()gt
Another one is to check if something was entered in an input field
function validateForm() var username = documentforms[rdquologinrdquo][rdquousernamerdquo]value if (username== null || username == ldquordquo)
documentforms[rdquologinrdquo][rdquousernamerdquo]stylebackgroundColor = ldquoFF9999rdquo docu-mentforms[rdquologinrdquo][rdquousernamerdquo]placeholder = ldquoPlease your usernamerdquo docu-mentforms[rdquologinrdquo][rdquousernamerdquo]focus() return false
A simple message is informing the user about an action which was taken against the database
echo ltscript type=textjavascriptgtalert(New entry $entry added successfully)windowlocation = tablesphp
ltscriptgt
The delete process is only executed if the user confirm to delete a record
ltform action=scriptsdelete-processphp onSubmit=return confirm(rsquoAre you sure to delete this entryrsquo) method=POSTgtltinput type=hidden name=table value=$sectiongtltinput type=hidden name=id value=$result-gtidgtltinput type=submit name=Submit value=Deletegt
ltformgt
For additional Javascript please check the source of the indexphp file and the reflsquowebservicelsquo_ section
21
Shop Documentation Release 001
22 Kapitel 7 Javascript
KAPITEL 8
Cookies and Sessions
The built-in support for sessions in PHP is handling all cookie manipulation to provide persistent variables that areaccessible from different pages and across multiple visits to the site
81 Cookies
A cookie is used to track the last time a visitor check the front page The cookie is set when a visitor arrives
function lastVisit($name $expire) $value = getDateDMY() - getTimeHM()setcookie($name $value time() + $expire rsquorsquo $_SERVER[rsquoSERVER_NAMErsquo] true true)
In the footer of the index page the details are presented
ltphpif(isset($_COOKIE[rsquoLastVisitrsquo]))
$last = $_COOKIE[rsquoLastVisitrsquo]echo You last visited us on $last
else echo This is your first visit
gt
82 Hit counter
As a simple show case for PHP sessions a hit counter for the front page is available
ltphpsession_start()
$_SESSION[rsquohitsrsquo] = $_SESSION[rsquohitsrsquo] + 1gt
Included in the footer it shous the users the total of visits
echo Total $_SESSION[rsquohitsrsquo] visits of this page
23
Shop Documentation Release 001
83 Language selection
84 User Accounts
24 Kapitel 8 Cookies and Sessions
KAPITEL 9
Database
The database backend for the webshop will be MariaDB which is the drop-in replacement for MySQL
For the setup please check the Development section in this documentation
91 Tables
The following tables are needed for the webshop to work
bull products
bull customers
bull pencils
bull colors
bull hardness
bull options
bull users
Please use the develwebshopsql to setup the database
92 PHP
Below you find the configuration file for a default installation of the webshop This file is a template and filled duringthe setup process
ltphp$host = localhost$user = root$password = webshop$dbase = webshop$connection = new mysqli($host $user $password $dbase)
if ($connection-gtconnect_errno) echo Failed to connect to MariaDBMySQL ($connection-gtconnect_errno) $connection-gtconnect_error
mysqli_report(MYSQLI_REPORT_ERROR)
gt
25
Shop Documentation Release 001
All connections to the database are done in the same way Below you find an example Everything is done in theobject-oriented style
ltphprequire_once(rsquoconfigdbconnectphprsquo)if ($connection-gtconnect_errno == 0)
$sql = SELECT FROM products$results = $connection-gtquery($sql)echo $results-gtnum_rows$results-gtclose()
else echo Database connection error
gt
26 Kapitel 9 Database
KAPITEL 10
Web service
Tow web services are integrated to take advantages of online available data sources
101 Map
Leafletjs a JavaScript library for working with interactive maps from OpenStreetMap (OSM) is implemented as ashow case for a simple web service
The basic steps to integrate a map is shown below
ltdiv id=map class=map style=width 600px height 400pxgtltdivgt
ltscript src=scriptsleafletjsgtltscriptgtltscript src=scriptsleaflet-providersjsgtltscriptgtltscriptgtvar map = Lmap(rsquomaprsquo
center [250472 -773255]zoom 12zoomControl true
)
var defaultLayer = LtileLayerprovider(rsquoOpenStreetMapMapnikrsquo)addTo(map)ltscriptgt
102 Weather
The OpenWeatherMap service provides free weather data and a forecast API for web applications
ltphp Details about the API httpbugsopenweathermaporgprojectsapiwikiApi_2_5_weather$url = rsquohttpapiopenweathermaporgdata25weatherq=Bernechampunit=metricsampmode=jsonrsquo
$json = file_get_contents($url)$data = json_decode($json)
$tempC = round((27315 - $data-gtmain-gttemp)100) 100$humidity = $data-gtmain-gthumidity$pressure = $data-gtmain-gtpressure
27
Shop Documentation Release 001
echo ltpgtTemperatur $tempC degCltbrgtnecho Luftfeuchtigkeit $humidity ltbrgtnecho Luftdruck $pressure Paltpgtn
gt
28 Kapitel 10 Web service
KAPITEL 11
Data export
111 PDF
FPDF is a PHP class that allows to generate PDF files with pure PHP As a showcase for that the product specificationsfor a given product are filled in a pdf and showed in the browser The user can then decide to download or print thefile
112 JSON
JavaScript Object Notation (JSON) is a lightweight data-interchange format The format is language independent andPHP support the encoding and the decoding JSON with json_encode($data) and json_decode($data)$rows = array()$sql = SELECT FROM products$results = $connection-gtquery($sql)while ($result = $results-gtfetch_object())
$rows[] = $result$results-gtclose()
Writing all rows to a JSON file$fp = fopen(rsquopencilsjsonrsquo rsquowrsquo)fwrite($fp json_encode($rows))fclose($fp)gt
and for reading it
ltphp$json = file_get_contents(rsquopencilsjsonrsquo)print_r(json_decode($json))
gt
29
Shop Documentation Release 001
30 Kapitel 11 Data export
KAPITEL 12
Messaging
Beside standard email messages the webshop supports sending MQ Telemetry Transport protocol (MQTT) messagesas an additional feature The MQTT messages are small
121 MQTT
Mosquitto-PHP is used as a PHP wrapper for MQTT Please check the Projectrsquos README for details about theinstallation and the setup
1211 Broker
Mosquitto is a message broker that implements the MQ Telemetry Transport protocol Check if mosquitto is run-ning
$ sudo systemctl status mosquittoservice
If not start it
$ systemctl start mosquittoservice
All messages are published to the topic webshop
1212 Publishing
After the installation of Mosquitto-PHP the snipplet shown below sends a single message
ltphpdefine(rsquoBROKERrsquo rsquolocalhostrsquo)define(rsquoPORTrsquo 1883)define(rsquoCLIENT_IDrsquo webshop_ + getmypid())$topic = webshop$subtopic = test$completeTopic = $topic$subtopic
$client = new MosquittoClient(CLIENT_ID)$client-gtconnect(BROKER PORT 60)
$message = Test message from webshop at date(Y-m-d His)$client-gtpublish($completeTopic $message 0 false)
gt
31
Shop Documentation Release 001
1213 Subscribing
To read the messages sent by the webshop a client is needed The Mosquitto broker contain a simple command-linetool for subscribing to various topics
$ mosquitto_sub -h localhost -t webshop
122 Email
This section doesnrsquot describe the installation and configuration of a local MTA There are enough resources thatcontains information about the setup of postfix for local delivery only
If you want to test the email feature add the following code in one of PHP pages
ltphp mail(rsquorootlocalhostrsquo rsquoTest message from webshoprsquo rsquoThe webshop is selling pencilsrsquo) gt
By default SELinux is running in Enforcing mode which is restrictive about about what a web server can do Toallow sending email the following SELinux boolean needs to changed
setsebool -P httpd_can_network_connect=1 setsebool -P httpd_can_sendmail=1
32 Kapitel 12 Messaging
KAPITEL 13
Localisation (L10n)
There are several ways to add localisation to a web site For small projects arrays with string can work but this is notvery efficient and user-friendly With Gettext is a toolset available that provide a framework to produce multi-lingualcontent in a wide area of programming languages
Make sure that the php-gettext package is available on your system If not install it
$ sudo yum -y install php-php-gettext
Check if gettext support is available
ltphpif (function_exists(gettext))
echo gettext is not installednelse
echo gettext is supportedn
gt
Make sure that all locales your want are available on the server
locale -a
The first step is to mark all string which should be translatable as shown below For further details please refer to theGettext documentation
echo _(rsquoSome textrsquo)
The next step is to extract all strings
xgettext --from-code=UTF-8 -o localewebshoppot php scriptsphp
To re-generate the file after an update join the strings
xgettext -j --from-code=UTF-8 -o localewebshoppot php scriptsphp
For every language a po file is needed for the transations Generate it with the command mentioned below
msginit --no-translator -l de_CH -o localede_CHpo -i localewebshoppot
Once created there are only updates of the message catalog needed in the futures
msgmerge -U localede_CHpo localewebshoppot
If you re finish create the mo file for the specific language
33
Shop Documentation Release 001
msgfmt -c -v -o localede_CHLC_MESSAGESwebshopmo localede_CHpo
34 Kapitel 13 Localisation (L10n)
KAPITEL 14
Templates
Beside other solutions Savant3 is a lightweight object-oriented template system for PHP This solution does not needa lot of additional configuration
141 Template
A simple template file looks like the one shown below
lthtmlgtltheadgt
lttitlegtltphp echo $this-gteprint($this-gttitle) gtlttitlegtltheadgtltbodygt
ltphp echo $this-gteprint($this-gtcontent) gtltbodygt
lthtmlgt
For a more detailed intro check this article on Zend Developer Zone
142 Content
To fill the template with data all wished variables needs to be defined in a seperate PHP file
ltphprequire_once rsquoscriptsSavant3phprsquo$tpl = new Savant3()
Create a title$title = Simple sample page
Create the content of the page$content = Some sample text to show
Assign values to the Savant instance$tpl-gttitle = $title$tpl-gtcontent = $content
Define the template source file to show$tpl-gtdisplay(rsquosimpletplphprsquo)
gt
35
Shop Documentation Release 001
The webshop contains a page (master)
36 Kapitel 14 Templates
KAPITEL 15
Development
This sections describes the configuration of the development and runtime environment for the web shop
151 Web server
Instead of Apache the project is running on Lighttpd The reasons are that Lighttpd provides faster setup easierconfiguration and better performance Lighttpd is running with FastCGI
The path of the web server is varwwwlighttpd and the SELinux configuration are still the defaults
The web server is running in SSL-only mode and the certificate is generated during the server setup process
152 Database server
For persistence storage the drop-in replacement MariaDB is used MySQL will work to but this is not tested phpMyAd-min is available under phpmyadmin on the web server beside the command-line tools for easy administration
The default credentials for phpMyAdmin are rootwebshop or the entry you made in the Ansible playbookdevelvariablessensitiveyml
153 Versions
The web shop is built with the below listed components and tested Other releases can be used and may work but thiswill not be tested Probably it will work with different releases
bull Operating system Fedora 20
bull Kernel 3135-202fc20x86_64
bull Lighttpd 1434
bull PHP 557
bull MariaDB 5534
For communication postfix and mosquitto are needed additionally
37
Shop Documentation Release 001
154 Setup infrastructure
1541 Configuration management
For the creation of reproducable and identical environment for the development and the run-time across differentsystems Ansible is used as configuration management solution All needed steps of the installation are automated Theconfiguration doesnrsquot differentiate between local or remote installations This matters only for the deployment of theweb content
For local development itrsquos possible to use an LX container
$ sudo ansible-playbook develcontaineryml
To get everything running some additional steps (check the network inside the container generate keys etc) areneeded After you are done check it
$ sudo ansible webshop -m setup
From the management system
$ sudo ssh-copy-id -i rootsshid_rsapub root[IP address of your managed node]
The configuration of Ansible itself (adding the system to etcansiblehosts and copying the SSH keys) isnot documented at this place There are various resources available like here All playbooks are located in the folderdevel Start the setup with the command shown below
$ sudo ansible-playbook develsetupyml
The used group name in etcansiblehosts is webshop
If the setup completes without errors then the web server is accessible and show a default page Please keep in mindthat the server is only accessible over https unencrypted traffic is not allowed
1542 DeploymentSetup website
For the simple deployment of the lastest version of the shop a playbook called deployyml is provided Thisplaybook put all files in place
$ sudo ansible-playbook develdeployyml
To full deploy the webshop all tables in the database must exist The file webshopsql contains all needed SQLcommands and sample data for the web application
Itrsquos possible to deploy the website manually but this is not recommended A couple of files are depending on templateswhich are created during the deployment
Itrsquos also not recommanded to clone everything into your webserver root This would save you the trouble of doing itby hand but third-party features are missing then Those missing parts are the template engine the pdf generation theconnection to Openstreetmap and probably other things not mentioned here
155 Git respository
All project relevante informations (Source code templates documentation etc) is located in a public Git repositoryon Github
38 Kapitel 15 Development
Shop Documentation Release 001
156 Documentation
The documentation is using reStructuredText as markup language For a local build Sphinx is needed Sphinx isavailable in the Fedora Package Collection and can be installed with yum or any other package management tool
yum -y install python-sphinx python-docutils
The source files of the documentation are located under docs
$ cd docs$ make html
The output is stored under docs_buildhtml
After every push to Github a hook launch a rebuild of the documentation The latest release will be published on Readthe Docs automatically
httpsshoprtfdorg
156 Documentation 39
Shop Documentation Release 001
40 Kapitel 15 Development
KAPITEL 16
Indices and tables
bull genindex
bull modindex
bull search
41
- Basics
-
- Products
- Personas
- Use cases
- Design principles
-
- Web shop Design
-
- General
- Layout
- Sitemap
- Main page
-
- Style and design
-
- Cascading Style Sheets
- Pages
-
- Dynamics
-
- Setup
- Current year
- Navigation Menu
- List of Products
- Company details
-
- External files
-
- Navigation Menu
- Header
- Footer
-
- Input processing
-
- ``Buy Now links
- Select options
-
- Javascript
-
- Simple use case
-
- Cookies and Sessions
-
- Cookies
- Hit counter
- Language selection
- User Accounts
-
- Database
-
- Tables
- PHP
-
- Web service
-
- Map
- Weather
-
- Data export
-
- JSON
-
- Messaging
-
- MQTT
-
- Localisation (L10n)
- Templates
-
- Template
- Content
-
- Development
-
- Web server
- Database server
- Versions
- Setup infrastructure
- Git respository
- Documentation
-
- Indices and tables
-
Shop Documentation Release 001
24 Main page
The first draft of the main page is based on the prototype shown in section Layout without any format- und styleinformationen
ltDOCTYPE htmlgtlthtml lang=engt
ltheadgtltmeta charset=utf-8gtltmeta name=viewport content=width=device-width initial-scale=10gtltmeta name=description content=Webshop Pencil AG fuumlr Bleistiftegtltmeta name=author content=Fabian AffoltergtlttitlegtWebshop Pencil AG | Homelttitlegt
ltheadgt
ltbodygtlt-- Header container--gtltdivgt
ltdivgtlt-- Logo and company name --gtltimg src=logologopnggtlth2gtWebshop Pencil AGlth2gtlt-- Navigation --gtltulgt
ltligtlta href=gtHomeltagtltligtltligtlta href=gtProdukteltagtltligtltligtlta href=gtUumlber unsltagtltligt
ltulgtlt-- Breadcrumb --gtltolgt
ltligtlta href=gtEbene 1ltagtltligtltligtlta href=gtEbene 2ltagtltligtltligtlta href=gtEbene 3ltagtltligt
ltolgtltdivgt
ltdivgtlt-- Header container--gt
lt-- Action container --gtltdivgt
lth1gtWochen-Aktionlth1gtltpgtDies ist eine super Aktion 10 Bleistifte fuumlr CHF 8ltpgt
ltdivgtlt-- Action container --gt
lt-- Selected products --gtltdivgt
ltpgtHier hat es zufaumlllige Produkteltpgtltdivgtlt-- Selected products --gt
lt-- Footer --gtltdivgt
ltpgtampcopy Pencil AG 2013ltpgtlt-- Footer --gtltdivgt
ltbodygtlthtmlgt
24 Main page 9
Shop Documentation Release 001
Loaded in a browser the initial draft of the main page looks like in the following screenshot
10 Kapitel 2 Web shop Design
KAPITEL 3
Style and design
31 Cascading Style Sheets
The design of the shop will be nothing fancy The approach which was choosen will reflect the points mentioned inthe Design principles section and makes heavy use of the bootstrap framework cascading style sheet Various changesto this CSS file ensure that it matche the needs of this project
32 Pages
The product page show the elements mentioned in the Product overview section
11
Shop Documentation Release 001
12 Kapitel 3 Style and design
KAPITEL 4
Dynamics
The webshop will be a PHP application at the end Those first steps are only covering the very basic stuff of PHP asan introduction
41 Setup
The setupyml playbook puts a simple PHP file in the root directory of the web server with the namephpinfophp This file displays PHP details
Achtung Remove this file before makeing the shop accessible by a public audience
42 Current year
The first PHP element in the webshop is showing the current year in the footer of every page With the help of thislittle piece of code there is no longer a need to update the year
ltphp echo date(Y) gt
43 Navigation Menu
The basic menu was built with the following snippet
ltphp$menu = array(rsquoHomersquo =gt rsquoindexphprsquo
rsquoProduktersquo =gt rsquoproductsphprsquorsquoUumlber unsrsquo =gt rsquoaboutphprsquo
)foreach($menu as $label =gt $link)
echo rsquoltligtlta href=rsquo $link rsquogtrsquo $label rsquoltagtltligtrsquo
gt
The issue with that snippet was that the CSS class was missing In regards to a future separation and reusability anadditional statements was added This way the label of the active page is highlighted
13
Shop Documentation Release 001
ltphp$menu = array(rsquoHomersquo =gt rsquoindexphprsquo
rsquoProduktersquo =gt rsquoproductsphprsquorsquoUumlber unsrsquo =gt rsquoaboutphprsquo
)foreach ($menu as $label =gt $link)
$url = trim($_SERVER[rsquoPHP_SELFrsquo] rsquorsquo)if ($link == $url)
echo rsquoltli class=activegtlta href=rsquo $link rsquogtrsquo $label rsquoltagtltligtrsquo else
echo rsquoltli class=gtlta href=rsquo $link rsquogtrsquo $label rsquoltagtltligtrsquo
gt
44 List of Products
The product overiew is a simple table The heading of the table is placed in an array
ltdivgtlttable class=table table-stripedgtltthead valign=bottomgtlttrgtltphp
$heading = array(rsquoTypersquo rsquoVariantrsquo rsquoColorrsquo rsquoHardnessrsquo rsquoPrice CHFrsquo)foreach ($heading as $element)
echo rsquoltth class=headgtrsquo$elementrsquoltthgtrsquon
gtlttrgtlttheadgtlttbody valign=topgtltphp
$products = array(array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquoHBrsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquoBrsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquo2Brsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquoFrsquo rsquo12rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquoHrsquo rsquo12rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquo2Hrsquo rsquo12rsquo)
)foreach ($products as $product =gt $details)
echo lttrgtforeach ($details as $detail)
echo lttdgt$detaillttdgtecho lttrgt
gtlttbodygtlttablegt
ltdivgt
14 Kapitel 4 Dynamics
Shop Documentation Release 001
45 Company details
The data for the About page are included out of a static and plain text file
ltphp$str = file_get_contents(companytxt)echo $str
gt
45 Company details 15
Shop Documentation Release 001
16 Kapitel 4 Dynamics
KAPITEL 5
External files
51 Navigation Menu
The menu is outsourced in the file menuphp
ltphpfunction menu()
$part1 = rsquoltul class=nav nav-tabsgtrsquon$part2 = rsquorsquo$part3 = rsquoltulgtrsquon Menu array with page title and assigned file$menu = array(rsquoHomersquo =gt rsquoindexphprsquo
rsquoProduktersquo =gt rsquoproductsphprsquorsquoUumlber unsrsquo =gt rsquoaboutphprsquo
)foreach ($menu as $label =gt $link)
For the CSS only the file name without is needed$url = trim($_SERVER[rsquoPHP_SELFrsquo] rsquorsquo)if ($link == $url)
$part2 = $part2ltli class=rsquoactiversquogtlta href=rsquo$linkrsquogt$labelltagtltligtn else
$part2 = $part2ltli class=rsquorsquogtlta href=rsquo$linkrsquogt$labelltagtltligtn
return $part1$part2$part3
gt
52 Header
The complete header part is loaded from the file headerphp
ltphpfunction head()
$start_page = indexphp$part1 = ltdivgtn$part2 = tlta class=rsquobrand-logorsquo href=rsquo$start_pagersquogtltagtn$part3 = tltp class=rsquobrand-namersquogtWebshop Pencil AGltpgtn$part4 = ltdivgtnreturn $part1$part2$part3$part4
17
Shop Documentation Release 001
gt
53 Footer
The same is done witht the page footers
ltphpfunction foot()
$class1 = rsquoltdiv class=footergtrsquon$class2 = rsquoltdivgtrsquon$text = ltpgtampcopy Pencil AG getYear()rsquoltpgtrsquonreturn $class1$text$class2
function getYear()return date(Y)
gt
18 Kapitel 5 External files
KAPITEL 6
Input processing
61 ldquoBuy Nowrdquo links
The ldquoBuy Nowrdquo links are attached to the Products page Every entry has itrsquos own link which lead to a detail page Thelinks are using hidden form elements to transfer the data
ltphp$products = array(array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquoHBrsquo rsquo1rsquo)
array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquoBrsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquo2Brsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquoFrsquo rsquo12rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquoHrsquo rsquo12rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquo2Hrsquo rsquo12rsquo)
)foreach ($products as $product =gt $details)
echo lttrgtnforeach ($details as $detail)
echo lttdgt$detaillttdgtnecho lttdgtnecho ltform action=rsquoproductphprsquo method=rsquogetrsquo name=rsquopencilrsquogtnecho ltinput type=rsquohiddenrsquo name=rsquotypersquo value=rsquo$details[0]rsquogtnecho ltinput type=rsquohiddenrsquo name=rsquooptionsrsquo value=rsquo$details[1]rsquogtnecho ltinput type=rsquohiddenrsquo name=rsquocolorrsquo value=rsquo$details[2]rsquogtnecho ltinput type=rsquohiddenrsquo name=rsquohardnessrsquo value=rsquo$details[3]rsquogtnecho ltinput type=rsquohiddenrsquo name=rsquopricersquo value=rsquo$details[4]rsquogtnecho ltinput type=rsquosubmitrsquo class=rsquobtn btn-defaultrsquo value=rsquoKauf michrsquogtnecho ltformgtnecho lttdgtnecho lttrgtn
gt
And the detail page contains the code fragement mentioned below
ltphp$type=$_GET[rsquotypersquo]$color=$_GET[rsquocolorrsquo]$hardness=$_GET[rsquohardnessrsquo]$options=$_GET[rsquooptionsrsquo]$price=$_GET[rsquopricersquo]echo I am a $type in $color and a hardness of $hardness I have $options as an option and my price is $price CHF
gt
19
Shop Documentation Release 001
Bemerkung The Products page was modified in the process of the development
62 Select options
The signupbilling page contains a dropdown element that all days of a month for the entry of the userrsquos birthday
ltselect name=daygtltoptiongtDayltoptiongt
ltphp$days = range(31 1)foreach ($days as $day)
echo rsquoltoption value=rsquo$dayrsquogtrsquo$dayrsquoltoptiongtrsquo
gtltselectgt
20 Kapitel 6 Input processing
KAPITEL 7
Javascript
Over the years Javascript became a very popular programming language The webshop is using Javascript at a coupleof places
71 Simple use case
Javascript makes it easy to access elements in the DOM Setting the focus is a nice way to support the user with inputform
ltscript language=javascriptgtfunction setFocus()
documentforms[login][username]focus()
ltscriptgtltheadgtltbody onload=setFocus()gt
Another one is to check if something was entered in an input field
function validateForm() var username = documentforms[rdquologinrdquo][rdquousernamerdquo]value if (username== null || username == ldquordquo)
documentforms[rdquologinrdquo][rdquousernamerdquo]stylebackgroundColor = ldquoFF9999rdquo docu-mentforms[rdquologinrdquo][rdquousernamerdquo]placeholder = ldquoPlease your usernamerdquo docu-mentforms[rdquologinrdquo][rdquousernamerdquo]focus() return false
A simple message is informing the user about an action which was taken against the database
echo ltscript type=textjavascriptgtalert(New entry $entry added successfully)windowlocation = tablesphp
ltscriptgt
The delete process is only executed if the user confirm to delete a record
ltform action=scriptsdelete-processphp onSubmit=return confirm(rsquoAre you sure to delete this entryrsquo) method=POSTgtltinput type=hidden name=table value=$sectiongtltinput type=hidden name=id value=$result-gtidgtltinput type=submit name=Submit value=Deletegt
ltformgt
For additional Javascript please check the source of the indexphp file and the reflsquowebservicelsquo_ section
21
Shop Documentation Release 001
22 Kapitel 7 Javascript
KAPITEL 8
Cookies and Sessions
The built-in support for sessions in PHP is handling all cookie manipulation to provide persistent variables that areaccessible from different pages and across multiple visits to the site
81 Cookies
A cookie is used to track the last time a visitor check the front page The cookie is set when a visitor arrives
function lastVisit($name $expire) $value = getDateDMY() - getTimeHM()setcookie($name $value time() + $expire rsquorsquo $_SERVER[rsquoSERVER_NAMErsquo] true true)
In the footer of the index page the details are presented
ltphpif(isset($_COOKIE[rsquoLastVisitrsquo]))
$last = $_COOKIE[rsquoLastVisitrsquo]echo You last visited us on $last
else echo This is your first visit
gt
82 Hit counter
As a simple show case for PHP sessions a hit counter for the front page is available
ltphpsession_start()
$_SESSION[rsquohitsrsquo] = $_SESSION[rsquohitsrsquo] + 1gt
Included in the footer it shous the users the total of visits
echo Total $_SESSION[rsquohitsrsquo] visits of this page
23
Shop Documentation Release 001
83 Language selection
84 User Accounts
24 Kapitel 8 Cookies and Sessions
KAPITEL 9
Database
The database backend for the webshop will be MariaDB which is the drop-in replacement for MySQL
For the setup please check the Development section in this documentation
91 Tables
The following tables are needed for the webshop to work
bull products
bull customers
bull pencils
bull colors
bull hardness
bull options
bull users
Please use the develwebshopsql to setup the database
92 PHP
Below you find the configuration file for a default installation of the webshop This file is a template and filled duringthe setup process
ltphp$host = localhost$user = root$password = webshop$dbase = webshop$connection = new mysqli($host $user $password $dbase)
if ($connection-gtconnect_errno) echo Failed to connect to MariaDBMySQL ($connection-gtconnect_errno) $connection-gtconnect_error
mysqli_report(MYSQLI_REPORT_ERROR)
gt
25
Shop Documentation Release 001
All connections to the database are done in the same way Below you find an example Everything is done in theobject-oriented style
ltphprequire_once(rsquoconfigdbconnectphprsquo)if ($connection-gtconnect_errno == 0)
$sql = SELECT FROM products$results = $connection-gtquery($sql)echo $results-gtnum_rows$results-gtclose()
else echo Database connection error
gt
26 Kapitel 9 Database
KAPITEL 10
Web service
Tow web services are integrated to take advantages of online available data sources
101 Map
Leafletjs a JavaScript library for working with interactive maps from OpenStreetMap (OSM) is implemented as ashow case for a simple web service
The basic steps to integrate a map is shown below
ltdiv id=map class=map style=width 600px height 400pxgtltdivgt
ltscript src=scriptsleafletjsgtltscriptgtltscript src=scriptsleaflet-providersjsgtltscriptgtltscriptgtvar map = Lmap(rsquomaprsquo
center [250472 -773255]zoom 12zoomControl true
)
var defaultLayer = LtileLayerprovider(rsquoOpenStreetMapMapnikrsquo)addTo(map)ltscriptgt
102 Weather
The OpenWeatherMap service provides free weather data and a forecast API for web applications
ltphp Details about the API httpbugsopenweathermaporgprojectsapiwikiApi_2_5_weather$url = rsquohttpapiopenweathermaporgdata25weatherq=Bernechampunit=metricsampmode=jsonrsquo
$json = file_get_contents($url)$data = json_decode($json)
$tempC = round((27315 - $data-gtmain-gttemp)100) 100$humidity = $data-gtmain-gthumidity$pressure = $data-gtmain-gtpressure
27
Shop Documentation Release 001
echo ltpgtTemperatur $tempC degCltbrgtnecho Luftfeuchtigkeit $humidity ltbrgtnecho Luftdruck $pressure Paltpgtn
gt
28 Kapitel 10 Web service
KAPITEL 11
Data export
111 PDF
FPDF is a PHP class that allows to generate PDF files with pure PHP As a showcase for that the product specificationsfor a given product are filled in a pdf and showed in the browser The user can then decide to download or print thefile
112 JSON
JavaScript Object Notation (JSON) is a lightweight data-interchange format The format is language independent andPHP support the encoding and the decoding JSON with json_encode($data) and json_decode($data)$rows = array()$sql = SELECT FROM products$results = $connection-gtquery($sql)while ($result = $results-gtfetch_object())
$rows[] = $result$results-gtclose()
Writing all rows to a JSON file$fp = fopen(rsquopencilsjsonrsquo rsquowrsquo)fwrite($fp json_encode($rows))fclose($fp)gt
and for reading it
ltphp$json = file_get_contents(rsquopencilsjsonrsquo)print_r(json_decode($json))
gt
29
Shop Documentation Release 001
30 Kapitel 11 Data export
KAPITEL 12
Messaging
Beside standard email messages the webshop supports sending MQ Telemetry Transport protocol (MQTT) messagesas an additional feature The MQTT messages are small
121 MQTT
Mosquitto-PHP is used as a PHP wrapper for MQTT Please check the Projectrsquos README for details about theinstallation and the setup
1211 Broker
Mosquitto is a message broker that implements the MQ Telemetry Transport protocol Check if mosquitto is run-ning
$ sudo systemctl status mosquittoservice
If not start it
$ systemctl start mosquittoservice
All messages are published to the topic webshop
1212 Publishing
After the installation of Mosquitto-PHP the snipplet shown below sends a single message
ltphpdefine(rsquoBROKERrsquo rsquolocalhostrsquo)define(rsquoPORTrsquo 1883)define(rsquoCLIENT_IDrsquo webshop_ + getmypid())$topic = webshop$subtopic = test$completeTopic = $topic$subtopic
$client = new MosquittoClient(CLIENT_ID)$client-gtconnect(BROKER PORT 60)
$message = Test message from webshop at date(Y-m-d His)$client-gtpublish($completeTopic $message 0 false)
gt
31
Shop Documentation Release 001
1213 Subscribing
To read the messages sent by the webshop a client is needed The Mosquitto broker contain a simple command-linetool for subscribing to various topics
$ mosquitto_sub -h localhost -t webshop
122 Email
This section doesnrsquot describe the installation and configuration of a local MTA There are enough resources thatcontains information about the setup of postfix for local delivery only
If you want to test the email feature add the following code in one of PHP pages
ltphp mail(rsquorootlocalhostrsquo rsquoTest message from webshoprsquo rsquoThe webshop is selling pencilsrsquo) gt
By default SELinux is running in Enforcing mode which is restrictive about about what a web server can do Toallow sending email the following SELinux boolean needs to changed
setsebool -P httpd_can_network_connect=1 setsebool -P httpd_can_sendmail=1
32 Kapitel 12 Messaging
KAPITEL 13
Localisation (L10n)
There are several ways to add localisation to a web site For small projects arrays with string can work but this is notvery efficient and user-friendly With Gettext is a toolset available that provide a framework to produce multi-lingualcontent in a wide area of programming languages
Make sure that the php-gettext package is available on your system If not install it
$ sudo yum -y install php-php-gettext
Check if gettext support is available
ltphpif (function_exists(gettext))
echo gettext is not installednelse
echo gettext is supportedn
gt
Make sure that all locales your want are available on the server
locale -a
The first step is to mark all string which should be translatable as shown below For further details please refer to theGettext documentation
echo _(rsquoSome textrsquo)
The next step is to extract all strings
xgettext --from-code=UTF-8 -o localewebshoppot php scriptsphp
To re-generate the file after an update join the strings
xgettext -j --from-code=UTF-8 -o localewebshoppot php scriptsphp
For every language a po file is needed for the transations Generate it with the command mentioned below
msginit --no-translator -l de_CH -o localede_CHpo -i localewebshoppot
Once created there are only updates of the message catalog needed in the futures
msgmerge -U localede_CHpo localewebshoppot
If you re finish create the mo file for the specific language
33
Shop Documentation Release 001
msgfmt -c -v -o localede_CHLC_MESSAGESwebshopmo localede_CHpo
34 Kapitel 13 Localisation (L10n)
KAPITEL 14
Templates
Beside other solutions Savant3 is a lightweight object-oriented template system for PHP This solution does not needa lot of additional configuration
141 Template
A simple template file looks like the one shown below
lthtmlgtltheadgt
lttitlegtltphp echo $this-gteprint($this-gttitle) gtlttitlegtltheadgtltbodygt
ltphp echo $this-gteprint($this-gtcontent) gtltbodygt
lthtmlgt
For a more detailed intro check this article on Zend Developer Zone
142 Content
To fill the template with data all wished variables needs to be defined in a seperate PHP file
ltphprequire_once rsquoscriptsSavant3phprsquo$tpl = new Savant3()
Create a title$title = Simple sample page
Create the content of the page$content = Some sample text to show
Assign values to the Savant instance$tpl-gttitle = $title$tpl-gtcontent = $content
Define the template source file to show$tpl-gtdisplay(rsquosimpletplphprsquo)
gt
35
Shop Documentation Release 001
The webshop contains a page (master)
36 Kapitel 14 Templates
KAPITEL 15
Development
This sections describes the configuration of the development and runtime environment for the web shop
151 Web server
Instead of Apache the project is running on Lighttpd The reasons are that Lighttpd provides faster setup easierconfiguration and better performance Lighttpd is running with FastCGI
The path of the web server is varwwwlighttpd and the SELinux configuration are still the defaults
The web server is running in SSL-only mode and the certificate is generated during the server setup process
152 Database server
For persistence storage the drop-in replacement MariaDB is used MySQL will work to but this is not tested phpMyAd-min is available under phpmyadmin on the web server beside the command-line tools for easy administration
The default credentials for phpMyAdmin are rootwebshop or the entry you made in the Ansible playbookdevelvariablessensitiveyml
153 Versions
The web shop is built with the below listed components and tested Other releases can be used and may work but thiswill not be tested Probably it will work with different releases
bull Operating system Fedora 20
bull Kernel 3135-202fc20x86_64
bull Lighttpd 1434
bull PHP 557
bull MariaDB 5534
For communication postfix and mosquitto are needed additionally
37
Shop Documentation Release 001
154 Setup infrastructure
1541 Configuration management
For the creation of reproducable and identical environment for the development and the run-time across differentsystems Ansible is used as configuration management solution All needed steps of the installation are automated Theconfiguration doesnrsquot differentiate between local or remote installations This matters only for the deployment of theweb content
For local development itrsquos possible to use an LX container
$ sudo ansible-playbook develcontaineryml
To get everything running some additional steps (check the network inside the container generate keys etc) areneeded After you are done check it
$ sudo ansible webshop -m setup
From the management system
$ sudo ssh-copy-id -i rootsshid_rsapub root[IP address of your managed node]
The configuration of Ansible itself (adding the system to etcansiblehosts and copying the SSH keys) isnot documented at this place There are various resources available like here All playbooks are located in the folderdevel Start the setup with the command shown below
$ sudo ansible-playbook develsetupyml
The used group name in etcansiblehosts is webshop
If the setup completes without errors then the web server is accessible and show a default page Please keep in mindthat the server is only accessible over https unencrypted traffic is not allowed
1542 DeploymentSetup website
For the simple deployment of the lastest version of the shop a playbook called deployyml is provided Thisplaybook put all files in place
$ sudo ansible-playbook develdeployyml
To full deploy the webshop all tables in the database must exist The file webshopsql contains all needed SQLcommands and sample data for the web application
Itrsquos possible to deploy the website manually but this is not recommended A couple of files are depending on templateswhich are created during the deployment
Itrsquos also not recommanded to clone everything into your webserver root This would save you the trouble of doing itby hand but third-party features are missing then Those missing parts are the template engine the pdf generation theconnection to Openstreetmap and probably other things not mentioned here
155 Git respository
All project relevante informations (Source code templates documentation etc) is located in a public Git repositoryon Github
38 Kapitel 15 Development
Shop Documentation Release 001
156 Documentation
The documentation is using reStructuredText as markup language For a local build Sphinx is needed Sphinx isavailable in the Fedora Package Collection and can be installed with yum or any other package management tool
yum -y install python-sphinx python-docutils
The source files of the documentation are located under docs
$ cd docs$ make html
The output is stored under docs_buildhtml
After every push to Github a hook launch a rebuild of the documentation The latest release will be published on Readthe Docs automatically
httpsshoprtfdorg
156 Documentation 39
Shop Documentation Release 001
40 Kapitel 15 Development
KAPITEL 16
Indices and tables
bull genindex
bull modindex
bull search
41
- Basics
-
- Products
- Personas
- Use cases
- Design principles
-
- Web shop Design
-
- General
- Layout
- Sitemap
- Main page
-
- Style and design
-
- Cascading Style Sheets
- Pages
-
- Dynamics
-
- Setup
- Current year
- Navigation Menu
- List of Products
- Company details
-
- External files
-
- Navigation Menu
- Header
- Footer
-
- Input processing
-
- ``Buy Now links
- Select options
-
- Javascript
-
- Simple use case
-
- Cookies and Sessions
-
- Cookies
- Hit counter
- Language selection
- User Accounts
-
- Database
-
- Tables
- PHP
-
- Web service
-
- Map
- Weather
-
- Data export
-
- JSON
-
- Messaging
-
- MQTT
-
- Localisation (L10n)
- Templates
-
- Template
- Content
-
- Development
-
- Web server
- Database server
- Versions
- Setup infrastructure
- Git respository
- Documentation
-
- Indices and tables
-
Shop Documentation Release 001
Loaded in a browser the initial draft of the main page looks like in the following screenshot
10 Kapitel 2 Web shop Design
KAPITEL 3
Style and design
31 Cascading Style Sheets
The design of the shop will be nothing fancy The approach which was choosen will reflect the points mentioned inthe Design principles section and makes heavy use of the bootstrap framework cascading style sheet Various changesto this CSS file ensure that it matche the needs of this project
32 Pages
The product page show the elements mentioned in the Product overview section
11
Shop Documentation Release 001
12 Kapitel 3 Style and design
KAPITEL 4
Dynamics
The webshop will be a PHP application at the end Those first steps are only covering the very basic stuff of PHP asan introduction
41 Setup
The setupyml playbook puts a simple PHP file in the root directory of the web server with the namephpinfophp This file displays PHP details
Achtung Remove this file before makeing the shop accessible by a public audience
42 Current year
The first PHP element in the webshop is showing the current year in the footer of every page With the help of thislittle piece of code there is no longer a need to update the year
ltphp echo date(Y) gt
43 Navigation Menu
The basic menu was built with the following snippet
ltphp$menu = array(rsquoHomersquo =gt rsquoindexphprsquo
rsquoProduktersquo =gt rsquoproductsphprsquorsquoUumlber unsrsquo =gt rsquoaboutphprsquo
)foreach($menu as $label =gt $link)
echo rsquoltligtlta href=rsquo $link rsquogtrsquo $label rsquoltagtltligtrsquo
gt
The issue with that snippet was that the CSS class was missing In regards to a future separation and reusability anadditional statements was added This way the label of the active page is highlighted
13
Shop Documentation Release 001
ltphp$menu = array(rsquoHomersquo =gt rsquoindexphprsquo
rsquoProduktersquo =gt rsquoproductsphprsquorsquoUumlber unsrsquo =gt rsquoaboutphprsquo
)foreach ($menu as $label =gt $link)
$url = trim($_SERVER[rsquoPHP_SELFrsquo] rsquorsquo)if ($link == $url)
echo rsquoltli class=activegtlta href=rsquo $link rsquogtrsquo $label rsquoltagtltligtrsquo else
echo rsquoltli class=gtlta href=rsquo $link rsquogtrsquo $label rsquoltagtltligtrsquo
gt
44 List of Products
The product overiew is a simple table The heading of the table is placed in an array
ltdivgtlttable class=table table-stripedgtltthead valign=bottomgtlttrgtltphp
$heading = array(rsquoTypersquo rsquoVariantrsquo rsquoColorrsquo rsquoHardnessrsquo rsquoPrice CHFrsquo)foreach ($heading as $element)
echo rsquoltth class=headgtrsquo$elementrsquoltthgtrsquon
gtlttrgtlttheadgtlttbody valign=topgtltphp
$products = array(array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquoHBrsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquoBrsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquo2Brsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquoFrsquo rsquo12rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquoHrsquo rsquo12rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquo2Hrsquo rsquo12rsquo)
)foreach ($products as $product =gt $details)
echo lttrgtforeach ($details as $detail)
echo lttdgt$detaillttdgtecho lttrgt
gtlttbodygtlttablegt
ltdivgt
14 Kapitel 4 Dynamics
Shop Documentation Release 001
45 Company details
The data for the About page are included out of a static and plain text file
ltphp$str = file_get_contents(companytxt)echo $str
gt
45 Company details 15
Shop Documentation Release 001
16 Kapitel 4 Dynamics
KAPITEL 5
External files
51 Navigation Menu
The menu is outsourced in the file menuphp
ltphpfunction menu()
$part1 = rsquoltul class=nav nav-tabsgtrsquon$part2 = rsquorsquo$part3 = rsquoltulgtrsquon Menu array with page title and assigned file$menu = array(rsquoHomersquo =gt rsquoindexphprsquo
rsquoProduktersquo =gt rsquoproductsphprsquorsquoUumlber unsrsquo =gt rsquoaboutphprsquo
)foreach ($menu as $label =gt $link)
For the CSS only the file name without is needed$url = trim($_SERVER[rsquoPHP_SELFrsquo] rsquorsquo)if ($link == $url)
$part2 = $part2ltli class=rsquoactiversquogtlta href=rsquo$linkrsquogt$labelltagtltligtn else
$part2 = $part2ltli class=rsquorsquogtlta href=rsquo$linkrsquogt$labelltagtltligtn
return $part1$part2$part3
gt
52 Header
The complete header part is loaded from the file headerphp
ltphpfunction head()
$start_page = indexphp$part1 = ltdivgtn$part2 = tlta class=rsquobrand-logorsquo href=rsquo$start_pagersquogtltagtn$part3 = tltp class=rsquobrand-namersquogtWebshop Pencil AGltpgtn$part4 = ltdivgtnreturn $part1$part2$part3$part4
17
Shop Documentation Release 001
gt
53 Footer
The same is done witht the page footers
ltphpfunction foot()
$class1 = rsquoltdiv class=footergtrsquon$class2 = rsquoltdivgtrsquon$text = ltpgtampcopy Pencil AG getYear()rsquoltpgtrsquonreturn $class1$text$class2
function getYear()return date(Y)
gt
18 Kapitel 5 External files
KAPITEL 6
Input processing
61 ldquoBuy Nowrdquo links
The ldquoBuy Nowrdquo links are attached to the Products page Every entry has itrsquos own link which lead to a detail page Thelinks are using hidden form elements to transfer the data
ltphp$products = array(array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquoHBrsquo rsquo1rsquo)
array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquoBrsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquo2Brsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquoFrsquo rsquo12rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquoHrsquo rsquo12rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquo2Hrsquo rsquo12rsquo)
)foreach ($products as $product =gt $details)
echo lttrgtnforeach ($details as $detail)
echo lttdgt$detaillttdgtnecho lttdgtnecho ltform action=rsquoproductphprsquo method=rsquogetrsquo name=rsquopencilrsquogtnecho ltinput type=rsquohiddenrsquo name=rsquotypersquo value=rsquo$details[0]rsquogtnecho ltinput type=rsquohiddenrsquo name=rsquooptionsrsquo value=rsquo$details[1]rsquogtnecho ltinput type=rsquohiddenrsquo name=rsquocolorrsquo value=rsquo$details[2]rsquogtnecho ltinput type=rsquohiddenrsquo name=rsquohardnessrsquo value=rsquo$details[3]rsquogtnecho ltinput type=rsquohiddenrsquo name=rsquopricersquo value=rsquo$details[4]rsquogtnecho ltinput type=rsquosubmitrsquo class=rsquobtn btn-defaultrsquo value=rsquoKauf michrsquogtnecho ltformgtnecho lttdgtnecho lttrgtn
gt
And the detail page contains the code fragement mentioned below
ltphp$type=$_GET[rsquotypersquo]$color=$_GET[rsquocolorrsquo]$hardness=$_GET[rsquohardnessrsquo]$options=$_GET[rsquooptionsrsquo]$price=$_GET[rsquopricersquo]echo I am a $type in $color and a hardness of $hardness I have $options as an option and my price is $price CHF
gt
19
Shop Documentation Release 001
Bemerkung The Products page was modified in the process of the development
62 Select options
The signupbilling page contains a dropdown element that all days of a month for the entry of the userrsquos birthday
ltselect name=daygtltoptiongtDayltoptiongt
ltphp$days = range(31 1)foreach ($days as $day)
echo rsquoltoption value=rsquo$dayrsquogtrsquo$dayrsquoltoptiongtrsquo
gtltselectgt
20 Kapitel 6 Input processing
KAPITEL 7
Javascript
Over the years Javascript became a very popular programming language The webshop is using Javascript at a coupleof places
71 Simple use case
Javascript makes it easy to access elements in the DOM Setting the focus is a nice way to support the user with inputform
ltscript language=javascriptgtfunction setFocus()
documentforms[login][username]focus()
ltscriptgtltheadgtltbody onload=setFocus()gt
Another one is to check if something was entered in an input field
function validateForm() var username = documentforms[rdquologinrdquo][rdquousernamerdquo]value if (username== null || username == ldquordquo)
documentforms[rdquologinrdquo][rdquousernamerdquo]stylebackgroundColor = ldquoFF9999rdquo docu-mentforms[rdquologinrdquo][rdquousernamerdquo]placeholder = ldquoPlease your usernamerdquo docu-mentforms[rdquologinrdquo][rdquousernamerdquo]focus() return false
A simple message is informing the user about an action which was taken against the database
echo ltscript type=textjavascriptgtalert(New entry $entry added successfully)windowlocation = tablesphp
ltscriptgt
The delete process is only executed if the user confirm to delete a record
ltform action=scriptsdelete-processphp onSubmit=return confirm(rsquoAre you sure to delete this entryrsquo) method=POSTgtltinput type=hidden name=table value=$sectiongtltinput type=hidden name=id value=$result-gtidgtltinput type=submit name=Submit value=Deletegt
ltformgt
For additional Javascript please check the source of the indexphp file and the reflsquowebservicelsquo_ section
21
Shop Documentation Release 001
22 Kapitel 7 Javascript
KAPITEL 8
Cookies and Sessions
The built-in support for sessions in PHP is handling all cookie manipulation to provide persistent variables that areaccessible from different pages and across multiple visits to the site
81 Cookies
A cookie is used to track the last time a visitor check the front page The cookie is set when a visitor arrives
function lastVisit($name $expire) $value = getDateDMY() - getTimeHM()setcookie($name $value time() + $expire rsquorsquo $_SERVER[rsquoSERVER_NAMErsquo] true true)
In the footer of the index page the details are presented
ltphpif(isset($_COOKIE[rsquoLastVisitrsquo]))
$last = $_COOKIE[rsquoLastVisitrsquo]echo You last visited us on $last
else echo This is your first visit
gt
82 Hit counter
As a simple show case for PHP sessions a hit counter for the front page is available
ltphpsession_start()
$_SESSION[rsquohitsrsquo] = $_SESSION[rsquohitsrsquo] + 1gt
Included in the footer it shous the users the total of visits
echo Total $_SESSION[rsquohitsrsquo] visits of this page
23
Shop Documentation Release 001
83 Language selection
84 User Accounts
24 Kapitel 8 Cookies and Sessions
KAPITEL 9
Database
The database backend for the webshop will be MariaDB which is the drop-in replacement for MySQL
For the setup please check the Development section in this documentation
91 Tables
The following tables are needed for the webshop to work
bull products
bull customers
bull pencils
bull colors
bull hardness
bull options
bull users
Please use the develwebshopsql to setup the database
92 PHP
Below you find the configuration file for a default installation of the webshop This file is a template and filled duringthe setup process
ltphp$host = localhost$user = root$password = webshop$dbase = webshop$connection = new mysqli($host $user $password $dbase)
if ($connection-gtconnect_errno) echo Failed to connect to MariaDBMySQL ($connection-gtconnect_errno) $connection-gtconnect_error
mysqli_report(MYSQLI_REPORT_ERROR)
gt
25
Shop Documentation Release 001
All connections to the database are done in the same way Below you find an example Everything is done in theobject-oriented style
ltphprequire_once(rsquoconfigdbconnectphprsquo)if ($connection-gtconnect_errno == 0)
$sql = SELECT FROM products$results = $connection-gtquery($sql)echo $results-gtnum_rows$results-gtclose()
else echo Database connection error
gt
26 Kapitel 9 Database
KAPITEL 10
Web service
Tow web services are integrated to take advantages of online available data sources
101 Map
Leafletjs a JavaScript library for working with interactive maps from OpenStreetMap (OSM) is implemented as ashow case for a simple web service
The basic steps to integrate a map is shown below
ltdiv id=map class=map style=width 600px height 400pxgtltdivgt
ltscript src=scriptsleafletjsgtltscriptgtltscript src=scriptsleaflet-providersjsgtltscriptgtltscriptgtvar map = Lmap(rsquomaprsquo
center [250472 -773255]zoom 12zoomControl true
)
var defaultLayer = LtileLayerprovider(rsquoOpenStreetMapMapnikrsquo)addTo(map)ltscriptgt
102 Weather
The OpenWeatherMap service provides free weather data and a forecast API for web applications
ltphp Details about the API httpbugsopenweathermaporgprojectsapiwikiApi_2_5_weather$url = rsquohttpapiopenweathermaporgdata25weatherq=Bernechampunit=metricsampmode=jsonrsquo
$json = file_get_contents($url)$data = json_decode($json)
$tempC = round((27315 - $data-gtmain-gttemp)100) 100$humidity = $data-gtmain-gthumidity$pressure = $data-gtmain-gtpressure
27
Shop Documentation Release 001
echo ltpgtTemperatur $tempC degCltbrgtnecho Luftfeuchtigkeit $humidity ltbrgtnecho Luftdruck $pressure Paltpgtn
gt
28 Kapitel 10 Web service
KAPITEL 11
Data export
111 PDF
FPDF is a PHP class that allows to generate PDF files with pure PHP As a showcase for that the product specificationsfor a given product are filled in a pdf and showed in the browser The user can then decide to download or print thefile
112 JSON
JavaScript Object Notation (JSON) is a lightweight data-interchange format The format is language independent andPHP support the encoding and the decoding JSON with json_encode($data) and json_decode($data)$rows = array()$sql = SELECT FROM products$results = $connection-gtquery($sql)while ($result = $results-gtfetch_object())
$rows[] = $result$results-gtclose()
Writing all rows to a JSON file$fp = fopen(rsquopencilsjsonrsquo rsquowrsquo)fwrite($fp json_encode($rows))fclose($fp)gt
and for reading it
ltphp$json = file_get_contents(rsquopencilsjsonrsquo)print_r(json_decode($json))
gt
29
Shop Documentation Release 001
30 Kapitel 11 Data export
KAPITEL 12
Messaging
Beside standard email messages the webshop supports sending MQ Telemetry Transport protocol (MQTT) messagesas an additional feature The MQTT messages are small
121 MQTT
Mosquitto-PHP is used as a PHP wrapper for MQTT Please check the Projectrsquos README for details about theinstallation and the setup
1211 Broker
Mosquitto is a message broker that implements the MQ Telemetry Transport protocol Check if mosquitto is run-ning
$ sudo systemctl status mosquittoservice
If not start it
$ systemctl start mosquittoservice
All messages are published to the topic webshop
1212 Publishing
After the installation of Mosquitto-PHP the snipplet shown below sends a single message
ltphpdefine(rsquoBROKERrsquo rsquolocalhostrsquo)define(rsquoPORTrsquo 1883)define(rsquoCLIENT_IDrsquo webshop_ + getmypid())$topic = webshop$subtopic = test$completeTopic = $topic$subtopic
$client = new MosquittoClient(CLIENT_ID)$client-gtconnect(BROKER PORT 60)
$message = Test message from webshop at date(Y-m-d His)$client-gtpublish($completeTopic $message 0 false)
gt
31
Shop Documentation Release 001
1213 Subscribing
To read the messages sent by the webshop a client is needed The Mosquitto broker contain a simple command-linetool for subscribing to various topics
$ mosquitto_sub -h localhost -t webshop
122 Email
This section doesnrsquot describe the installation and configuration of a local MTA There are enough resources thatcontains information about the setup of postfix for local delivery only
If you want to test the email feature add the following code in one of PHP pages
ltphp mail(rsquorootlocalhostrsquo rsquoTest message from webshoprsquo rsquoThe webshop is selling pencilsrsquo) gt
By default SELinux is running in Enforcing mode which is restrictive about about what a web server can do Toallow sending email the following SELinux boolean needs to changed
setsebool -P httpd_can_network_connect=1 setsebool -P httpd_can_sendmail=1
32 Kapitel 12 Messaging
KAPITEL 13
Localisation (L10n)
There are several ways to add localisation to a web site For small projects arrays with string can work but this is notvery efficient and user-friendly With Gettext is a toolset available that provide a framework to produce multi-lingualcontent in a wide area of programming languages
Make sure that the php-gettext package is available on your system If not install it
$ sudo yum -y install php-php-gettext
Check if gettext support is available
ltphpif (function_exists(gettext))
echo gettext is not installednelse
echo gettext is supportedn
gt
Make sure that all locales your want are available on the server
locale -a
The first step is to mark all string which should be translatable as shown below For further details please refer to theGettext documentation
echo _(rsquoSome textrsquo)
The next step is to extract all strings
xgettext --from-code=UTF-8 -o localewebshoppot php scriptsphp
To re-generate the file after an update join the strings
xgettext -j --from-code=UTF-8 -o localewebshoppot php scriptsphp
For every language a po file is needed for the transations Generate it with the command mentioned below
msginit --no-translator -l de_CH -o localede_CHpo -i localewebshoppot
Once created there are only updates of the message catalog needed in the futures
msgmerge -U localede_CHpo localewebshoppot
If you re finish create the mo file for the specific language
33
Shop Documentation Release 001
msgfmt -c -v -o localede_CHLC_MESSAGESwebshopmo localede_CHpo
34 Kapitel 13 Localisation (L10n)
KAPITEL 14
Templates
Beside other solutions Savant3 is a lightweight object-oriented template system for PHP This solution does not needa lot of additional configuration
141 Template
A simple template file looks like the one shown below
lthtmlgtltheadgt
lttitlegtltphp echo $this-gteprint($this-gttitle) gtlttitlegtltheadgtltbodygt
ltphp echo $this-gteprint($this-gtcontent) gtltbodygt
lthtmlgt
For a more detailed intro check this article on Zend Developer Zone
142 Content
To fill the template with data all wished variables needs to be defined in a seperate PHP file
ltphprequire_once rsquoscriptsSavant3phprsquo$tpl = new Savant3()
Create a title$title = Simple sample page
Create the content of the page$content = Some sample text to show
Assign values to the Savant instance$tpl-gttitle = $title$tpl-gtcontent = $content
Define the template source file to show$tpl-gtdisplay(rsquosimpletplphprsquo)
gt
35
Shop Documentation Release 001
The webshop contains a page (master)
36 Kapitel 14 Templates
KAPITEL 15
Development
This sections describes the configuration of the development and runtime environment for the web shop
151 Web server
Instead of Apache the project is running on Lighttpd The reasons are that Lighttpd provides faster setup easierconfiguration and better performance Lighttpd is running with FastCGI
The path of the web server is varwwwlighttpd and the SELinux configuration are still the defaults
The web server is running in SSL-only mode and the certificate is generated during the server setup process
152 Database server
For persistence storage the drop-in replacement MariaDB is used MySQL will work to but this is not tested phpMyAd-min is available under phpmyadmin on the web server beside the command-line tools for easy administration
The default credentials for phpMyAdmin are rootwebshop or the entry you made in the Ansible playbookdevelvariablessensitiveyml
153 Versions
The web shop is built with the below listed components and tested Other releases can be used and may work but thiswill not be tested Probably it will work with different releases
bull Operating system Fedora 20
bull Kernel 3135-202fc20x86_64
bull Lighttpd 1434
bull PHP 557
bull MariaDB 5534
For communication postfix and mosquitto are needed additionally
37
Shop Documentation Release 001
154 Setup infrastructure
1541 Configuration management
For the creation of reproducable and identical environment for the development and the run-time across differentsystems Ansible is used as configuration management solution All needed steps of the installation are automated Theconfiguration doesnrsquot differentiate between local or remote installations This matters only for the deployment of theweb content
For local development itrsquos possible to use an LX container
$ sudo ansible-playbook develcontaineryml
To get everything running some additional steps (check the network inside the container generate keys etc) areneeded After you are done check it
$ sudo ansible webshop -m setup
From the management system
$ sudo ssh-copy-id -i rootsshid_rsapub root[IP address of your managed node]
The configuration of Ansible itself (adding the system to etcansiblehosts and copying the SSH keys) isnot documented at this place There are various resources available like here All playbooks are located in the folderdevel Start the setup with the command shown below
$ sudo ansible-playbook develsetupyml
The used group name in etcansiblehosts is webshop
If the setup completes without errors then the web server is accessible and show a default page Please keep in mindthat the server is only accessible over https unencrypted traffic is not allowed
1542 DeploymentSetup website
For the simple deployment of the lastest version of the shop a playbook called deployyml is provided Thisplaybook put all files in place
$ sudo ansible-playbook develdeployyml
To full deploy the webshop all tables in the database must exist The file webshopsql contains all needed SQLcommands and sample data for the web application
Itrsquos possible to deploy the website manually but this is not recommended A couple of files are depending on templateswhich are created during the deployment
Itrsquos also not recommanded to clone everything into your webserver root This would save you the trouble of doing itby hand but third-party features are missing then Those missing parts are the template engine the pdf generation theconnection to Openstreetmap and probably other things not mentioned here
155 Git respository
All project relevante informations (Source code templates documentation etc) is located in a public Git repositoryon Github
38 Kapitel 15 Development
Shop Documentation Release 001
156 Documentation
The documentation is using reStructuredText as markup language For a local build Sphinx is needed Sphinx isavailable in the Fedora Package Collection and can be installed with yum or any other package management tool
yum -y install python-sphinx python-docutils
The source files of the documentation are located under docs
$ cd docs$ make html
The output is stored under docs_buildhtml
After every push to Github a hook launch a rebuild of the documentation The latest release will be published on Readthe Docs automatically
httpsshoprtfdorg
156 Documentation 39
Shop Documentation Release 001
40 Kapitel 15 Development
KAPITEL 16
Indices and tables
bull genindex
bull modindex
bull search
41
- Basics
-
- Products
- Personas
- Use cases
- Design principles
-
- Web shop Design
-
- General
- Layout
- Sitemap
- Main page
-
- Style and design
-
- Cascading Style Sheets
- Pages
-
- Dynamics
-
- Setup
- Current year
- Navigation Menu
- List of Products
- Company details
-
- External files
-
- Navigation Menu
- Header
- Footer
-
- Input processing
-
- ``Buy Now links
- Select options
-
- Javascript
-
- Simple use case
-
- Cookies and Sessions
-
- Cookies
- Hit counter
- Language selection
- User Accounts
-
- Database
-
- Tables
- PHP
-
- Web service
-
- Map
- Weather
-
- Data export
-
- JSON
-
- Messaging
-
- MQTT
-
- Localisation (L10n)
- Templates
-
- Template
- Content
-
- Development
-
- Web server
- Database server
- Versions
- Setup infrastructure
- Git respository
- Documentation
-
- Indices and tables
-
KAPITEL 3
Style and design
31 Cascading Style Sheets
The design of the shop will be nothing fancy The approach which was choosen will reflect the points mentioned inthe Design principles section and makes heavy use of the bootstrap framework cascading style sheet Various changesto this CSS file ensure that it matche the needs of this project
32 Pages
The product page show the elements mentioned in the Product overview section
11
Shop Documentation Release 001
12 Kapitel 3 Style and design
KAPITEL 4
Dynamics
The webshop will be a PHP application at the end Those first steps are only covering the very basic stuff of PHP asan introduction
41 Setup
The setupyml playbook puts a simple PHP file in the root directory of the web server with the namephpinfophp This file displays PHP details
Achtung Remove this file before makeing the shop accessible by a public audience
42 Current year
The first PHP element in the webshop is showing the current year in the footer of every page With the help of thislittle piece of code there is no longer a need to update the year
ltphp echo date(Y) gt
43 Navigation Menu
The basic menu was built with the following snippet
ltphp$menu = array(rsquoHomersquo =gt rsquoindexphprsquo
rsquoProduktersquo =gt rsquoproductsphprsquorsquoUumlber unsrsquo =gt rsquoaboutphprsquo
)foreach($menu as $label =gt $link)
echo rsquoltligtlta href=rsquo $link rsquogtrsquo $label rsquoltagtltligtrsquo
gt
The issue with that snippet was that the CSS class was missing In regards to a future separation and reusability anadditional statements was added This way the label of the active page is highlighted
13
Shop Documentation Release 001
ltphp$menu = array(rsquoHomersquo =gt rsquoindexphprsquo
rsquoProduktersquo =gt rsquoproductsphprsquorsquoUumlber unsrsquo =gt rsquoaboutphprsquo
)foreach ($menu as $label =gt $link)
$url = trim($_SERVER[rsquoPHP_SELFrsquo] rsquorsquo)if ($link == $url)
echo rsquoltli class=activegtlta href=rsquo $link rsquogtrsquo $label rsquoltagtltligtrsquo else
echo rsquoltli class=gtlta href=rsquo $link rsquogtrsquo $label rsquoltagtltligtrsquo
gt
44 List of Products
The product overiew is a simple table The heading of the table is placed in an array
ltdivgtlttable class=table table-stripedgtltthead valign=bottomgtlttrgtltphp
$heading = array(rsquoTypersquo rsquoVariantrsquo rsquoColorrsquo rsquoHardnessrsquo rsquoPrice CHFrsquo)foreach ($heading as $element)
echo rsquoltth class=headgtrsquo$elementrsquoltthgtrsquon
gtlttrgtlttheadgtlttbody valign=topgtltphp
$products = array(array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquoHBrsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquoBrsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquo2Brsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquoFrsquo rsquo12rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquoHrsquo rsquo12rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquo2Hrsquo rsquo12rsquo)
)foreach ($products as $product =gt $details)
echo lttrgtforeach ($details as $detail)
echo lttdgt$detaillttdgtecho lttrgt
gtlttbodygtlttablegt
ltdivgt
14 Kapitel 4 Dynamics
Shop Documentation Release 001
45 Company details
The data for the About page are included out of a static and plain text file
ltphp$str = file_get_contents(companytxt)echo $str
gt
45 Company details 15
Shop Documentation Release 001
16 Kapitel 4 Dynamics
KAPITEL 5
External files
51 Navigation Menu
The menu is outsourced in the file menuphp
ltphpfunction menu()
$part1 = rsquoltul class=nav nav-tabsgtrsquon$part2 = rsquorsquo$part3 = rsquoltulgtrsquon Menu array with page title and assigned file$menu = array(rsquoHomersquo =gt rsquoindexphprsquo
rsquoProduktersquo =gt rsquoproductsphprsquorsquoUumlber unsrsquo =gt rsquoaboutphprsquo
)foreach ($menu as $label =gt $link)
For the CSS only the file name without is needed$url = trim($_SERVER[rsquoPHP_SELFrsquo] rsquorsquo)if ($link == $url)
$part2 = $part2ltli class=rsquoactiversquogtlta href=rsquo$linkrsquogt$labelltagtltligtn else
$part2 = $part2ltli class=rsquorsquogtlta href=rsquo$linkrsquogt$labelltagtltligtn
return $part1$part2$part3
gt
52 Header
The complete header part is loaded from the file headerphp
ltphpfunction head()
$start_page = indexphp$part1 = ltdivgtn$part2 = tlta class=rsquobrand-logorsquo href=rsquo$start_pagersquogtltagtn$part3 = tltp class=rsquobrand-namersquogtWebshop Pencil AGltpgtn$part4 = ltdivgtnreturn $part1$part2$part3$part4
17
Shop Documentation Release 001
gt
53 Footer
The same is done witht the page footers
ltphpfunction foot()
$class1 = rsquoltdiv class=footergtrsquon$class2 = rsquoltdivgtrsquon$text = ltpgtampcopy Pencil AG getYear()rsquoltpgtrsquonreturn $class1$text$class2
function getYear()return date(Y)
gt
18 Kapitel 5 External files
KAPITEL 6
Input processing
61 ldquoBuy Nowrdquo links
The ldquoBuy Nowrdquo links are attached to the Products page Every entry has itrsquos own link which lead to a detail page Thelinks are using hidden form elements to transfer the data
ltphp$products = array(array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquoHBrsquo rsquo1rsquo)
array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquoBrsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquo2Brsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquoFrsquo rsquo12rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquoHrsquo rsquo12rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquo2Hrsquo rsquo12rsquo)
)foreach ($products as $product =gt $details)
echo lttrgtnforeach ($details as $detail)
echo lttdgt$detaillttdgtnecho lttdgtnecho ltform action=rsquoproductphprsquo method=rsquogetrsquo name=rsquopencilrsquogtnecho ltinput type=rsquohiddenrsquo name=rsquotypersquo value=rsquo$details[0]rsquogtnecho ltinput type=rsquohiddenrsquo name=rsquooptionsrsquo value=rsquo$details[1]rsquogtnecho ltinput type=rsquohiddenrsquo name=rsquocolorrsquo value=rsquo$details[2]rsquogtnecho ltinput type=rsquohiddenrsquo name=rsquohardnessrsquo value=rsquo$details[3]rsquogtnecho ltinput type=rsquohiddenrsquo name=rsquopricersquo value=rsquo$details[4]rsquogtnecho ltinput type=rsquosubmitrsquo class=rsquobtn btn-defaultrsquo value=rsquoKauf michrsquogtnecho ltformgtnecho lttdgtnecho lttrgtn
gt
And the detail page contains the code fragement mentioned below
ltphp$type=$_GET[rsquotypersquo]$color=$_GET[rsquocolorrsquo]$hardness=$_GET[rsquohardnessrsquo]$options=$_GET[rsquooptionsrsquo]$price=$_GET[rsquopricersquo]echo I am a $type in $color and a hardness of $hardness I have $options as an option and my price is $price CHF
gt
19
Shop Documentation Release 001
Bemerkung The Products page was modified in the process of the development
62 Select options
The signupbilling page contains a dropdown element that all days of a month for the entry of the userrsquos birthday
ltselect name=daygtltoptiongtDayltoptiongt
ltphp$days = range(31 1)foreach ($days as $day)
echo rsquoltoption value=rsquo$dayrsquogtrsquo$dayrsquoltoptiongtrsquo
gtltselectgt
20 Kapitel 6 Input processing
KAPITEL 7
Javascript
Over the years Javascript became a very popular programming language The webshop is using Javascript at a coupleof places
71 Simple use case
Javascript makes it easy to access elements in the DOM Setting the focus is a nice way to support the user with inputform
ltscript language=javascriptgtfunction setFocus()
documentforms[login][username]focus()
ltscriptgtltheadgtltbody onload=setFocus()gt
Another one is to check if something was entered in an input field
function validateForm() var username = documentforms[rdquologinrdquo][rdquousernamerdquo]value if (username== null || username == ldquordquo)
documentforms[rdquologinrdquo][rdquousernamerdquo]stylebackgroundColor = ldquoFF9999rdquo docu-mentforms[rdquologinrdquo][rdquousernamerdquo]placeholder = ldquoPlease your usernamerdquo docu-mentforms[rdquologinrdquo][rdquousernamerdquo]focus() return false
A simple message is informing the user about an action which was taken against the database
echo ltscript type=textjavascriptgtalert(New entry $entry added successfully)windowlocation = tablesphp
ltscriptgt
The delete process is only executed if the user confirm to delete a record
ltform action=scriptsdelete-processphp onSubmit=return confirm(rsquoAre you sure to delete this entryrsquo) method=POSTgtltinput type=hidden name=table value=$sectiongtltinput type=hidden name=id value=$result-gtidgtltinput type=submit name=Submit value=Deletegt
ltformgt
For additional Javascript please check the source of the indexphp file and the reflsquowebservicelsquo_ section
21
Shop Documentation Release 001
22 Kapitel 7 Javascript
KAPITEL 8
Cookies and Sessions
The built-in support for sessions in PHP is handling all cookie manipulation to provide persistent variables that areaccessible from different pages and across multiple visits to the site
81 Cookies
A cookie is used to track the last time a visitor check the front page The cookie is set when a visitor arrives
function lastVisit($name $expire) $value = getDateDMY() - getTimeHM()setcookie($name $value time() + $expire rsquorsquo $_SERVER[rsquoSERVER_NAMErsquo] true true)
In the footer of the index page the details are presented
ltphpif(isset($_COOKIE[rsquoLastVisitrsquo]))
$last = $_COOKIE[rsquoLastVisitrsquo]echo You last visited us on $last
else echo This is your first visit
gt
82 Hit counter
As a simple show case for PHP sessions a hit counter for the front page is available
ltphpsession_start()
$_SESSION[rsquohitsrsquo] = $_SESSION[rsquohitsrsquo] + 1gt
Included in the footer it shous the users the total of visits
echo Total $_SESSION[rsquohitsrsquo] visits of this page
23
Shop Documentation Release 001
83 Language selection
84 User Accounts
24 Kapitel 8 Cookies and Sessions
KAPITEL 9
Database
The database backend for the webshop will be MariaDB which is the drop-in replacement for MySQL
For the setup please check the Development section in this documentation
91 Tables
The following tables are needed for the webshop to work
bull products
bull customers
bull pencils
bull colors
bull hardness
bull options
bull users
Please use the develwebshopsql to setup the database
92 PHP
Below you find the configuration file for a default installation of the webshop This file is a template and filled duringthe setup process
ltphp$host = localhost$user = root$password = webshop$dbase = webshop$connection = new mysqli($host $user $password $dbase)
if ($connection-gtconnect_errno) echo Failed to connect to MariaDBMySQL ($connection-gtconnect_errno) $connection-gtconnect_error
mysqli_report(MYSQLI_REPORT_ERROR)
gt
25
Shop Documentation Release 001
All connections to the database are done in the same way Below you find an example Everything is done in theobject-oriented style
ltphprequire_once(rsquoconfigdbconnectphprsquo)if ($connection-gtconnect_errno == 0)
$sql = SELECT FROM products$results = $connection-gtquery($sql)echo $results-gtnum_rows$results-gtclose()
else echo Database connection error
gt
26 Kapitel 9 Database
KAPITEL 10
Web service
Tow web services are integrated to take advantages of online available data sources
101 Map
Leafletjs a JavaScript library for working with interactive maps from OpenStreetMap (OSM) is implemented as ashow case for a simple web service
The basic steps to integrate a map is shown below
ltdiv id=map class=map style=width 600px height 400pxgtltdivgt
ltscript src=scriptsleafletjsgtltscriptgtltscript src=scriptsleaflet-providersjsgtltscriptgtltscriptgtvar map = Lmap(rsquomaprsquo
center [250472 -773255]zoom 12zoomControl true
)
var defaultLayer = LtileLayerprovider(rsquoOpenStreetMapMapnikrsquo)addTo(map)ltscriptgt
102 Weather
The OpenWeatherMap service provides free weather data and a forecast API for web applications
ltphp Details about the API httpbugsopenweathermaporgprojectsapiwikiApi_2_5_weather$url = rsquohttpapiopenweathermaporgdata25weatherq=Bernechampunit=metricsampmode=jsonrsquo
$json = file_get_contents($url)$data = json_decode($json)
$tempC = round((27315 - $data-gtmain-gttemp)100) 100$humidity = $data-gtmain-gthumidity$pressure = $data-gtmain-gtpressure
27
Shop Documentation Release 001
echo ltpgtTemperatur $tempC degCltbrgtnecho Luftfeuchtigkeit $humidity ltbrgtnecho Luftdruck $pressure Paltpgtn
gt
28 Kapitel 10 Web service
KAPITEL 11
Data export
111 PDF
FPDF is a PHP class that allows to generate PDF files with pure PHP As a showcase for that the product specificationsfor a given product are filled in a pdf and showed in the browser The user can then decide to download or print thefile
112 JSON
JavaScript Object Notation (JSON) is a lightweight data-interchange format The format is language independent andPHP support the encoding and the decoding JSON with json_encode($data) and json_decode($data)$rows = array()$sql = SELECT FROM products$results = $connection-gtquery($sql)while ($result = $results-gtfetch_object())
$rows[] = $result$results-gtclose()
Writing all rows to a JSON file$fp = fopen(rsquopencilsjsonrsquo rsquowrsquo)fwrite($fp json_encode($rows))fclose($fp)gt
and for reading it
ltphp$json = file_get_contents(rsquopencilsjsonrsquo)print_r(json_decode($json))
gt
29
Shop Documentation Release 001
30 Kapitel 11 Data export
KAPITEL 12
Messaging
Beside standard email messages the webshop supports sending MQ Telemetry Transport protocol (MQTT) messagesas an additional feature The MQTT messages are small
121 MQTT
Mosquitto-PHP is used as a PHP wrapper for MQTT Please check the Projectrsquos README for details about theinstallation and the setup
1211 Broker
Mosquitto is a message broker that implements the MQ Telemetry Transport protocol Check if mosquitto is run-ning
$ sudo systemctl status mosquittoservice
If not start it
$ systemctl start mosquittoservice
All messages are published to the topic webshop
1212 Publishing
After the installation of Mosquitto-PHP the snipplet shown below sends a single message
ltphpdefine(rsquoBROKERrsquo rsquolocalhostrsquo)define(rsquoPORTrsquo 1883)define(rsquoCLIENT_IDrsquo webshop_ + getmypid())$topic = webshop$subtopic = test$completeTopic = $topic$subtopic
$client = new MosquittoClient(CLIENT_ID)$client-gtconnect(BROKER PORT 60)
$message = Test message from webshop at date(Y-m-d His)$client-gtpublish($completeTopic $message 0 false)
gt
31
Shop Documentation Release 001
1213 Subscribing
To read the messages sent by the webshop a client is needed The Mosquitto broker contain a simple command-linetool for subscribing to various topics
$ mosquitto_sub -h localhost -t webshop
122 Email
This section doesnrsquot describe the installation and configuration of a local MTA There are enough resources thatcontains information about the setup of postfix for local delivery only
If you want to test the email feature add the following code in one of PHP pages
ltphp mail(rsquorootlocalhostrsquo rsquoTest message from webshoprsquo rsquoThe webshop is selling pencilsrsquo) gt
By default SELinux is running in Enforcing mode which is restrictive about about what a web server can do Toallow sending email the following SELinux boolean needs to changed
setsebool -P httpd_can_network_connect=1 setsebool -P httpd_can_sendmail=1
32 Kapitel 12 Messaging
KAPITEL 13
Localisation (L10n)
There are several ways to add localisation to a web site For small projects arrays with string can work but this is notvery efficient and user-friendly With Gettext is a toolset available that provide a framework to produce multi-lingualcontent in a wide area of programming languages
Make sure that the php-gettext package is available on your system If not install it
$ sudo yum -y install php-php-gettext
Check if gettext support is available
ltphpif (function_exists(gettext))
echo gettext is not installednelse
echo gettext is supportedn
gt
Make sure that all locales your want are available on the server
locale -a
The first step is to mark all string which should be translatable as shown below For further details please refer to theGettext documentation
echo _(rsquoSome textrsquo)
The next step is to extract all strings
xgettext --from-code=UTF-8 -o localewebshoppot php scriptsphp
To re-generate the file after an update join the strings
xgettext -j --from-code=UTF-8 -o localewebshoppot php scriptsphp
For every language a po file is needed for the transations Generate it with the command mentioned below
msginit --no-translator -l de_CH -o localede_CHpo -i localewebshoppot
Once created there are only updates of the message catalog needed in the futures
msgmerge -U localede_CHpo localewebshoppot
If you re finish create the mo file for the specific language
33
Shop Documentation Release 001
msgfmt -c -v -o localede_CHLC_MESSAGESwebshopmo localede_CHpo
34 Kapitel 13 Localisation (L10n)
KAPITEL 14
Templates
Beside other solutions Savant3 is a lightweight object-oriented template system for PHP This solution does not needa lot of additional configuration
141 Template
A simple template file looks like the one shown below
lthtmlgtltheadgt
lttitlegtltphp echo $this-gteprint($this-gttitle) gtlttitlegtltheadgtltbodygt
ltphp echo $this-gteprint($this-gtcontent) gtltbodygt
lthtmlgt
For a more detailed intro check this article on Zend Developer Zone
142 Content
To fill the template with data all wished variables needs to be defined in a seperate PHP file
ltphprequire_once rsquoscriptsSavant3phprsquo$tpl = new Savant3()
Create a title$title = Simple sample page
Create the content of the page$content = Some sample text to show
Assign values to the Savant instance$tpl-gttitle = $title$tpl-gtcontent = $content
Define the template source file to show$tpl-gtdisplay(rsquosimpletplphprsquo)
gt
35
Shop Documentation Release 001
The webshop contains a page (master)
36 Kapitel 14 Templates
KAPITEL 15
Development
This sections describes the configuration of the development and runtime environment for the web shop
151 Web server
Instead of Apache the project is running on Lighttpd The reasons are that Lighttpd provides faster setup easierconfiguration and better performance Lighttpd is running with FastCGI
The path of the web server is varwwwlighttpd and the SELinux configuration are still the defaults
The web server is running in SSL-only mode and the certificate is generated during the server setup process
152 Database server
For persistence storage the drop-in replacement MariaDB is used MySQL will work to but this is not tested phpMyAd-min is available under phpmyadmin on the web server beside the command-line tools for easy administration
The default credentials for phpMyAdmin are rootwebshop or the entry you made in the Ansible playbookdevelvariablessensitiveyml
153 Versions
The web shop is built with the below listed components and tested Other releases can be used and may work but thiswill not be tested Probably it will work with different releases
bull Operating system Fedora 20
bull Kernel 3135-202fc20x86_64
bull Lighttpd 1434
bull PHP 557
bull MariaDB 5534
For communication postfix and mosquitto are needed additionally
37
Shop Documentation Release 001
154 Setup infrastructure
1541 Configuration management
For the creation of reproducable and identical environment for the development and the run-time across differentsystems Ansible is used as configuration management solution All needed steps of the installation are automated Theconfiguration doesnrsquot differentiate between local or remote installations This matters only for the deployment of theweb content
For local development itrsquos possible to use an LX container
$ sudo ansible-playbook develcontaineryml
To get everything running some additional steps (check the network inside the container generate keys etc) areneeded After you are done check it
$ sudo ansible webshop -m setup
From the management system
$ sudo ssh-copy-id -i rootsshid_rsapub root[IP address of your managed node]
The configuration of Ansible itself (adding the system to etcansiblehosts and copying the SSH keys) isnot documented at this place There are various resources available like here All playbooks are located in the folderdevel Start the setup with the command shown below
$ sudo ansible-playbook develsetupyml
The used group name in etcansiblehosts is webshop
If the setup completes without errors then the web server is accessible and show a default page Please keep in mindthat the server is only accessible over https unencrypted traffic is not allowed
1542 DeploymentSetup website
For the simple deployment of the lastest version of the shop a playbook called deployyml is provided Thisplaybook put all files in place
$ sudo ansible-playbook develdeployyml
To full deploy the webshop all tables in the database must exist The file webshopsql contains all needed SQLcommands and sample data for the web application
Itrsquos possible to deploy the website manually but this is not recommended A couple of files are depending on templateswhich are created during the deployment
Itrsquos also not recommanded to clone everything into your webserver root This would save you the trouble of doing itby hand but third-party features are missing then Those missing parts are the template engine the pdf generation theconnection to Openstreetmap and probably other things not mentioned here
155 Git respository
All project relevante informations (Source code templates documentation etc) is located in a public Git repositoryon Github
38 Kapitel 15 Development
Shop Documentation Release 001
156 Documentation
The documentation is using reStructuredText as markup language For a local build Sphinx is needed Sphinx isavailable in the Fedora Package Collection and can be installed with yum or any other package management tool
yum -y install python-sphinx python-docutils
The source files of the documentation are located under docs
$ cd docs$ make html
The output is stored under docs_buildhtml
After every push to Github a hook launch a rebuild of the documentation The latest release will be published on Readthe Docs automatically
httpsshoprtfdorg
156 Documentation 39
Shop Documentation Release 001
40 Kapitel 15 Development
KAPITEL 16
Indices and tables
bull genindex
bull modindex
bull search
41
- Basics
-
- Products
- Personas
- Use cases
- Design principles
-
- Web shop Design
-
- General
- Layout
- Sitemap
- Main page
-
- Style and design
-
- Cascading Style Sheets
- Pages
-
- Dynamics
-
- Setup
- Current year
- Navigation Menu
- List of Products
- Company details
-
- External files
-
- Navigation Menu
- Header
- Footer
-
- Input processing
-
- ``Buy Now links
- Select options
-
- Javascript
-
- Simple use case
-
- Cookies and Sessions
-
- Cookies
- Hit counter
- Language selection
- User Accounts
-
- Database
-
- Tables
- PHP
-
- Web service
-
- Map
- Weather
-
- Data export
-
- JSON
-
- Messaging
-
- MQTT
-
- Localisation (L10n)
- Templates
-
- Template
- Content
-
- Development
-
- Web server
- Database server
- Versions
- Setup infrastructure
- Git respository
- Documentation
-
- Indices and tables
-
Shop Documentation Release 001
12 Kapitel 3 Style and design
KAPITEL 4
Dynamics
The webshop will be a PHP application at the end Those first steps are only covering the very basic stuff of PHP asan introduction
41 Setup
The setupyml playbook puts a simple PHP file in the root directory of the web server with the namephpinfophp This file displays PHP details
Achtung Remove this file before makeing the shop accessible by a public audience
42 Current year
The first PHP element in the webshop is showing the current year in the footer of every page With the help of thislittle piece of code there is no longer a need to update the year
ltphp echo date(Y) gt
43 Navigation Menu
The basic menu was built with the following snippet
ltphp$menu = array(rsquoHomersquo =gt rsquoindexphprsquo
rsquoProduktersquo =gt rsquoproductsphprsquorsquoUumlber unsrsquo =gt rsquoaboutphprsquo
)foreach($menu as $label =gt $link)
echo rsquoltligtlta href=rsquo $link rsquogtrsquo $label rsquoltagtltligtrsquo
gt
The issue with that snippet was that the CSS class was missing In regards to a future separation and reusability anadditional statements was added This way the label of the active page is highlighted
13
Shop Documentation Release 001
ltphp$menu = array(rsquoHomersquo =gt rsquoindexphprsquo
rsquoProduktersquo =gt rsquoproductsphprsquorsquoUumlber unsrsquo =gt rsquoaboutphprsquo
)foreach ($menu as $label =gt $link)
$url = trim($_SERVER[rsquoPHP_SELFrsquo] rsquorsquo)if ($link == $url)
echo rsquoltli class=activegtlta href=rsquo $link rsquogtrsquo $label rsquoltagtltligtrsquo else
echo rsquoltli class=gtlta href=rsquo $link rsquogtrsquo $label rsquoltagtltligtrsquo
gt
44 List of Products
The product overiew is a simple table The heading of the table is placed in an array
ltdivgtlttable class=table table-stripedgtltthead valign=bottomgtlttrgtltphp
$heading = array(rsquoTypersquo rsquoVariantrsquo rsquoColorrsquo rsquoHardnessrsquo rsquoPrice CHFrsquo)foreach ($heading as $element)
echo rsquoltth class=headgtrsquo$elementrsquoltthgtrsquon
gtlttrgtlttheadgtlttbody valign=topgtltphp
$products = array(array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquoHBrsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquoBrsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquo2Brsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquoFrsquo rsquo12rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquoHrsquo rsquo12rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquo2Hrsquo rsquo12rsquo)
)foreach ($products as $product =gt $details)
echo lttrgtforeach ($details as $detail)
echo lttdgt$detaillttdgtecho lttrgt
gtlttbodygtlttablegt
ltdivgt
14 Kapitel 4 Dynamics
Shop Documentation Release 001
45 Company details
The data for the About page are included out of a static and plain text file
ltphp$str = file_get_contents(companytxt)echo $str
gt
45 Company details 15
Shop Documentation Release 001
16 Kapitel 4 Dynamics
KAPITEL 5
External files
51 Navigation Menu
The menu is outsourced in the file menuphp
ltphpfunction menu()
$part1 = rsquoltul class=nav nav-tabsgtrsquon$part2 = rsquorsquo$part3 = rsquoltulgtrsquon Menu array with page title and assigned file$menu = array(rsquoHomersquo =gt rsquoindexphprsquo
rsquoProduktersquo =gt rsquoproductsphprsquorsquoUumlber unsrsquo =gt rsquoaboutphprsquo
)foreach ($menu as $label =gt $link)
For the CSS only the file name without is needed$url = trim($_SERVER[rsquoPHP_SELFrsquo] rsquorsquo)if ($link == $url)
$part2 = $part2ltli class=rsquoactiversquogtlta href=rsquo$linkrsquogt$labelltagtltligtn else
$part2 = $part2ltli class=rsquorsquogtlta href=rsquo$linkrsquogt$labelltagtltligtn
return $part1$part2$part3
gt
52 Header
The complete header part is loaded from the file headerphp
ltphpfunction head()
$start_page = indexphp$part1 = ltdivgtn$part2 = tlta class=rsquobrand-logorsquo href=rsquo$start_pagersquogtltagtn$part3 = tltp class=rsquobrand-namersquogtWebshop Pencil AGltpgtn$part4 = ltdivgtnreturn $part1$part2$part3$part4
17
Shop Documentation Release 001
gt
53 Footer
The same is done witht the page footers
ltphpfunction foot()
$class1 = rsquoltdiv class=footergtrsquon$class2 = rsquoltdivgtrsquon$text = ltpgtampcopy Pencil AG getYear()rsquoltpgtrsquonreturn $class1$text$class2
function getYear()return date(Y)
gt
18 Kapitel 5 External files
KAPITEL 6
Input processing
61 ldquoBuy Nowrdquo links
The ldquoBuy Nowrdquo links are attached to the Products page Every entry has itrsquos own link which lead to a detail page Thelinks are using hidden form elements to transfer the data
ltphp$products = array(array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquoHBrsquo rsquo1rsquo)
array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquoBrsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquo2Brsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquoFrsquo rsquo12rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquoHrsquo rsquo12rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquo2Hrsquo rsquo12rsquo)
)foreach ($products as $product =gt $details)
echo lttrgtnforeach ($details as $detail)
echo lttdgt$detaillttdgtnecho lttdgtnecho ltform action=rsquoproductphprsquo method=rsquogetrsquo name=rsquopencilrsquogtnecho ltinput type=rsquohiddenrsquo name=rsquotypersquo value=rsquo$details[0]rsquogtnecho ltinput type=rsquohiddenrsquo name=rsquooptionsrsquo value=rsquo$details[1]rsquogtnecho ltinput type=rsquohiddenrsquo name=rsquocolorrsquo value=rsquo$details[2]rsquogtnecho ltinput type=rsquohiddenrsquo name=rsquohardnessrsquo value=rsquo$details[3]rsquogtnecho ltinput type=rsquohiddenrsquo name=rsquopricersquo value=rsquo$details[4]rsquogtnecho ltinput type=rsquosubmitrsquo class=rsquobtn btn-defaultrsquo value=rsquoKauf michrsquogtnecho ltformgtnecho lttdgtnecho lttrgtn
gt
And the detail page contains the code fragement mentioned below
ltphp$type=$_GET[rsquotypersquo]$color=$_GET[rsquocolorrsquo]$hardness=$_GET[rsquohardnessrsquo]$options=$_GET[rsquooptionsrsquo]$price=$_GET[rsquopricersquo]echo I am a $type in $color and a hardness of $hardness I have $options as an option and my price is $price CHF
gt
19
Shop Documentation Release 001
Bemerkung The Products page was modified in the process of the development
62 Select options
The signupbilling page contains a dropdown element that all days of a month for the entry of the userrsquos birthday
ltselect name=daygtltoptiongtDayltoptiongt
ltphp$days = range(31 1)foreach ($days as $day)
echo rsquoltoption value=rsquo$dayrsquogtrsquo$dayrsquoltoptiongtrsquo
gtltselectgt
20 Kapitel 6 Input processing
KAPITEL 7
Javascript
Over the years Javascript became a very popular programming language The webshop is using Javascript at a coupleof places
71 Simple use case
Javascript makes it easy to access elements in the DOM Setting the focus is a nice way to support the user with inputform
ltscript language=javascriptgtfunction setFocus()
documentforms[login][username]focus()
ltscriptgtltheadgtltbody onload=setFocus()gt
Another one is to check if something was entered in an input field
function validateForm() var username = documentforms[rdquologinrdquo][rdquousernamerdquo]value if (username== null || username == ldquordquo)
documentforms[rdquologinrdquo][rdquousernamerdquo]stylebackgroundColor = ldquoFF9999rdquo docu-mentforms[rdquologinrdquo][rdquousernamerdquo]placeholder = ldquoPlease your usernamerdquo docu-mentforms[rdquologinrdquo][rdquousernamerdquo]focus() return false
A simple message is informing the user about an action which was taken against the database
echo ltscript type=textjavascriptgtalert(New entry $entry added successfully)windowlocation = tablesphp
ltscriptgt
The delete process is only executed if the user confirm to delete a record
ltform action=scriptsdelete-processphp onSubmit=return confirm(rsquoAre you sure to delete this entryrsquo) method=POSTgtltinput type=hidden name=table value=$sectiongtltinput type=hidden name=id value=$result-gtidgtltinput type=submit name=Submit value=Deletegt
ltformgt
For additional Javascript please check the source of the indexphp file and the reflsquowebservicelsquo_ section
21
Shop Documentation Release 001
22 Kapitel 7 Javascript
KAPITEL 8
Cookies and Sessions
The built-in support for sessions in PHP is handling all cookie manipulation to provide persistent variables that areaccessible from different pages and across multiple visits to the site
81 Cookies
A cookie is used to track the last time a visitor check the front page The cookie is set when a visitor arrives
function lastVisit($name $expire) $value = getDateDMY() - getTimeHM()setcookie($name $value time() + $expire rsquorsquo $_SERVER[rsquoSERVER_NAMErsquo] true true)
In the footer of the index page the details are presented
ltphpif(isset($_COOKIE[rsquoLastVisitrsquo]))
$last = $_COOKIE[rsquoLastVisitrsquo]echo You last visited us on $last
else echo This is your first visit
gt
82 Hit counter
As a simple show case for PHP sessions a hit counter for the front page is available
ltphpsession_start()
$_SESSION[rsquohitsrsquo] = $_SESSION[rsquohitsrsquo] + 1gt
Included in the footer it shous the users the total of visits
echo Total $_SESSION[rsquohitsrsquo] visits of this page
23
Shop Documentation Release 001
83 Language selection
84 User Accounts
24 Kapitel 8 Cookies and Sessions
KAPITEL 9
Database
The database backend for the webshop will be MariaDB which is the drop-in replacement for MySQL
For the setup please check the Development section in this documentation
91 Tables
The following tables are needed for the webshop to work
bull products
bull customers
bull pencils
bull colors
bull hardness
bull options
bull users
Please use the develwebshopsql to setup the database
92 PHP
Below you find the configuration file for a default installation of the webshop This file is a template and filled duringthe setup process
ltphp$host = localhost$user = root$password = webshop$dbase = webshop$connection = new mysqli($host $user $password $dbase)
if ($connection-gtconnect_errno) echo Failed to connect to MariaDBMySQL ($connection-gtconnect_errno) $connection-gtconnect_error
mysqli_report(MYSQLI_REPORT_ERROR)
gt
25
Shop Documentation Release 001
All connections to the database are done in the same way Below you find an example Everything is done in theobject-oriented style
ltphprequire_once(rsquoconfigdbconnectphprsquo)if ($connection-gtconnect_errno == 0)
$sql = SELECT FROM products$results = $connection-gtquery($sql)echo $results-gtnum_rows$results-gtclose()
else echo Database connection error
gt
26 Kapitel 9 Database
KAPITEL 10
Web service
Tow web services are integrated to take advantages of online available data sources
101 Map
Leafletjs a JavaScript library for working with interactive maps from OpenStreetMap (OSM) is implemented as ashow case for a simple web service
The basic steps to integrate a map is shown below
ltdiv id=map class=map style=width 600px height 400pxgtltdivgt
ltscript src=scriptsleafletjsgtltscriptgtltscript src=scriptsleaflet-providersjsgtltscriptgtltscriptgtvar map = Lmap(rsquomaprsquo
center [250472 -773255]zoom 12zoomControl true
)
var defaultLayer = LtileLayerprovider(rsquoOpenStreetMapMapnikrsquo)addTo(map)ltscriptgt
102 Weather
The OpenWeatherMap service provides free weather data and a forecast API for web applications
ltphp Details about the API httpbugsopenweathermaporgprojectsapiwikiApi_2_5_weather$url = rsquohttpapiopenweathermaporgdata25weatherq=Bernechampunit=metricsampmode=jsonrsquo
$json = file_get_contents($url)$data = json_decode($json)
$tempC = round((27315 - $data-gtmain-gttemp)100) 100$humidity = $data-gtmain-gthumidity$pressure = $data-gtmain-gtpressure
27
Shop Documentation Release 001
echo ltpgtTemperatur $tempC degCltbrgtnecho Luftfeuchtigkeit $humidity ltbrgtnecho Luftdruck $pressure Paltpgtn
gt
28 Kapitel 10 Web service
KAPITEL 11
Data export
111 PDF
FPDF is a PHP class that allows to generate PDF files with pure PHP As a showcase for that the product specificationsfor a given product are filled in a pdf and showed in the browser The user can then decide to download or print thefile
112 JSON
JavaScript Object Notation (JSON) is a lightweight data-interchange format The format is language independent andPHP support the encoding and the decoding JSON with json_encode($data) and json_decode($data)$rows = array()$sql = SELECT FROM products$results = $connection-gtquery($sql)while ($result = $results-gtfetch_object())
$rows[] = $result$results-gtclose()
Writing all rows to a JSON file$fp = fopen(rsquopencilsjsonrsquo rsquowrsquo)fwrite($fp json_encode($rows))fclose($fp)gt
and for reading it
ltphp$json = file_get_contents(rsquopencilsjsonrsquo)print_r(json_decode($json))
gt
29
Shop Documentation Release 001
30 Kapitel 11 Data export
KAPITEL 12
Messaging
Beside standard email messages the webshop supports sending MQ Telemetry Transport protocol (MQTT) messagesas an additional feature The MQTT messages are small
121 MQTT
Mosquitto-PHP is used as a PHP wrapper for MQTT Please check the Projectrsquos README for details about theinstallation and the setup
1211 Broker
Mosquitto is a message broker that implements the MQ Telemetry Transport protocol Check if mosquitto is run-ning
$ sudo systemctl status mosquittoservice
If not start it
$ systemctl start mosquittoservice
All messages are published to the topic webshop
1212 Publishing
After the installation of Mosquitto-PHP the snipplet shown below sends a single message
ltphpdefine(rsquoBROKERrsquo rsquolocalhostrsquo)define(rsquoPORTrsquo 1883)define(rsquoCLIENT_IDrsquo webshop_ + getmypid())$topic = webshop$subtopic = test$completeTopic = $topic$subtopic
$client = new MosquittoClient(CLIENT_ID)$client-gtconnect(BROKER PORT 60)
$message = Test message from webshop at date(Y-m-d His)$client-gtpublish($completeTopic $message 0 false)
gt
31
Shop Documentation Release 001
1213 Subscribing
To read the messages sent by the webshop a client is needed The Mosquitto broker contain a simple command-linetool for subscribing to various topics
$ mosquitto_sub -h localhost -t webshop
122 Email
This section doesnrsquot describe the installation and configuration of a local MTA There are enough resources thatcontains information about the setup of postfix for local delivery only
If you want to test the email feature add the following code in one of PHP pages
ltphp mail(rsquorootlocalhostrsquo rsquoTest message from webshoprsquo rsquoThe webshop is selling pencilsrsquo) gt
By default SELinux is running in Enforcing mode which is restrictive about about what a web server can do Toallow sending email the following SELinux boolean needs to changed
setsebool -P httpd_can_network_connect=1 setsebool -P httpd_can_sendmail=1
32 Kapitel 12 Messaging
KAPITEL 13
Localisation (L10n)
There are several ways to add localisation to a web site For small projects arrays with string can work but this is notvery efficient and user-friendly With Gettext is a toolset available that provide a framework to produce multi-lingualcontent in a wide area of programming languages
Make sure that the php-gettext package is available on your system If not install it
$ sudo yum -y install php-php-gettext
Check if gettext support is available
ltphpif (function_exists(gettext))
echo gettext is not installednelse
echo gettext is supportedn
gt
Make sure that all locales your want are available on the server
locale -a
The first step is to mark all string which should be translatable as shown below For further details please refer to theGettext documentation
echo _(rsquoSome textrsquo)
The next step is to extract all strings
xgettext --from-code=UTF-8 -o localewebshoppot php scriptsphp
To re-generate the file after an update join the strings
xgettext -j --from-code=UTF-8 -o localewebshoppot php scriptsphp
For every language a po file is needed for the transations Generate it with the command mentioned below
msginit --no-translator -l de_CH -o localede_CHpo -i localewebshoppot
Once created there are only updates of the message catalog needed in the futures
msgmerge -U localede_CHpo localewebshoppot
If you re finish create the mo file for the specific language
33
Shop Documentation Release 001
msgfmt -c -v -o localede_CHLC_MESSAGESwebshopmo localede_CHpo
34 Kapitel 13 Localisation (L10n)
KAPITEL 14
Templates
Beside other solutions Savant3 is a lightweight object-oriented template system for PHP This solution does not needa lot of additional configuration
141 Template
A simple template file looks like the one shown below
lthtmlgtltheadgt
lttitlegtltphp echo $this-gteprint($this-gttitle) gtlttitlegtltheadgtltbodygt
ltphp echo $this-gteprint($this-gtcontent) gtltbodygt
lthtmlgt
For a more detailed intro check this article on Zend Developer Zone
142 Content
To fill the template with data all wished variables needs to be defined in a seperate PHP file
ltphprequire_once rsquoscriptsSavant3phprsquo$tpl = new Savant3()
Create a title$title = Simple sample page
Create the content of the page$content = Some sample text to show
Assign values to the Savant instance$tpl-gttitle = $title$tpl-gtcontent = $content
Define the template source file to show$tpl-gtdisplay(rsquosimpletplphprsquo)
gt
35
Shop Documentation Release 001
The webshop contains a page (master)
36 Kapitel 14 Templates
KAPITEL 15
Development
This sections describes the configuration of the development and runtime environment for the web shop
151 Web server
Instead of Apache the project is running on Lighttpd The reasons are that Lighttpd provides faster setup easierconfiguration and better performance Lighttpd is running with FastCGI
The path of the web server is varwwwlighttpd and the SELinux configuration are still the defaults
The web server is running in SSL-only mode and the certificate is generated during the server setup process
152 Database server
For persistence storage the drop-in replacement MariaDB is used MySQL will work to but this is not tested phpMyAd-min is available under phpmyadmin on the web server beside the command-line tools for easy administration
The default credentials for phpMyAdmin are rootwebshop or the entry you made in the Ansible playbookdevelvariablessensitiveyml
153 Versions
The web shop is built with the below listed components and tested Other releases can be used and may work but thiswill not be tested Probably it will work with different releases
bull Operating system Fedora 20
bull Kernel 3135-202fc20x86_64
bull Lighttpd 1434
bull PHP 557
bull MariaDB 5534
For communication postfix and mosquitto are needed additionally
37
Shop Documentation Release 001
154 Setup infrastructure
1541 Configuration management
For the creation of reproducable and identical environment for the development and the run-time across differentsystems Ansible is used as configuration management solution All needed steps of the installation are automated Theconfiguration doesnrsquot differentiate between local or remote installations This matters only for the deployment of theweb content
For local development itrsquos possible to use an LX container
$ sudo ansible-playbook develcontaineryml
To get everything running some additional steps (check the network inside the container generate keys etc) areneeded After you are done check it
$ sudo ansible webshop -m setup
From the management system
$ sudo ssh-copy-id -i rootsshid_rsapub root[IP address of your managed node]
The configuration of Ansible itself (adding the system to etcansiblehosts and copying the SSH keys) isnot documented at this place There are various resources available like here All playbooks are located in the folderdevel Start the setup with the command shown below
$ sudo ansible-playbook develsetupyml
The used group name in etcansiblehosts is webshop
If the setup completes without errors then the web server is accessible and show a default page Please keep in mindthat the server is only accessible over https unencrypted traffic is not allowed
1542 DeploymentSetup website
For the simple deployment of the lastest version of the shop a playbook called deployyml is provided Thisplaybook put all files in place
$ sudo ansible-playbook develdeployyml
To full deploy the webshop all tables in the database must exist The file webshopsql contains all needed SQLcommands and sample data for the web application
Itrsquos possible to deploy the website manually but this is not recommended A couple of files are depending on templateswhich are created during the deployment
Itrsquos also not recommanded to clone everything into your webserver root This would save you the trouble of doing itby hand but third-party features are missing then Those missing parts are the template engine the pdf generation theconnection to Openstreetmap and probably other things not mentioned here
155 Git respository
All project relevante informations (Source code templates documentation etc) is located in a public Git repositoryon Github
38 Kapitel 15 Development
Shop Documentation Release 001
156 Documentation
The documentation is using reStructuredText as markup language For a local build Sphinx is needed Sphinx isavailable in the Fedora Package Collection and can be installed with yum or any other package management tool
yum -y install python-sphinx python-docutils
The source files of the documentation are located under docs
$ cd docs$ make html
The output is stored under docs_buildhtml
After every push to Github a hook launch a rebuild of the documentation The latest release will be published on Readthe Docs automatically
httpsshoprtfdorg
156 Documentation 39
Shop Documentation Release 001
40 Kapitel 15 Development
KAPITEL 16
Indices and tables
bull genindex
bull modindex
bull search
41
- Basics
-
- Products
- Personas
- Use cases
- Design principles
-
- Web shop Design
-
- General
- Layout
- Sitemap
- Main page
-
- Style and design
-
- Cascading Style Sheets
- Pages
-
- Dynamics
-
- Setup
- Current year
- Navigation Menu
- List of Products
- Company details
-
- External files
-
- Navigation Menu
- Header
- Footer
-
- Input processing
-
- ``Buy Now links
- Select options
-
- Javascript
-
- Simple use case
-
- Cookies and Sessions
-
- Cookies
- Hit counter
- Language selection
- User Accounts
-
- Database
-
- Tables
- PHP
-
- Web service
-
- Map
- Weather
-
- Data export
-
- JSON
-
- Messaging
-
- MQTT
-
- Localisation (L10n)
- Templates
-
- Template
- Content
-
- Development
-
- Web server
- Database server
- Versions
- Setup infrastructure
- Git respository
- Documentation
-
- Indices and tables
-
KAPITEL 4
Dynamics
The webshop will be a PHP application at the end Those first steps are only covering the very basic stuff of PHP asan introduction
41 Setup
The setupyml playbook puts a simple PHP file in the root directory of the web server with the namephpinfophp This file displays PHP details
Achtung Remove this file before makeing the shop accessible by a public audience
42 Current year
The first PHP element in the webshop is showing the current year in the footer of every page With the help of thislittle piece of code there is no longer a need to update the year
ltphp echo date(Y) gt
43 Navigation Menu
The basic menu was built with the following snippet
ltphp$menu = array(rsquoHomersquo =gt rsquoindexphprsquo
rsquoProduktersquo =gt rsquoproductsphprsquorsquoUumlber unsrsquo =gt rsquoaboutphprsquo
)foreach($menu as $label =gt $link)
echo rsquoltligtlta href=rsquo $link rsquogtrsquo $label rsquoltagtltligtrsquo
gt
The issue with that snippet was that the CSS class was missing In regards to a future separation and reusability anadditional statements was added This way the label of the active page is highlighted
13
Shop Documentation Release 001
ltphp$menu = array(rsquoHomersquo =gt rsquoindexphprsquo
rsquoProduktersquo =gt rsquoproductsphprsquorsquoUumlber unsrsquo =gt rsquoaboutphprsquo
)foreach ($menu as $label =gt $link)
$url = trim($_SERVER[rsquoPHP_SELFrsquo] rsquorsquo)if ($link == $url)
echo rsquoltli class=activegtlta href=rsquo $link rsquogtrsquo $label rsquoltagtltligtrsquo else
echo rsquoltli class=gtlta href=rsquo $link rsquogtrsquo $label rsquoltagtltligtrsquo
gt
44 List of Products
The product overiew is a simple table The heading of the table is placed in an array
ltdivgtlttable class=table table-stripedgtltthead valign=bottomgtlttrgtltphp
$heading = array(rsquoTypersquo rsquoVariantrsquo rsquoColorrsquo rsquoHardnessrsquo rsquoPrice CHFrsquo)foreach ($heading as $element)
echo rsquoltth class=headgtrsquo$elementrsquoltthgtrsquon
gtlttrgtlttheadgtlttbody valign=topgtltphp
$products = array(array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquoHBrsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquoBrsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquo2Brsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquoFrsquo rsquo12rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquoHrsquo rsquo12rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquo2Hrsquo rsquo12rsquo)
)foreach ($products as $product =gt $details)
echo lttrgtforeach ($details as $detail)
echo lttdgt$detaillttdgtecho lttrgt
gtlttbodygtlttablegt
ltdivgt
14 Kapitel 4 Dynamics
Shop Documentation Release 001
45 Company details
The data for the About page are included out of a static and plain text file
ltphp$str = file_get_contents(companytxt)echo $str
gt
45 Company details 15
Shop Documentation Release 001
16 Kapitel 4 Dynamics
KAPITEL 5
External files
51 Navigation Menu
The menu is outsourced in the file menuphp
ltphpfunction menu()
$part1 = rsquoltul class=nav nav-tabsgtrsquon$part2 = rsquorsquo$part3 = rsquoltulgtrsquon Menu array with page title and assigned file$menu = array(rsquoHomersquo =gt rsquoindexphprsquo
rsquoProduktersquo =gt rsquoproductsphprsquorsquoUumlber unsrsquo =gt rsquoaboutphprsquo
)foreach ($menu as $label =gt $link)
For the CSS only the file name without is needed$url = trim($_SERVER[rsquoPHP_SELFrsquo] rsquorsquo)if ($link == $url)
$part2 = $part2ltli class=rsquoactiversquogtlta href=rsquo$linkrsquogt$labelltagtltligtn else
$part2 = $part2ltli class=rsquorsquogtlta href=rsquo$linkrsquogt$labelltagtltligtn
return $part1$part2$part3
gt
52 Header
The complete header part is loaded from the file headerphp
ltphpfunction head()
$start_page = indexphp$part1 = ltdivgtn$part2 = tlta class=rsquobrand-logorsquo href=rsquo$start_pagersquogtltagtn$part3 = tltp class=rsquobrand-namersquogtWebshop Pencil AGltpgtn$part4 = ltdivgtnreturn $part1$part2$part3$part4
17
Shop Documentation Release 001
gt
53 Footer
The same is done witht the page footers
ltphpfunction foot()
$class1 = rsquoltdiv class=footergtrsquon$class2 = rsquoltdivgtrsquon$text = ltpgtampcopy Pencil AG getYear()rsquoltpgtrsquonreturn $class1$text$class2
function getYear()return date(Y)
gt
18 Kapitel 5 External files
KAPITEL 6
Input processing
61 ldquoBuy Nowrdquo links
The ldquoBuy Nowrdquo links are attached to the Products page Every entry has itrsquos own link which lead to a detail page Thelinks are using hidden form elements to transfer the data
ltphp$products = array(array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquoHBrsquo rsquo1rsquo)
array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquoBrsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquo2Brsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquoFrsquo rsquo12rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquoHrsquo rsquo12rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquo2Hrsquo rsquo12rsquo)
)foreach ($products as $product =gt $details)
echo lttrgtnforeach ($details as $detail)
echo lttdgt$detaillttdgtnecho lttdgtnecho ltform action=rsquoproductphprsquo method=rsquogetrsquo name=rsquopencilrsquogtnecho ltinput type=rsquohiddenrsquo name=rsquotypersquo value=rsquo$details[0]rsquogtnecho ltinput type=rsquohiddenrsquo name=rsquooptionsrsquo value=rsquo$details[1]rsquogtnecho ltinput type=rsquohiddenrsquo name=rsquocolorrsquo value=rsquo$details[2]rsquogtnecho ltinput type=rsquohiddenrsquo name=rsquohardnessrsquo value=rsquo$details[3]rsquogtnecho ltinput type=rsquohiddenrsquo name=rsquopricersquo value=rsquo$details[4]rsquogtnecho ltinput type=rsquosubmitrsquo class=rsquobtn btn-defaultrsquo value=rsquoKauf michrsquogtnecho ltformgtnecho lttdgtnecho lttrgtn
gt
And the detail page contains the code fragement mentioned below
ltphp$type=$_GET[rsquotypersquo]$color=$_GET[rsquocolorrsquo]$hardness=$_GET[rsquohardnessrsquo]$options=$_GET[rsquooptionsrsquo]$price=$_GET[rsquopricersquo]echo I am a $type in $color and a hardness of $hardness I have $options as an option and my price is $price CHF
gt
19
Shop Documentation Release 001
Bemerkung The Products page was modified in the process of the development
62 Select options
The signupbilling page contains a dropdown element that all days of a month for the entry of the userrsquos birthday
ltselect name=daygtltoptiongtDayltoptiongt
ltphp$days = range(31 1)foreach ($days as $day)
echo rsquoltoption value=rsquo$dayrsquogtrsquo$dayrsquoltoptiongtrsquo
gtltselectgt
20 Kapitel 6 Input processing
KAPITEL 7
Javascript
Over the years Javascript became a very popular programming language The webshop is using Javascript at a coupleof places
71 Simple use case
Javascript makes it easy to access elements in the DOM Setting the focus is a nice way to support the user with inputform
ltscript language=javascriptgtfunction setFocus()
documentforms[login][username]focus()
ltscriptgtltheadgtltbody onload=setFocus()gt
Another one is to check if something was entered in an input field
function validateForm() var username = documentforms[rdquologinrdquo][rdquousernamerdquo]value if (username== null || username == ldquordquo)
documentforms[rdquologinrdquo][rdquousernamerdquo]stylebackgroundColor = ldquoFF9999rdquo docu-mentforms[rdquologinrdquo][rdquousernamerdquo]placeholder = ldquoPlease your usernamerdquo docu-mentforms[rdquologinrdquo][rdquousernamerdquo]focus() return false
A simple message is informing the user about an action which was taken against the database
echo ltscript type=textjavascriptgtalert(New entry $entry added successfully)windowlocation = tablesphp
ltscriptgt
The delete process is only executed if the user confirm to delete a record
ltform action=scriptsdelete-processphp onSubmit=return confirm(rsquoAre you sure to delete this entryrsquo) method=POSTgtltinput type=hidden name=table value=$sectiongtltinput type=hidden name=id value=$result-gtidgtltinput type=submit name=Submit value=Deletegt
ltformgt
For additional Javascript please check the source of the indexphp file and the reflsquowebservicelsquo_ section
21
Shop Documentation Release 001
22 Kapitel 7 Javascript
KAPITEL 8
Cookies and Sessions
The built-in support for sessions in PHP is handling all cookie manipulation to provide persistent variables that areaccessible from different pages and across multiple visits to the site
81 Cookies
A cookie is used to track the last time a visitor check the front page The cookie is set when a visitor arrives
function lastVisit($name $expire) $value = getDateDMY() - getTimeHM()setcookie($name $value time() + $expire rsquorsquo $_SERVER[rsquoSERVER_NAMErsquo] true true)
In the footer of the index page the details are presented
ltphpif(isset($_COOKIE[rsquoLastVisitrsquo]))
$last = $_COOKIE[rsquoLastVisitrsquo]echo You last visited us on $last
else echo This is your first visit
gt
82 Hit counter
As a simple show case for PHP sessions a hit counter for the front page is available
ltphpsession_start()
$_SESSION[rsquohitsrsquo] = $_SESSION[rsquohitsrsquo] + 1gt
Included in the footer it shous the users the total of visits
echo Total $_SESSION[rsquohitsrsquo] visits of this page
23
Shop Documentation Release 001
83 Language selection
84 User Accounts
24 Kapitel 8 Cookies and Sessions
KAPITEL 9
Database
The database backend for the webshop will be MariaDB which is the drop-in replacement for MySQL
For the setup please check the Development section in this documentation
91 Tables
The following tables are needed for the webshop to work
bull products
bull customers
bull pencils
bull colors
bull hardness
bull options
bull users
Please use the develwebshopsql to setup the database
92 PHP
Below you find the configuration file for a default installation of the webshop This file is a template and filled duringthe setup process
ltphp$host = localhost$user = root$password = webshop$dbase = webshop$connection = new mysqli($host $user $password $dbase)
if ($connection-gtconnect_errno) echo Failed to connect to MariaDBMySQL ($connection-gtconnect_errno) $connection-gtconnect_error
mysqli_report(MYSQLI_REPORT_ERROR)
gt
25
Shop Documentation Release 001
All connections to the database are done in the same way Below you find an example Everything is done in theobject-oriented style
ltphprequire_once(rsquoconfigdbconnectphprsquo)if ($connection-gtconnect_errno == 0)
$sql = SELECT FROM products$results = $connection-gtquery($sql)echo $results-gtnum_rows$results-gtclose()
else echo Database connection error
gt
26 Kapitel 9 Database
KAPITEL 10
Web service
Tow web services are integrated to take advantages of online available data sources
101 Map
Leafletjs a JavaScript library for working with interactive maps from OpenStreetMap (OSM) is implemented as ashow case for a simple web service
The basic steps to integrate a map is shown below
ltdiv id=map class=map style=width 600px height 400pxgtltdivgt
ltscript src=scriptsleafletjsgtltscriptgtltscript src=scriptsleaflet-providersjsgtltscriptgtltscriptgtvar map = Lmap(rsquomaprsquo
center [250472 -773255]zoom 12zoomControl true
)
var defaultLayer = LtileLayerprovider(rsquoOpenStreetMapMapnikrsquo)addTo(map)ltscriptgt
102 Weather
The OpenWeatherMap service provides free weather data and a forecast API for web applications
ltphp Details about the API httpbugsopenweathermaporgprojectsapiwikiApi_2_5_weather$url = rsquohttpapiopenweathermaporgdata25weatherq=Bernechampunit=metricsampmode=jsonrsquo
$json = file_get_contents($url)$data = json_decode($json)
$tempC = round((27315 - $data-gtmain-gttemp)100) 100$humidity = $data-gtmain-gthumidity$pressure = $data-gtmain-gtpressure
27
Shop Documentation Release 001
echo ltpgtTemperatur $tempC degCltbrgtnecho Luftfeuchtigkeit $humidity ltbrgtnecho Luftdruck $pressure Paltpgtn
gt
28 Kapitel 10 Web service
KAPITEL 11
Data export
111 PDF
FPDF is a PHP class that allows to generate PDF files with pure PHP As a showcase for that the product specificationsfor a given product are filled in a pdf and showed in the browser The user can then decide to download or print thefile
112 JSON
JavaScript Object Notation (JSON) is a lightweight data-interchange format The format is language independent andPHP support the encoding and the decoding JSON with json_encode($data) and json_decode($data)$rows = array()$sql = SELECT FROM products$results = $connection-gtquery($sql)while ($result = $results-gtfetch_object())
$rows[] = $result$results-gtclose()
Writing all rows to a JSON file$fp = fopen(rsquopencilsjsonrsquo rsquowrsquo)fwrite($fp json_encode($rows))fclose($fp)gt
and for reading it
ltphp$json = file_get_contents(rsquopencilsjsonrsquo)print_r(json_decode($json))
gt
29
Shop Documentation Release 001
30 Kapitel 11 Data export
KAPITEL 12
Messaging
Beside standard email messages the webshop supports sending MQ Telemetry Transport protocol (MQTT) messagesas an additional feature The MQTT messages are small
121 MQTT
Mosquitto-PHP is used as a PHP wrapper for MQTT Please check the Projectrsquos README for details about theinstallation and the setup
1211 Broker
Mosquitto is a message broker that implements the MQ Telemetry Transport protocol Check if mosquitto is run-ning
$ sudo systemctl status mosquittoservice
If not start it
$ systemctl start mosquittoservice
All messages are published to the topic webshop
1212 Publishing
After the installation of Mosquitto-PHP the snipplet shown below sends a single message
ltphpdefine(rsquoBROKERrsquo rsquolocalhostrsquo)define(rsquoPORTrsquo 1883)define(rsquoCLIENT_IDrsquo webshop_ + getmypid())$topic = webshop$subtopic = test$completeTopic = $topic$subtopic
$client = new MosquittoClient(CLIENT_ID)$client-gtconnect(BROKER PORT 60)
$message = Test message from webshop at date(Y-m-d His)$client-gtpublish($completeTopic $message 0 false)
gt
31
Shop Documentation Release 001
1213 Subscribing
To read the messages sent by the webshop a client is needed The Mosquitto broker contain a simple command-linetool for subscribing to various topics
$ mosquitto_sub -h localhost -t webshop
122 Email
This section doesnrsquot describe the installation and configuration of a local MTA There are enough resources thatcontains information about the setup of postfix for local delivery only
If you want to test the email feature add the following code in one of PHP pages
ltphp mail(rsquorootlocalhostrsquo rsquoTest message from webshoprsquo rsquoThe webshop is selling pencilsrsquo) gt
By default SELinux is running in Enforcing mode which is restrictive about about what a web server can do Toallow sending email the following SELinux boolean needs to changed
setsebool -P httpd_can_network_connect=1 setsebool -P httpd_can_sendmail=1
32 Kapitel 12 Messaging
KAPITEL 13
Localisation (L10n)
There are several ways to add localisation to a web site For small projects arrays with string can work but this is notvery efficient and user-friendly With Gettext is a toolset available that provide a framework to produce multi-lingualcontent in a wide area of programming languages
Make sure that the php-gettext package is available on your system If not install it
$ sudo yum -y install php-php-gettext
Check if gettext support is available
ltphpif (function_exists(gettext))
echo gettext is not installednelse
echo gettext is supportedn
gt
Make sure that all locales your want are available on the server
locale -a
The first step is to mark all string which should be translatable as shown below For further details please refer to theGettext documentation
echo _(rsquoSome textrsquo)
The next step is to extract all strings
xgettext --from-code=UTF-8 -o localewebshoppot php scriptsphp
To re-generate the file after an update join the strings
xgettext -j --from-code=UTF-8 -o localewebshoppot php scriptsphp
For every language a po file is needed for the transations Generate it with the command mentioned below
msginit --no-translator -l de_CH -o localede_CHpo -i localewebshoppot
Once created there are only updates of the message catalog needed in the futures
msgmerge -U localede_CHpo localewebshoppot
If you re finish create the mo file for the specific language
33
Shop Documentation Release 001
msgfmt -c -v -o localede_CHLC_MESSAGESwebshopmo localede_CHpo
34 Kapitel 13 Localisation (L10n)
KAPITEL 14
Templates
Beside other solutions Savant3 is a lightweight object-oriented template system for PHP This solution does not needa lot of additional configuration
141 Template
A simple template file looks like the one shown below
lthtmlgtltheadgt
lttitlegtltphp echo $this-gteprint($this-gttitle) gtlttitlegtltheadgtltbodygt
ltphp echo $this-gteprint($this-gtcontent) gtltbodygt
lthtmlgt
For a more detailed intro check this article on Zend Developer Zone
142 Content
To fill the template with data all wished variables needs to be defined in a seperate PHP file
ltphprequire_once rsquoscriptsSavant3phprsquo$tpl = new Savant3()
Create a title$title = Simple sample page
Create the content of the page$content = Some sample text to show
Assign values to the Savant instance$tpl-gttitle = $title$tpl-gtcontent = $content
Define the template source file to show$tpl-gtdisplay(rsquosimpletplphprsquo)
gt
35
Shop Documentation Release 001
The webshop contains a page (master)
36 Kapitel 14 Templates
KAPITEL 15
Development
This sections describes the configuration of the development and runtime environment for the web shop
151 Web server
Instead of Apache the project is running on Lighttpd The reasons are that Lighttpd provides faster setup easierconfiguration and better performance Lighttpd is running with FastCGI
The path of the web server is varwwwlighttpd and the SELinux configuration are still the defaults
The web server is running in SSL-only mode and the certificate is generated during the server setup process
152 Database server
For persistence storage the drop-in replacement MariaDB is used MySQL will work to but this is not tested phpMyAd-min is available under phpmyadmin on the web server beside the command-line tools for easy administration
The default credentials for phpMyAdmin are rootwebshop or the entry you made in the Ansible playbookdevelvariablessensitiveyml
153 Versions
The web shop is built with the below listed components and tested Other releases can be used and may work but thiswill not be tested Probably it will work with different releases
bull Operating system Fedora 20
bull Kernel 3135-202fc20x86_64
bull Lighttpd 1434
bull PHP 557
bull MariaDB 5534
For communication postfix and mosquitto are needed additionally
37
Shop Documentation Release 001
154 Setup infrastructure
1541 Configuration management
For the creation of reproducable and identical environment for the development and the run-time across differentsystems Ansible is used as configuration management solution All needed steps of the installation are automated Theconfiguration doesnrsquot differentiate between local or remote installations This matters only for the deployment of theweb content
For local development itrsquos possible to use an LX container
$ sudo ansible-playbook develcontaineryml
To get everything running some additional steps (check the network inside the container generate keys etc) areneeded After you are done check it
$ sudo ansible webshop -m setup
From the management system
$ sudo ssh-copy-id -i rootsshid_rsapub root[IP address of your managed node]
The configuration of Ansible itself (adding the system to etcansiblehosts and copying the SSH keys) isnot documented at this place There are various resources available like here All playbooks are located in the folderdevel Start the setup with the command shown below
$ sudo ansible-playbook develsetupyml
The used group name in etcansiblehosts is webshop
If the setup completes without errors then the web server is accessible and show a default page Please keep in mindthat the server is only accessible over https unencrypted traffic is not allowed
1542 DeploymentSetup website
For the simple deployment of the lastest version of the shop a playbook called deployyml is provided Thisplaybook put all files in place
$ sudo ansible-playbook develdeployyml
To full deploy the webshop all tables in the database must exist The file webshopsql contains all needed SQLcommands and sample data for the web application
Itrsquos possible to deploy the website manually but this is not recommended A couple of files are depending on templateswhich are created during the deployment
Itrsquos also not recommanded to clone everything into your webserver root This would save you the trouble of doing itby hand but third-party features are missing then Those missing parts are the template engine the pdf generation theconnection to Openstreetmap and probably other things not mentioned here
155 Git respository
All project relevante informations (Source code templates documentation etc) is located in a public Git repositoryon Github
38 Kapitel 15 Development
Shop Documentation Release 001
156 Documentation
The documentation is using reStructuredText as markup language For a local build Sphinx is needed Sphinx isavailable in the Fedora Package Collection and can be installed with yum or any other package management tool
yum -y install python-sphinx python-docutils
The source files of the documentation are located under docs
$ cd docs$ make html
The output is stored under docs_buildhtml
After every push to Github a hook launch a rebuild of the documentation The latest release will be published on Readthe Docs automatically
httpsshoprtfdorg
156 Documentation 39
Shop Documentation Release 001
40 Kapitel 15 Development
KAPITEL 16
Indices and tables
bull genindex
bull modindex
bull search
41
- Basics
-
- Products
- Personas
- Use cases
- Design principles
-
- Web shop Design
-
- General
- Layout
- Sitemap
- Main page
-
- Style and design
-
- Cascading Style Sheets
- Pages
-
- Dynamics
-
- Setup
- Current year
- Navigation Menu
- List of Products
- Company details
-
- External files
-
- Navigation Menu
- Header
- Footer
-
- Input processing
-
- ``Buy Now links
- Select options
-
- Javascript
-
- Simple use case
-
- Cookies and Sessions
-
- Cookies
- Hit counter
- Language selection
- User Accounts
-
- Database
-
- Tables
- PHP
-
- Web service
-
- Map
- Weather
-
- Data export
-
- JSON
-
- Messaging
-
- MQTT
-
- Localisation (L10n)
- Templates
-
- Template
- Content
-
- Development
-
- Web server
- Database server
- Versions
- Setup infrastructure
- Git respository
- Documentation
-
- Indices and tables
-
Shop Documentation Release 001
ltphp$menu = array(rsquoHomersquo =gt rsquoindexphprsquo
rsquoProduktersquo =gt rsquoproductsphprsquorsquoUumlber unsrsquo =gt rsquoaboutphprsquo
)foreach ($menu as $label =gt $link)
$url = trim($_SERVER[rsquoPHP_SELFrsquo] rsquorsquo)if ($link == $url)
echo rsquoltli class=activegtlta href=rsquo $link rsquogtrsquo $label rsquoltagtltligtrsquo else
echo rsquoltli class=gtlta href=rsquo $link rsquogtrsquo $label rsquoltagtltligtrsquo
gt
44 List of Products
The product overiew is a simple table The heading of the table is placed in an array
ltdivgtlttable class=table table-stripedgtltthead valign=bottomgtlttrgtltphp
$heading = array(rsquoTypersquo rsquoVariantrsquo rsquoColorrsquo rsquoHardnessrsquo rsquoPrice CHFrsquo)foreach ($heading as $element)
echo rsquoltth class=headgtrsquo$elementrsquoltthgtrsquon
gtlttrgtlttheadgtlttbody valign=topgtltphp
$products = array(array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquoHBrsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquoBrsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquo2Brsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquoFrsquo rsquo12rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquoHrsquo rsquo12rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquo2Hrsquo rsquo12rsquo)
)foreach ($products as $product =gt $details)
echo lttrgtforeach ($details as $detail)
echo lttdgt$detaillttdgtecho lttrgt
gtlttbodygtlttablegt
ltdivgt
14 Kapitel 4 Dynamics
Shop Documentation Release 001
45 Company details
The data for the About page are included out of a static and plain text file
ltphp$str = file_get_contents(companytxt)echo $str
gt
45 Company details 15
Shop Documentation Release 001
16 Kapitel 4 Dynamics
KAPITEL 5
External files
51 Navigation Menu
The menu is outsourced in the file menuphp
ltphpfunction menu()
$part1 = rsquoltul class=nav nav-tabsgtrsquon$part2 = rsquorsquo$part3 = rsquoltulgtrsquon Menu array with page title and assigned file$menu = array(rsquoHomersquo =gt rsquoindexphprsquo
rsquoProduktersquo =gt rsquoproductsphprsquorsquoUumlber unsrsquo =gt rsquoaboutphprsquo
)foreach ($menu as $label =gt $link)
For the CSS only the file name without is needed$url = trim($_SERVER[rsquoPHP_SELFrsquo] rsquorsquo)if ($link == $url)
$part2 = $part2ltli class=rsquoactiversquogtlta href=rsquo$linkrsquogt$labelltagtltligtn else
$part2 = $part2ltli class=rsquorsquogtlta href=rsquo$linkrsquogt$labelltagtltligtn
return $part1$part2$part3
gt
52 Header
The complete header part is loaded from the file headerphp
ltphpfunction head()
$start_page = indexphp$part1 = ltdivgtn$part2 = tlta class=rsquobrand-logorsquo href=rsquo$start_pagersquogtltagtn$part3 = tltp class=rsquobrand-namersquogtWebshop Pencil AGltpgtn$part4 = ltdivgtnreturn $part1$part2$part3$part4
17
Shop Documentation Release 001
gt
53 Footer
The same is done witht the page footers
ltphpfunction foot()
$class1 = rsquoltdiv class=footergtrsquon$class2 = rsquoltdivgtrsquon$text = ltpgtampcopy Pencil AG getYear()rsquoltpgtrsquonreturn $class1$text$class2
function getYear()return date(Y)
gt
18 Kapitel 5 External files
KAPITEL 6
Input processing
61 ldquoBuy Nowrdquo links
The ldquoBuy Nowrdquo links are attached to the Products page Every entry has itrsquos own link which lead to a detail page Thelinks are using hidden form elements to transfer the data
ltphp$products = array(array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquoHBrsquo rsquo1rsquo)
array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquoBrsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquo2Brsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquoFrsquo rsquo12rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquoHrsquo rsquo12rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquo2Hrsquo rsquo12rsquo)
)foreach ($products as $product =gt $details)
echo lttrgtnforeach ($details as $detail)
echo lttdgt$detaillttdgtnecho lttdgtnecho ltform action=rsquoproductphprsquo method=rsquogetrsquo name=rsquopencilrsquogtnecho ltinput type=rsquohiddenrsquo name=rsquotypersquo value=rsquo$details[0]rsquogtnecho ltinput type=rsquohiddenrsquo name=rsquooptionsrsquo value=rsquo$details[1]rsquogtnecho ltinput type=rsquohiddenrsquo name=rsquocolorrsquo value=rsquo$details[2]rsquogtnecho ltinput type=rsquohiddenrsquo name=rsquohardnessrsquo value=rsquo$details[3]rsquogtnecho ltinput type=rsquohiddenrsquo name=rsquopricersquo value=rsquo$details[4]rsquogtnecho ltinput type=rsquosubmitrsquo class=rsquobtn btn-defaultrsquo value=rsquoKauf michrsquogtnecho ltformgtnecho lttdgtnecho lttrgtn
gt
And the detail page contains the code fragement mentioned below
ltphp$type=$_GET[rsquotypersquo]$color=$_GET[rsquocolorrsquo]$hardness=$_GET[rsquohardnessrsquo]$options=$_GET[rsquooptionsrsquo]$price=$_GET[rsquopricersquo]echo I am a $type in $color and a hardness of $hardness I have $options as an option and my price is $price CHF
gt
19
Shop Documentation Release 001
Bemerkung The Products page was modified in the process of the development
62 Select options
The signupbilling page contains a dropdown element that all days of a month for the entry of the userrsquos birthday
ltselect name=daygtltoptiongtDayltoptiongt
ltphp$days = range(31 1)foreach ($days as $day)
echo rsquoltoption value=rsquo$dayrsquogtrsquo$dayrsquoltoptiongtrsquo
gtltselectgt
20 Kapitel 6 Input processing
KAPITEL 7
Javascript
Over the years Javascript became a very popular programming language The webshop is using Javascript at a coupleof places
71 Simple use case
Javascript makes it easy to access elements in the DOM Setting the focus is a nice way to support the user with inputform
ltscript language=javascriptgtfunction setFocus()
documentforms[login][username]focus()
ltscriptgtltheadgtltbody onload=setFocus()gt
Another one is to check if something was entered in an input field
function validateForm() var username = documentforms[rdquologinrdquo][rdquousernamerdquo]value if (username== null || username == ldquordquo)
documentforms[rdquologinrdquo][rdquousernamerdquo]stylebackgroundColor = ldquoFF9999rdquo docu-mentforms[rdquologinrdquo][rdquousernamerdquo]placeholder = ldquoPlease your usernamerdquo docu-mentforms[rdquologinrdquo][rdquousernamerdquo]focus() return false
A simple message is informing the user about an action which was taken against the database
echo ltscript type=textjavascriptgtalert(New entry $entry added successfully)windowlocation = tablesphp
ltscriptgt
The delete process is only executed if the user confirm to delete a record
ltform action=scriptsdelete-processphp onSubmit=return confirm(rsquoAre you sure to delete this entryrsquo) method=POSTgtltinput type=hidden name=table value=$sectiongtltinput type=hidden name=id value=$result-gtidgtltinput type=submit name=Submit value=Deletegt
ltformgt
For additional Javascript please check the source of the indexphp file and the reflsquowebservicelsquo_ section
21
Shop Documentation Release 001
22 Kapitel 7 Javascript
KAPITEL 8
Cookies and Sessions
The built-in support for sessions in PHP is handling all cookie manipulation to provide persistent variables that areaccessible from different pages and across multiple visits to the site
81 Cookies
A cookie is used to track the last time a visitor check the front page The cookie is set when a visitor arrives
function lastVisit($name $expire) $value = getDateDMY() - getTimeHM()setcookie($name $value time() + $expire rsquorsquo $_SERVER[rsquoSERVER_NAMErsquo] true true)
In the footer of the index page the details are presented
ltphpif(isset($_COOKIE[rsquoLastVisitrsquo]))
$last = $_COOKIE[rsquoLastVisitrsquo]echo You last visited us on $last
else echo This is your first visit
gt
82 Hit counter
As a simple show case for PHP sessions a hit counter for the front page is available
ltphpsession_start()
$_SESSION[rsquohitsrsquo] = $_SESSION[rsquohitsrsquo] + 1gt
Included in the footer it shous the users the total of visits
echo Total $_SESSION[rsquohitsrsquo] visits of this page
23
Shop Documentation Release 001
83 Language selection
84 User Accounts
24 Kapitel 8 Cookies and Sessions
KAPITEL 9
Database
The database backend for the webshop will be MariaDB which is the drop-in replacement for MySQL
For the setup please check the Development section in this documentation
91 Tables
The following tables are needed for the webshop to work
bull products
bull customers
bull pencils
bull colors
bull hardness
bull options
bull users
Please use the develwebshopsql to setup the database
92 PHP
Below you find the configuration file for a default installation of the webshop This file is a template and filled duringthe setup process
ltphp$host = localhost$user = root$password = webshop$dbase = webshop$connection = new mysqli($host $user $password $dbase)
if ($connection-gtconnect_errno) echo Failed to connect to MariaDBMySQL ($connection-gtconnect_errno) $connection-gtconnect_error
mysqli_report(MYSQLI_REPORT_ERROR)
gt
25
Shop Documentation Release 001
All connections to the database are done in the same way Below you find an example Everything is done in theobject-oriented style
ltphprequire_once(rsquoconfigdbconnectphprsquo)if ($connection-gtconnect_errno == 0)
$sql = SELECT FROM products$results = $connection-gtquery($sql)echo $results-gtnum_rows$results-gtclose()
else echo Database connection error
gt
26 Kapitel 9 Database
KAPITEL 10
Web service
Tow web services are integrated to take advantages of online available data sources
101 Map
Leafletjs a JavaScript library for working with interactive maps from OpenStreetMap (OSM) is implemented as ashow case for a simple web service
The basic steps to integrate a map is shown below
ltdiv id=map class=map style=width 600px height 400pxgtltdivgt
ltscript src=scriptsleafletjsgtltscriptgtltscript src=scriptsleaflet-providersjsgtltscriptgtltscriptgtvar map = Lmap(rsquomaprsquo
center [250472 -773255]zoom 12zoomControl true
)
var defaultLayer = LtileLayerprovider(rsquoOpenStreetMapMapnikrsquo)addTo(map)ltscriptgt
102 Weather
The OpenWeatherMap service provides free weather data and a forecast API for web applications
ltphp Details about the API httpbugsopenweathermaporgprojectsapiwikiApi_2_5_weather$url = rsquohttpapiopenweathermaporgdata25weatherq=Bernechampunit=metricsampmode=jsonrsquo
$json = file_get_contents($url)$data = json_decode($json)
$tempC = round((27315 - $data-gtmain-gttemp)100) 100$humidity = $data-gtmain-gthumidity$pressure = $data-gtmain-gtpressure
27
Shop Documentation Release 001
echo ltpgtTemperatur $tempC degCltbrgtnecho Luftfeuchtigkeit $humidity ltbrgtnecho Luftdruck $pressure Paltpgtn
gt
28 Kapitel 10 Web service
KAPITEL 11
Data export
111 PDF
FPDF is a PHP class that allows to generate PDF files with pure PHP As a showcase for that the product specificationsfor a given product are filled in a pdf and showed in the browser The user can then decide to download or print thefile
112 JSON
JavaScript Object Notation (JSON) is a lightweight data-interchange format The format is language independent andPHP support the encoding and the decoding JSON with json_encode($data) and json_decode($data)$rows = array()$sql = SELECT FROM products$results = $connection-gtquery($sql)while ($result = $results-gtfetch_object())
$rows[] = $result$results-gtclose()
Writing all rows to a JSON file$fp = fopen(rsquopencilsjsonrsquo rsquowrsquo)fwrite($fp json_encode($rows))fclose($fp)gt
and for reading it
ltphp$json = file_get_contents(rsquopencilsjsonrsquo)print_r(json_decode($json))
gt
29
Shop Documentation Release 001
30 Kapitel 11 Data export
KAPITEL 12
Messaging
Beside standard email messages the webshop supports sending MQ Telemetry Transport protocol (MQTT) messagesas an additional feature The MQTT messages are small
121 MQTT
Mosquitto-PHP is used as a PHP wrapper for MQTT Please check the Projectrsquos README for details about theinstallation and the setup
1211 Broker
Mosquitto is a message broker that implements the MQ Telemetry Transport protocol Check if mosquitto is run-ning
$ sudo systemctl status mosquittoservice
If not start it
$ systemctl start mosquittoservice
All messages are published to the topic webshop
1212 Publishing
After the installation of Mosquitto-PHP the snipplet shown below sends a single message
ltphpdefine(rsquoBROKERrsquo rsquolocalhostrsquo)define(rsquoPORTrsquo 1883)define(rsquoCLIENT_IDrsquo webshop_ + getmypid())$topic = webshop$subtopic = test$completeTopic = $topic$subtopic
$client = new MosquittoClient(CLIENT_ID)$client-gtconnect(BROKER PORT 60)
$message = Test message from webshop at date(Y-m-d His)$client-gtpublish($completeTopic $message 0 false)
gt
31
Shop Documentation Release 001
1213 Subscribing
To read the messages sent by the webshop a client is needed The Mosquitto broker contain a simple command-linetool for subscribing to various topics
$ mosquitto_sub -h localhost -t webshop
122 Email
This section doesnrsquot describe the installation and configuration of a local MTA There are enough resources thatcontains information about the setup of postfix for local delivery only
If you want to test the email feature add the following code in one of PHP pages
ltphp mail(rsquorootlocalhostrsquo rsquoTest message from webshoprsquo rsquoThe webshop is selling pencilsrsquo) gt
By default SELinux is running in Enforcing mode which is restrictive about about what a web server can do Toallow sending email the following SELinux boolean needs to changed
setsebool -P httpd_can_network_connect=1 setsebool -P httpd_can_sendmail=1
32 Kapitel 12 Messaging
KAPITEL 13
Localisation (L10n)
There are several ways to add localisation to a web site For small projects arrays with string can work but this is notvery efficient and user-friendly With Gettext is a toolset available that provide a framework to produce multi-lingualcontent in a wide area of programming languages
Make sure that the php-gettext package is available on your system If not install it
$ sudo yum -y install php-php-gettext
Check if gettext support is available
ltphpif (function_exists(gettext))
echo gettext is not installednelse
echo gettext is supportedn
gt
Make sure that all locales your want are available on the server
locale -a
The first step is to mark all string which should be translatable as shown below For further details please refer to theGettext documentation
echo _(rsquoSome textrsquo)
The next step is to extract all strings
xgettext --from-code=UTF-8 -o localewebshoppot php scriptsphp
To re-generate the file after an update join the strings
xgettext -j --from-code=UTF-8 -o localewebshoppot php scriptsphp
For every language a po file is needed for the transations Generate it with the command mentioned below
msginit --no-translator -l de_CH -o localede_CHpo -i localewebshoppot
Once created there are only updates of the message catalog needed in the futures
msgmerge -U localede_CHpo localewebshoppot
If you re finish create the mo file for the specific language
33
Shop Documentation Release 001
msgfmt -c -v -o localede_CHLC_MESSAGESwebshopmo localede_CHpo
34 Kapitel 13 Localisation (L10n)
KAPITEL 14
Templates
Beside other solutions Savant3 is a lightweight object-oriented template system for PHP This solution does not needa lot of additional configuration
141 Template
A simple template file looks like the one shown below
lthtmlgtltheadgt
lttitlegtltphp echo $this-gteprint($this-gttitle) gtlttitlegtltheadgtltbodygt
ltphp echo $this-gteprint($this-gtcontent) gtltbodygt
lthtmlgt
For a more detailed intro check this article on Zend Developer Zone
142 Content
To fill the template with data all wished variables needs to be defined in a seperate PHP file
ltphprequire_once rsquoscriptsSavant3phprsquo$tpl = new Savant3()
Create a title$title = Simple sample page
Create the content of the page$content = Some sample text to show
Assign values to the Savant instance$tpl-gttitle = $title$tpl-gtcontent = $content
Define the template source file to show$tpl-gtdisplay(rsquosimpletplphprsquo)
gt
35
Shop Documentation Release 001
The webshop contains a page (master)
36 Kapitel 14 Templates
KAPITEL 15
Development
This sections describes the configuration of the development and runtime environment for the web shop
151 Web server
Instead of Apache the project is running on Lighttpd The reasons are that Lighttpd provides faster setup easierconfiguration and better performance Lighttpd is running with FastCGI
The path of the web server is varwwwlighttpd and the SELinux configuration are still the defaults
The web server is running in SSL-only mode and the certificate is generated during the server setup process
152 Database server
For persistence storage the drop-in replacement MariaDB is used MySQL will work to but this is not tested phpMyAd-min is available under phpmyadmin on the web server beside the command-line tools for easy administration
The default credentials for phpMyAdmin are rootwebshop or the entry you made in the Ansible playbookdevelvariablessensitiveyml
153 Versions
The web shop is built with the below listed components and tested Other releases can be used and may work but thiswill not be tested Probably it will work with different releases
bull Operating system Fedora 20
bull Kernel 3135-202fc20x86_64
bull Lighttpd 1434
bull PHP 557
bull MariaDB 5534
For communication postfix and mosquitto are needed additionally
37
Shop Documentation Release 001
154 Setup infrastructure
1541 Configuration management
For the creation of reproducable and identical environment for the development and the run-time across differentsystems Ansible is used as configuration management solution All needed steps of the installation are automated Theconfiguration doesnrsquot differentiate between local or remote installations This matters only for the deployment of theweb content
For local development itrsquos possible to use an LX container
$ sudo ansible-playbook develcontaineryml
To get everything running some additional steps (check the network inside the container generate keys etc) areneeded After you are done check it
$ sudo ansible webshop -m setup
From the management system
$ sudo ssh-copy-id -i rootsshid_rsapub root[IP address of your managed node]
The configuration of Ansible itself (adding the system to etcansiblehosts and copying the SSH keys) isnot documented at this place There are various resources available like here All playbooks are located in the folderdevel Start the setup with the command shown below
$ sudo ansible-playbook develsetupyml
The used group name in etcansiblehosts is webshop
If the setup completes without errors then the web server is accessible and show a default page Please keep in mindthat the server is only accessible over https unencrypted traffic is not allowed
1542 DeploymentSetup website
For the simple deployment of the lastest version of the shop a playbook called deployyml is provided Thisplaybook put all files in place
$ sudo ansible-playbook develdeployyml
To full deploy the webshop all tables in the database must exist The file webshopsql contains all needed SQLcommands and sample data for the web application
Itrsquos possible to deploy the website manually but this is not recommended A couple of files are depending on templateswhich are created during the deployment
Itrsquos also not recommanded to clone everything into your webserver root This would save you the trouble of doing itby hand but third-party features are missing then Those missing parts are the template engine the pdf generation theconnection to Openstreetmap and probably other things not mentioned here
155 Git respository
All project relevante informations (Source code templates documentation etc) is located in a public Git repositoryon Github
38 Kapitel 15 Development
Shop Documentation Release 001
156 Documentation
The documentation is using reStructuredText as markup language For a local build Sphinx is needed Sphinx isavailable in the Fedora Package Collection and can be installed with yum or any other package management tool
yum -y install python-sphinx python-docutils
The source files of the documentation are located under docs
$ cd docs$ make html
The output is stored under docs_buildhtml
After every push to Github a hook launch a rebuild of the documentation The latest release will be published on Readthe Docs automatically
httpsshoprtfdorg
156 Documentation 39
Shop Documentation Release 001
40 Kapitel 15 Development
KAPITEL 16
Indices and tables
bull genindex
bull modindex
bull search
41
- Basics
-
- Products
- Personas
- Use cases
- Design principles
-
- Web shop Design
-
- General
- Layout
- Sitemap
- Main page
-
- Style and design
-
- Cascading Style Sheets
- Pages
-
- Dynamics
-
- Setup
- Current year
- Navigation Menu
- List of Products
- Company details
-
- External files
-
- Navigation Menu
- Header
- Footer
-
- Input processing
-
- ``Buy Now links
- Select options
-
- Javascript
-
- Simple use case
-
- Cookies and Sessions
-
- Cookies
- Hit counter
- Language selection
- User Accounts
-
- Database
-
- Tables
- PHP
-
- Web service
-
- Map
- Weather
-
- Data export
-
- JSON
-
- Messaging
-
- MQTT
-
- Localisation (L10n)
- Templates
-
- Template
- Content
-
- Development
-
- Web server
- Database server
- Versions
- Setup infrastructure
- Git respository
- Documentation
-
- Indices and tables
-
Shop Documentation Release 001
45 Company details
The data for the About page are included out of a static and plain text file
ltphp$str = file_get_contents(companytxt)echo $str
gt
45 Company details 15
Shop Documentation Release 001
16 Kapitel 4 Dynamics
KAPITEL 5
External files
51 Navigation Menu
The menu is outsourced in the file menuphp
ltphpfunction menu()
$part1 = rsquoltul class=nav nav-tabsgtrsquon$part2 = rsquorsquo$part3 = rsquoltulgtrsquon Menu array with page title and assigned file$menu = array(rsquoHomersquo =gt rsquoindexphprsquo
rsquoProduktersquo =gt rsquoproductsphprsquorsquoUumlber unsrsquo =gt rsquoaboutphprsquo
)foreach ($menu as $label =gt $link)
For the CSS only the file name without is needed$url = trim($_SERVER[rsquoPHP_SELFrsquo] rsquorsquo)if ($link == $url)
$part2 = $part2ltli class=rsquoactiversquogtlta href=rsquo$linkrsquogt$labelltagtltligtn else
$part2 = $part2ltli class=rsquorsquogtlta href=rsquo$linkrsquogt$labelltagtltligtn
return $part1$part2$part3
gt
52 Header
The complete header part is loaded from the file headerphp
ltphpfunction head()
$start_page = indexphp$part1 = ltdivgtn$part2 = tlta class=rsquobrand-logorsquo href=rsquo$start_pagersquogtltagtn$part3 = tltp class=rsquobrand-namersquogtWebshop Pencil AGltpgtn$part4 = ltdivgtnreturn $part1$part2$part3$part4
17
Shop Documentation Release 001
gt
53 Footer
The same is done witht the page footers
ltphpfunction foot()
$class1 = rsquoltdiv class=footergtrsquon$class2 = rsquoltdivgtrsquon$text = ltpgtampcopy Pencil AG getYear()rsquoltpgtrsquonreturn $class1$text$class2
function getYear()return date(Y)
gt
18 Kapitel 5 External files
KAPITEL 6
Input processing
61 ldquoBuy Nowrdquo links
The ldquoBuy Nowrdquo links are attached to the Products page Every entry has itrsquos own link which lead to a detail page Thelinks are using hidden form elements to transfer the data
ltphp$products = array(array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquoHBrsquo rsquo1rsquo)
array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquoBrsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquo2Brsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquoFrsquo rsquo12rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquoHrsquo rsquo12rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquo2Hrsquo rsquo12rsquo)
)foreach ($products as $product =gt $details)
echo lttrgtnforeach ($details as $detail)
echo lttdgt$detaillttdgtnecho lttdgtnecho ltform action=rsquoproductphprsquo method=rsquogetrsquo name=rsquopencilrsquogtnecho ltinput type=rsquohiddenrsquo name=rsquotypersquo value=rsquo$details[0]rsquogtnecho ltinput type=rsquohiddenrsquo name=rsquooptionsrsquo value=rsquo$details[1]rsquogtnecho ltinput type=rsquohiddenrsquo name=rsquocolorrsquo value=rsquo$details[2]rsquogtnecho ltinput type=rsquohiddenrsquo name=rsquohardnessrsquo value=rsquo$details[3]rsquogtnecho ltinput type=rsquohiddenrsquo name=rsquopricersquo value=rsquo$details[4]rsquogtnecho ltinput type=rsquosubmitrsquo class=rsquobtn btn-defaultrsquo value=rsquoKauf michrsquogtnecho ltformgtnecho lttdgtnecho lttrgtn
gt
And the detail page contains the code fragement mentioned below
ltphp$type=$_GET[rsquotypersquo]$color=$_GET[rsquocolorrsquo]$hardness=$_GET[rsquohardnessrsquo]$options=$_GET[rsquooptionsrsquo]$price=$_GET[rsquopricersquo]echo I am a $type in $color and a hardness of $hardness I have $options as an option and my price is $price CHF
gt
19
Shop Documentation Release 001
Bemerkung The Products page was modified in the process of the development
62 Select options
The signupbilling page contains a dropdown element that all days of a month for the entry of the userrsquos birthday
ltselect name=daygtltoptiongtDayltoptiongt
ltphp$days = range(31 1)foreach ($days as $day)
echo rsquoltoption value=rsquo$dayrsquogtrsquo$dayrsquoltoptiongtrsquo
gtltselectgt
20 Kapitel 6 Input processing
KAPITEL 7
Javascript
Over the years Javascript became a very popular programming language The webshop is using Javascript at a coupleof places
71 Simple use case
Javascript makes it easy to access elements in the DOM Setting the focus is a nice way to support the user with inputform
ltscript language=javascriptgtfunction setFocus()
documentforms[login][username]focus()
ltscriptgtltheadgtltbody onload=setFocus()gt
Another one is to check if something was entered in an input field
function validateForm() var username = documentforms[rdquologinrdquo][rdquousernamerdquo]value if (username== null || username == ldquordquo)
documentforms[rdquologinrdquo][rdquousernamerdquo]stylebackgroundColor = ldquoFF9999rdquo docu-mentforms[rdquologinrdquo][rdquousernamerdquo]placeholder = ldquoPlease your usernamerdquo docu-mentforms[rdquologinrdquo][rdquousernamerdquo]focus() return false
A simple message is informing the user about an action which was taken against the database
echo ltscript type=textjavascriptgtalert(New entry $entry added successfully)windowlocation = tablesphp
ltscriptgt
The delete process is only executed if the user confirm to delete a record
ltform action=scriptsdelete-processphp onSubmit=return confirm(rsquoAre you sure to delete this entryrsquo) method=POSTgtltinput type=hidden name=table value=$sectiongtltinput type=hidden name=id value=$result-gtidgtltinput type=submit name=Submit value=Deletegt
ltformgt
For additional Javascript please check the source of the indexphp file and the reflsquowebservicelsquo_ section
21
Shop Documentation Release 001
22 Kapitel 7 Javascript
KAPITEL 8
Cookies and Sessions
The built-in support for sessions in PHP is handling all cookie manipulation to provide persistent variables that areaccessible from different pages and across multiple visits to the site
81 Cookies
A cookie is used to track the last time a visitor check the front page The cookie is set when a visitor arrives
function lastVisit($name $expire) $value = getDateDMY() - getTimeHM()setcookie($name $value time() + $expire rsquorsquo $_SERVER[rsquoSERVER_NAMErsquo] true true)
In the footer of the index page the details are presented
ltphpif(isset($_COOKIE[rsquoLastVisitrsquo]))
$last = $_COOKIE[rsquoLastVisitrsquo]echo You last visited us on $last
else echo This is your first visit
gt
82 Hit counter
As a simple show case for PHP sessions a hit counter for the front page is available
ltphpsession_start()
$_SESSION[rsquohitsrsquo] = $_SESSION[rsquohitsrsquo] + 1gt
Included in the footer it shous the users the total of visits
echo Total $_SESSION[rsquohitsrsquo] visits of this page
23
Shop Documentation Release 001
83 Language selection
84 User Accounts
24 Kapitel 8 Cookies and Sessions
KAPITEL 9
Database
The database backend for the webshop will be MariaDB which is the drop-in replacement for MySQL
For the setup please check the Development section in this documentation
91 Tables
The following tables are needed for the webshop to work
bull products
bull customers
bull pencils
bull colors
bull hardness
bull options
bull users
Please use the develwebshopsql to setup the database
92 PHP
Below you find the configuration file for a default installation of the webshop This file is a template and filled duringthe setup process
ltphp$host = localhost$user = root$password = webshop$dbase = webshop$connection = new mysqli($host $user $password $dbase)
if ($connection-gtconnect_errno) echo Failed to connect to MariaDBMySQL ($connection-gtconnect_errno) $connection-gtconnect_error
mysqli_report(MYSQLI_REPORT_ERROR)
gt
25
Shop Documentation Release 001
All connections to the database are done in the same way Below you find an example Everything is done in theobject-oriented style
ltphprequire_once(rsquoconfigdbconnectphprsquo)if ($connection-gtconnect_errno == 0)
$sql = SELECT FROM products$results = $connection-gtquery($sql)echo $results-gtnum_rows$results-gtclose()
else echo Database connection error
gt
26 Kapitel 9 Database
KAPITEL 10
Web service
Tow web services are integrated to take advantages of online available data sources
101 Map
Leafletjs a JavaScript library for working with interactive maps from OpenStreetMap (OSM) is implemented as ashow case for a simple web service
The basic steps to integrate a map is shown below
ltdiv id=map class=map style=width 600px height 400pxgtltdivgt
ltscript src=scriptsleafletjsgtltscriptgtltscript src=scriptsleaflet-providersjsgtltscriptgtltscriptgtvar map = Lmap(rsquomaprsquo
center [250472 -773255]zoom 12zoomControl true
)
var defaultLayer = LtileLayerprovider(rsquoOpenStreetMapMapnikrsquo)addTo(map)ltscriptgt
102 Weather
The OpenWeatherMap service provides free weather data and a forecast API for web applications
ltphp Details about the API httpbugsopenweathermaporgprojectsapiwikiApi_2_5_weather$url = rsquohttpapiopenweathermaporgdata25weatherq=Bernechampunit=metricsampmode=jsonrsquo
$json = file_get_contents($url)$data = json_decode($json)
$tempC = round((27315 - $data-gtmain-gttemp)100) 100$humidity = $data-gtmain-gthumidity$pressure = $data-gtmain-gtpressure
27
Shop Documentation Release 001
echo ltpgtTemperatur $tempC degCltbrgtnecho Luftfeuchtigkeit $humidity ltbrgtnecho Luftdruck $pressure Paltpgtn
gt
28 Kapitel 10 Web service
KAPITEL 11
Data export
111 PDF
FPDF is a PHP class that allows to generate PDF files with pure PHP As a showcase for that the product specificationsfor a given product are filled in a pdf and showed in the browser The user can then decide to download or print thefile
112 JSON
JavaScript Object Notation (JSON) is a lightweight data-interchange format The format is language independent andPHP support the encoding and the decoding JSON with json_encode($data) and json_decode($data)$rows = array()$sql = SELECT FROM products$results = $connection-gtquery($sql)while ($result = $results-gtfetch_object())
$rows[] = $result$results-gtclose()
Writing all rows to a JSON file$fp = fopen(rsquopencilsjsonrsquo rsquowrsquo)fwrite($fp json_encode($rows))fclose($fp)gt
and for reading it
ltphp$json = file_get_contents(rsquopencilsjsonrsquo)print_r(json_decode($json))
gt
29
Shop Documentation Release 001
30 Kapitel 11 Data export
KAPITEL 12
Messaging
Beside standard email messages the webshop supports sending MQ Telemetry Transport protocol (MQTT) messagesas an additional feature The MQTT messages are small
121 MQTT
Mosquitto-PHP is used as a PHP wrapper for MQTT Please check the Projectrsquos README for details about theinstallation and the setup
1211 Broker
Mosquitto is a message broker that implements the MQ Telemetry Transport protocol Check if mosquitto is run-ning
$ sudo systemctl status mosquittoservice
If not start it
$ systemctl start mosquittoservice
All messages are published to the topic webshop
1212 Publishing
After the installation of Mosquitto-PHP the snipplet shown below sends a single message
ltphpdefine(rsquoBROKERrsquo rsquolocalhostrsquo)define(rsquoPORTrsquo 1883)define(rsquoCLIENT_IDrsquo webshop_ + getmypid())$topic = webshop$subtopic = test$completeTopic = $topic$subtopic
$client = new MosquittoClient(CLIENT_ID)$client-gtconnect(BROKER PORT 60)
$message = Test message from webshop at date(Y-m-d His)$client-gtpublish($completeTopic $message 0 false)
gt
31
Shop Documentation Release 001
1213 Subscribing
To read the messages sent by the webshop a client is needed The Mosquitto broker contain a simple command-linetool for subscribing to various topics
$ mosquitto_sub -h localhost -t webshop
122 Email
This section doesnrsquot describe the installation and configuration of a local MTA There are enough resources thatcontains information about the setup of postfix for local delivery only
If you want to test the email feature add the following code in one of PHP pages
ltphp mail(rsquorootlocalhostrsquo rsquoTest message from webshoprsquo rsquoThe webshop is selling pencilsrsquo) gt
By default SELinux is running in Enforcing mode which is restrictive about about what a web server can do Toallow sending email the following SELinux boolean needs to changed
setsebool -P httpd_can_network_connect=1 setsebool -P httpd_can_sendmail=1
32 Kapitel 12 Messaging
KAPITEL 13
Localisation (L10n)
There are several ways to add localisation to a web site For small projects arrays with string can work but this is notvery efficient and user-friendly With Gettext is a toolset available that provide a framework to produce multi-lingualcontent in a wide area of programming languages
Make sure that the php-gettext package is available on your system If not install it
$ sudo yum -y install php-php-gettext
Check if gettext support is available
ltphpif (function_exists(gettext))
echo gettext is not installednelse
echo gettext is supportedn
gt
Make sure that all locales your want are available on the server
locale -a
The first step is to mark all string which should be translatable as shown below For further details please refer to theGettext documentation
echo _(rsquoSome textrsquo)
The next step is to extract all strings
xgettext --from-code=UTF-8 -o localewebshoppot php scriptsphp
To re-generate the file after an update join the strings
xgettext -j --from-code=UTF-8 -o localewebshoppot php scriptsphp
For every language a po file is needed for the transations Generate it with the command mentioned below
msginit --no-translator -l de_CH -o localede_CHpo -i localewebshoppot
Once created there are only updates of the message catalog needed in the futures
msgmerge -U localede_CHpo localewebshoppot
If you re finish create the mo file for the specific language
33
Shop Documentation Release 001
msgfmt -c -v -o localede_CHLC_MESSAGESwebshopmo localede_CHpo
34 Kapitel 13 Localisation (L10n)
KAPITEL 14
Templates
Beside other solutions Savant3 is a lightweight object-oriented template system for PHP This solution does not needa lot of additional configuration
141 Template
A simple template file looks like the one shown below
lthtmlgtltheadgt
lttitlegtltphp echo $this-gteprint($this-gttitle) gtlttitlegtltheadgtltbodygt
ltphp echo $this-gteprint($this-gtcontent) gtltbodygt
lthtmlgt
For a more detailed intro check this article on Zend Developer Zone
142 Content
To fill the template with data all wished variables needs to be defined in a seperate PHP file
ltphprequire_once rsquoscriptsSavant3phprsquo$tpl = new Savant3()
Create a title$title = Simple sample page
Create the content of the page$content = Some sample text to show
Assign values to the Savant instance$tpl-gttitle = $title$tpl-gtcontent = $content
Define the template source file to show$tpl-gtdisplay(rsquosimpletplphprsquo)
gt
35
Shop Documentation Release 001
The webshop contains a page (master)
36 Kapitel 14 Templates
KAPITEL 15
Development
This sections describes the configuration of the development and runtime environment for the web shop
151 Web server
Instead of Apache the project is running on Lighttpd The reasons are that Lighttpd provides faster setup easierconfiguration and better performance Lighttpd is running with FastCGI
The path of the web server is varwwwlighttpd and the SELinux configuration are still the defaults
The web server is running in SSL-only mode and the certificate is generated during the server setup process
152 Database server
For persistence storage the drop-in replacement MariaDB is used MySQL will work to but this is not tested phpMyAd-min is available under phpmyadmin on the web server beside the command-line tools for easy administration
The default credentials for phpMyAdmin are rootwebshop or the entry you made in the Ansible playbookdevelvariablessensitiveyml
153 Versions
The web shop is built with the below listed components and tested Other releases can be used and may work but thiswill not be tested Probably it will work with different releases
bull Operating system Fedora 20
bull Kernel 3135-202fc20x86_64
bull Lighttpd 1434
bull PHP 557
bull MariaDB 5534
For communication postfix and mosquitto are needed additionally
37
Shop Documentation Release 001
154 Setup infrastructure
1541 Configuration management
For the creation of reproducable and identical environment for the development and the run-time across differentsystems Ansible is used as configuration management solution All needed steps of the installation are automated Theconfiguration doesnrsquot differentiate between local or remote installations This matters only for the deployment of theweb content
For local development itrsquos possible to use an LX container
$ sudo ansible-playbook develcontaineryml
To get everything running some additional steps (check the network inside the container generate keys etc) areneeded After you are done check it
$ sudo ansible webshop -m setup
From the management system
$ sudo ssh-copy-id -i rootsshid_rsapub root[IP address of your managed node]
The configuration of Ansible itself (adding the system to etcansiblehosts and copying the SSH keys) isnot documented at this place There are various resources available like here All playbooks are located in the folderdevel Start the setup with the command shown below
$ sudo ansible-playbook develsetupyml
The used group name in etcansiblehosts is webshop
If the setup completes without errors then the web server is accessible and show a default page Please keep in mindthat the server is only accessible over https unencrypted traffic is not allowed
1542 DeploymentSetup website
For the simple deployment of the lastest version of the shop a playbook called deployyml is provided Thisplaybook put all files in place
$ sudo ansible-playbook develdeployyml
To full deploy the webshop all tables in the database must exist The file webshopsql contains all needed SQLcommands and sample data for the web application
Itrsquos possible to deploy the website manually but this is not recommended A couple of files are depending on templateswhich are created during the deployment
Itrsquos also not recommanded to clone everything into your webserver root This would save you the trouble of doing itby hand but third-party features are missing then Those missing parts are the template engine the pdf generation theconnection to Openstreetmap and probably other things not mentioned here
155 Git respository
All project relevante informations (Source code templates documentation etc) is located in a public Git repositoryon Github
38 Kapitel 15 Development
Shop Documentation Release 001
156 Documentation
The documentation is using reStructuredText as markup language For a local build Sphinx is needed Sphinx isavailable in the Fedora Package Collection and can be installed with yum or any other package management tool
yum -y install python-sphinx python-docutils
The source files of the documentation are located under docs
$ cd docs$ make html
The output is stored under docs_buildhtml
After every push to Github a hook launch a rebuild of the documentation The latest release will be published on Readthe Docs automatically
httpsshoprtfdorg
156 Documentation 39
Shop Documentation Release 001
40 Kapitel 15 Development
KAPITEL 16
Indices and tables
bull genindex
bull modindex
bull search
41
- Basics
-
- Products
- Personas
- Use cases
- Design principles
-
- Web shop Design
-
- General
- Layout
- Sitemap
- Main page
-
- Style and design
-
- Cascading Style Sheets
- Pages
-
- Dynamics
-
- Setup
- Current year
- Navigation Menu
- List of Products
- Company details
-
- External files
-
- Navigation Menu
- Header
- Footer
-
- Input processing
-
- ``Buy Now links
- Select options
-
- Javascript
-
- Simple use case
-
- Cookies and Sessions
-
- Cookies
- Hit counter
- Language selection
- User Accounts
-
- Database
-
- Tables
- PHP
-
- Web service
-
- Map
- Weather
-
- Data export
-
- JSON
-
- Messaging
-
- MQTT
-
- Localisation (L10n)
- Templates
-
- Template
- Content
-
- Development
-
- Web server
- Database server
- Versions
- Setup infrastructure
- Git respository
- Documentation
-
- Indices and tables
-
Shop Documentation Release 001
16 Kapitel 4 Dynamics
KAPITEL 5
External files
51 Navigation Menu
The menu is outsourced in the file menuphp
ltphpfunction menu()
$part1 = rsquoltul class=nav nav-tabsgtrsquon$part2 = rsquorsquo$part3 = rsquoltulgtrsquon Menu array with page title and assigned file$menu = array(rsquoHomersquo =gt rsquoindexphprsquo
rsquoProduktersquo =gt rsquoproductsphprsquorsquoUumlber unsrsquo =gt rsquoaboutphprsquo
)foreach ($menu as $label =gt $link)
For the CSS only the file name without is needed$url = trim($_SERVER[rsquoPHP_SELFrsquo] rsquorsquo)if ($link == $url)
$part2 = $part2ltli class=rsquoactiversquogtlta href=rsquo$linkrsquogt$labelltagtltligtn else
$part2 = $part2ltli class=rsquorsquogtlta href=rsquo$linkrsquogt$labelltagtltligtn
return $part1$part2$part3
gt
52 Header
The complete header part is loaded from the file headerphp
ltphpfunction head()
$start_page = indexphp$part1 = ltdivgtn$part2 = tlta class=rsquobrand-logorsquo href=rsquo$start_pagersquogtltagtn$part3 = tltp class=rsquobrand-namersquogtWebshop Pencil AGltpgtn$part4 = ltdivgtnreturn $part1$part2$part3$part4
17
Shop Documentation Release 001
gt
53 Footer
The same is done witht the page footers
ltphpfunction foot()
$class1 = rsquoltdiv class=footergtrsquon$class2 = rsquoltdivgtrsquon$text = ltpgtampcopy Pencil AG getYear()rsquoltpgtrsquonreturn $class1$text$class2
function getYear()return date(Y)
gt
18 Kapitel 5 External files
KAPITEL 6
Input processing
61 ldquoBuy Nowrdquo links
The ldquoBuy Nowrdquo links are attached to the Products page Every entry has itrsquos own link which lead to a detail page Thelinks are using hidden form elements to transfer the data
ltphp$products = array(array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquoHBrsquo rsquo1rsquo)
array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquoBrsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquo2Brsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquoFrsquo rsquo12rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquoHrsquo rsquo12rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquo2Hrsquo rsquo12rsquo)
)foreach ($products as $product =gt $details)
echo lttrgtnforeach ($details as $detail)
echo lttdgt$detaillttdgtnecho lttdgtnecho ltform action=rsquoproductphprsquo method=rsquogetrsquo name=rsquopencilrsquogtnecho ltinput type=rsquohiddenrsquo name=rsquotypersquo value=rsquo$details[0]rsquogtnecho ltinput type=rsquohiddenrsquo name=rsquooptionsrsquo value=rsquo$details[1]rsquogtnecho ltinput type=rsquohiddenrsquo name=rsquocolorrsquo value=rsquo$details[2]rsquogtnecho ltinput type=rsquohiddenrsquo name=rsquohardnessrsquo value=rsquo$details[3]rsquogtnecho ltinput type=rsquohiddenrsquo name=rsquopricersquo value=rsquo$details[4]rsquogtnecho ltinput type=rsquosubmitrsquo class=rsquobtn btn-defaultrsquo value=rsquoKauf michrsquogtnecho ltformgtnecho lttdgtnecho lttrgtn
gt
And the detail page contains the code fragement mentioned below
ltphp$type=$_GET[rsquotypersquo]$color=$_GET[rsquocolorrsquo]$hardness=$_GET[rsquohardnessrsquo]$options=$_GET[rsquooptionsrsquo]$price=$_GET[rsquopricersquo]echo I am a $type in $color and a hardness of $hardness I have $options as an option and my price is $price CHF
gt
19
Shop Documentation Release 001
Bemerkung The Products page was modified in the process of the development
62 Select options
The signupbilling page contains a dropdown element that all days of a month for the entry of the userrsquos birthday
ltselect name=daygtltoptiongtDayltoptiongt
ltphp$days = range(31 1)foreach ($days as $day)
echo rsquoltoption value=rsquo$dayrsquogtrsquo$dayrsquoltoptiongtrsquo
gtltselectgt
20 Kapitel 6 Input processing
KAPITEL 7
Javascript
Over the years Javascript became a very popular programming language The webshop is using Javascript at a coupleof places
71 Simple use case
Javascript makes it easy to access elements in the DOM Setting the focus is a nice way to support the user with inputform
ltscript language=javascriptgtfunction setFocus()
documentforms[login][username]focus()
ltscriptgtltheadgtltbody onload=setFocus()gt
Another one is to check if something was entered in an input field
function validateForm() var username = documentforms[rdquologinrdquo][rdquousernamerdquo]value if (username== null || username == ldquordquo)
documentforms[rdquologinrdquo][rdquousernamerdquo]stylebackgroundColor = ldquoFF9999rdquo docu-mentforms[rdquologinrdquo][rdquousernamerdquo]placeholder = ldquoPlease your usernamerdquo docu-mentforms[rdquologinrdquo][rdquousernamerdquo]focus() return false
A simple message is informing the user about an action which was taken against the database
echo ltscript type=textjavascriptgtalert(New entry $entry added successfully)windowlocation = tablesphp
ltscriptgt
The delete process is only executed if the user confirm to delete a record
ltform action=scriptsdelete-processphp onSubmit=return confirm(rsquoAre you sure to delete this entryrsquo) method=POSTgtltinput type=hidden name=table value=$sectiongtltinput type=hidden name=id value=$result-gtidgtltinput type=submit name=Submit value=Deletegt
ltformgt
For additional Javascript please check the source of the indexphp file and the reflsquowebservicelsquo_ section
21
Shop Documentation Release 001
22 Kapitel 7 Javascript
KAPITEL 8
Cookies and Sessions
The built-in support for sessions in PHP is handling all cookie manipulation to provide persistent variables that areaccessible from different pages and across multiple visits to the site
81 Cookies
A cookie is used to track the last time a visitor check the front page The cookie is set when a visitor arrives
function lastVisit($name $expire) $value = getDateDMY() - getTimeHM()setcookie($name $value time() + $expire rsquorsquo $_SERVER[rsquoSERVER_NAMErsquo] true true)
In the footer of the index page the details are presented
ltphpif(isset($_COOKIE[rsquoLastVisitrsquo]))
$last = $_COOKIE[rsquoLastVisitrsquo]echo You last visited us on $last
else echo This is your first visit
gt
82 Hit counter
As a simple show case for PHP sessions a hit counter for the front page is available
ltphpsession_start()
$_SESSION[rsquohitsrsquo] = $_SESSION[rsquohitsrsquo] + 1gt
Included in the footer it shous the users the total of visits
echo Total $_SESSION[rsquohitsrsquo] visits of this page
23
Shop Documentation Release 001
83 Language selection
84 User Accounts
24 Kapitel 8 Cookies and Sessions
KAPITEL 9
Database
The database backend for the webshop will be MariaDB which is the drop-in replacement for MySQL
For the setup please check the Development section in this documentation
91 Tables
The following tables are needed for the webshop to work
bull products
bull customers
bull pencils
bull colors
bull hardness
bull options
bull users
Please use the develwebshopsql to setup the database
92 PHP
Below you find the configuration file for a default installation of the webshop This file is a template and filled duringthe setup process
ltphp$host = localhost$user = root$password = webshop$dbase = webshop$connection = new mysqli($host $user $password $dbase)
if ($connection-gtconnect_errno) echo Failed to connect to MariaDBMySQL ($connection-gtconnect_errno) $connection-gtconnect_error
mysqli_report(MYSQLI_REPORT_ERROR)
gt
25
Shop Documentation Release 001
All connections to the database are done in the same way Below you find an example Everything is done in theobject-oriented style
ltphprequire_once(rsquoconfigdbconnectphprsquo)if ($connection-gtconnect_errno == 0)
$sql = SELECT FROM products$results = $connection-gtquery($sql)echo $results-gtnum_rows$results-gtclose()
else echo Database connection error
gt
26 Kapitel 9 Database
KAPITEL 10
Web service
Tow web services are integrated to take advantages of online available data sources
101 Map
Leafletjs a JavaScript library for working with interactive maps from OpenStreetMap (OSM) is implemented as ashow case for a simple web service
The basic steps to integrate a map is shown below
ltdiv id=map class=map style=width 600px height 400pxgtltdivgt
ltscript src=scriptsleafletjsgtltscriptgtltscript src=scriptsleaflet-providersjsgtltscriptgtltscriptgtvar map = Lmap(rsquomaprsquo
center [250472 -773255]zoom 12zoomControl true
)
var defaultLayer = LtileLayerprovider(rsquoOpenStreetMapMapnikrsquo)addTo(map)ltscriptgt
102 Weather
The OpenWeatherMap service provides free weather data and a forecast API for web applications
ltphp Details about the API httpbugsopenweathermaporgprojectsapiwikiApi_2_5_weather$url = rsquohttpapiopenweathermaporgdata25weatherq=Bernechampunit=metricsampmode=jsonrsquo
$json = file_get_contents($url)$data = json_decode($json)
$tempC = round((27315 - $data-gtmain-gttemp)100) 100$humidity = $data-gtmain-gthumidity$pressure = $data-gtmain-gtpressure
27
Shop Documentation Release 001
echo ltpgtTemperatur $tempC degCltbrgtnecho Luftfeuchtigkeit $humidity ltbrgtnecho Luftdruck $pressure Paltpgtn
gt
28 Kapitel 10 Web service
KAPITEL 11
Data export
111 PDF
FPDF is a PHP class that allows to generate PDF files with pure PHP As a showcase for that the product specificationsfor a given product are filled in a pdf and showed in the browser The user can then decide to download or print thefile
112 JSON
JavaScript Object Notation (JSON) is a lightweight data-interchange format The format is language independent andPHP support the encoding and the decoding JSON with json_encode($data) and json_decode($data)$rows = array()$sql = SELECT FROM products$results = $connection-gtquery($sql)while ($result = $results-gtfetch_object())
$rows[] = $result$results-gtclose()
Writing all rows to a JSON file$fp = fopen(rsquopencilsjsonrsquo rsquowrsquo)fwrite($fp json_encode($rows))fclose($fp)gt
and for reading it
ltphp$json = file_get_contents(rsquopencilsjsonrsquo)print_r(json_decode($json))
gt
29
Shop Documentation Release 001
30 Kapitel 11 Data export
KAPITEL 12
Messaging
Beside standard email messages the webshop supports sending MQ Telemetry Transport protocol (MQTT) messagesas an additional feature The MQTT messages are small
121 MQTT
Mosquitto-PHP is used as a PHP wrapper for MQTT Please check the Projectrsquos README for details about theinstallation and the setup
1211 Broker
Mosquitto is a message broker that implements the MQ Telemetry Transport protocol Check if mosquitto is run-ning
$ sudo systemctl status mosquittoservice
If not start it
$ systemctl start mosquittoservice
All messages are published to the topic webshop
1212 Publishing
After the installation of Mosquitto-PHP the snipplet shown below sends a single message
ltphpdefine(rsquoBROKERrsquo rsquolocalhostrsquo)define(rsquoPORTrsquo 1883)define(rsquoCLIENT_IDrsquo webshop_ + getmypid())$topic = webshop$subtopic = test$completeTopic = $topic$subtopic
$client = new MosquittoClient(CLIENT_ID)$client-gtconnect(BROKER PORT 60)
$message = Test message from webshop at date(Y-m-d His)$client-gtpublish($completeTopic $message 0 false)
gt
31
Shop Documentation Release 001
1213 Subscribing
To read the messages sent by the webshop a client is needed The Mosquitto broker contain a simple command-linetool for subscribing to various topics
$ mosquitto_sub -h localhost -t webshop
122 Email
This section doesnrsquot describe the installation and configuration of a local MTA There are enough resources thatcontains information about the setup of postfix for local delivery only
If you want to test the email feature add the following code in one of PHP pages
ltphp mail(rsquorootlocalhostrsquo rsquoTest message from webshoprsquo rsquoThe webshop is selling pencilsrsquo) gt
By default SELinux is running in Enforcing mode which is restrictive about about what a web server can do Toallow sending email the following SELinux boolean needs to changed
setsebool -P httpd_can_network_connect=1 setsebool -P httpd_can_sendmail=1
32 Kapitel 12 Messaging
KAPITEL 13
Localisation (L10n)
There are several ways to add localisation to a web site For small projects arrays with string can work but this is notvery efficient and user-friendly With Gettext is a toolset available that provide a framework to produce multi-lingualcontent in a wide area of programming languages
Make sure that the php-gettext package is available on your system If not install it
$ sudo yum -y install php-php-gettext
Check if gettext support is available
ltphpif (function_exists(gettext))
echo gettext is not installednelse
echo gettext is supportedn
gt
Make sure that all locales your want are available on the server
locale -a
The first step is to mark all string which should be translatable as shown below For further details please refer to theGettext documentation
echo _(rsquoSome textrsquo)
The next step is to extract all strings
xgettext --from-code=UTF-8 -o localewebshoppot php scriptsphp
To re-generate the file after an update join the strings
xgettext -j --from-code=UTF-8 -o localewebshoppot php scriptsphp
For every language a po file is needed for the transations Generate it with the command mentioned below
msginit --no-translator -l de_CH -o localede_CHpo -i localewebshoppot
Once created there are only updates of the message catalog needed in the futures
msgmerge -U localede_CHpo localewebshoppot
If you re finish create the mo file for the specific language
33
Shop Documentation Release 001
msgfmt -c -v -o localede_CHLC_MESSAGESwebshopmo localede_CHpo
34 Kapitel 13 Localisation (L10n)
KAPITEL 14
Templates
Beside other solutions Savant3 is a lightweight object-oriented template system for PHP This solution does not needa lot of additional configuration
141 Template
A simple template file looks like the one shown below
lthtmlgtltheadgt
lttitlegtltphp echo $this-gteprint($this-gttitle) gtlttitlegtltheadgtltbodygt
ltphp echo $this-gteprint($this-gtcontent) gtltbodygt
lthtmlgt
For a more detailed intro check this article on Zend Developer Zone
142 Content
To fill the template with data all wished variables needs to be defined in a seperate PHP file
ltphprequire_once rsquoscriptsSavant3phprsquo$tpl = new Savant3()
Create a title$title = Simple sample page
Create the content of the page$content = Some sample text to show
Assign values to the Savant instance$tpl-gttitle = $title$tpl-gtcontent = $content
Define the template source file to show$tpl-gtdisplay(rsquosimpletplphprsquo)
gt
35
Shop Documentation Release 001
The webshop contains a page (master)
36 Kapitel 14 Templates
KAPITEL 15
Development
This sections describes the configuration of the development and runtime environment for the web shop
151 Web server
Instead of Apache the project is running on Lighttpd The reasons are that Lighttpd provides faster setup easierconfiguration and better performance Lighttpd is running with FastCGI
The path of the web server is varwwwlighttpd and the SELinux configuration are still the defaults
The web server is running in SSL-only mode and the certificate is generated during the server setup process
152 Database server
For persistence storage the drop-in replacement MariaDB is used MySQL will work to but this is not tested phpMyAd-min is available under phpmyadmin on the web server beside the command-line tools for easy administration
The default credentials for phpMyAdmin are rootwebshop or the entry you made in the Ansible playbookdevelvariablessensitiveyml
153 Versions
The web shop is built with the below listed components and tested Other releases can be used and may work but thiswill not be tested Probably it will work with different releases
bull Operating system Fedora 20
bull Kernel 3135-202fc20x86_64
bull Lighttpd 1434
bull PHP 557
bull MariaDB 5534
For communication postfix and mosquitto are needed additionally
37
Shop Documentation Release 001
154 Setup infrastructure
1541 Configuration management
For the creation of reproducable and identical environment for the development and the run-time across differentsystems Ansible is used as configuration management solution All needed steps of the installation are automated Theconfiguration doesnrsquot differentiate between local or remote installations This matters only for the deployment of theweb content
For local development itrsquos possible to use an LX container
$ sudo ansible-playbook develcontaineryml
To get everything running some additional steps (check the network inside the container generate keys etc) areneeded After you are done check it
$ sudo ansible webshop -m setup
From the management system
$ sudo ssh-copy-id -i rootsshid_rsapub root[IP address of your managed node]
The configuration of Ansible itself (adding the system to etcansiblehosts and copying the SSH keys) isnot documented at this place There are various resources available like here All playbooks are located in the folderdevel Start the setup with the command shown below
$ sudo ansible-playbook develsetupyml
The used group name in etcansiblehosts is webshop
If the setup completes without errors then the web server is accessible and show a default page Please keep in mindthat the server is only accessible over https unencrypted traffic is not allowed
1542 DeploymentSetup website
For the simple deployment of the lastest version of the shop a playbook called deployyml is provided Thisplaybook put all files in place
$ sudo ansible-playbook develdeployyml
To full deploy the webshop all tables in the database must exist The file webshopsql contains all needed SQLcommands and sample data for the web application
Itrsquos possible to deploy the website manually but this is not recommended A couple of files are depending on templateswhich are created during the deployment
Itrsquos also not recommanded to clone everything into your webserver root This would save you the trouble of doing itby hand but third-party features are missing then Those missing parts are the template engine the pdf generation theconnection to Openstreetmap and probably other things not mentioned here
155 Git respository
All project relevante informations (Source code templates documentation etc) is located in a public Git repositoryon Github
38 Kapitel 15 Development
Shop Documentation Release 001
156 Documentation
The documentation is using reStructuredText as markup language For a local build Sphinx is needed Sphinx isavailable in the Fedora Package Collection and can be installed with yum or any other package management tool
yum -y install python-sphinx python-docutils
The source files of the documentation are located under docs
$ cd docs$ make html
The output is stored under docs_buildhtml
After every push to Github a hook launch a rebuild of the documentation The latest release will be published on Readthe Docs automatically
httpsshoprtfdorg
156 Documentation 39
Shop Documentation Release 001
40 Kapitel 15 Development
KAPITEL 16
Indices and tables
bull genindex
bull modindex
bull search
41
- Basics
-
- Products
- Personas
- Use cases
- Design principles
-
- Web shop Design
-
- General
- Layout
- Sitemap
- Main page
-
- Style and design
-
- Cascading Style Sheets
- Pages
-
- Dynamics
-
- Setup
- Current year
- Navigation Menu
- List of Products
- Company details
-
- External files
-
- Navigation Menu
- Header
- Footer
-
- Input processing
-
- ``Buy Now links
- Select options
-
- Javascript
-
- Simple use case
-
- Cookies and Sessions
-
- Cookies
- Hit counter
- Language selection
- User Accounts
-
- Database
-
- Tables
- PHP
-
- Web service
-
- Map
- Weather
-
- Data export
-
- JSON
-
- Messaging
-
- MQTT
-
- Localisation (L10n)
- Templates
-
- Template
- Content
-
- Development
-
- Web server
- Database server
- Versions
- Setup infrastructure
- Git respository
- Documentation
-
- Indices and tables
-
KAPITEL 5
External files
51 Navigation Menu
The menu is outsourced in the file menuphp
ltphpfunction menu()
$part1 = rsquoltul class=nav nav-tabsgtrsquon$part2 = rsquorsquo$part3 = rsquoltulgtrsquon Menu array with page title and assigned file$menu = array(rsquoHomersquo =gt rsquoindexphprsquo
rsquoProduktersquo =gt rsquoproductsphprsquorsquoUumlber unsrsquo =gt rsquoaboutphprsquo
)foreach ($menu as $label =gt $link)
For the CSS only the file name without is needed$url = trim($_SERVER[rsquoPHP_SELFrsquo] rsquorsquo)if ($link == $url)
$part2 = $part2ltli class=rsquoactiversquogtlta href=rsquo$linkrsquogt$labelltagtltligtn else
$part2 = $part2ltli class=rsquorsquogtlta href=rsquo$linkrsquogt$labelltagtltligtn
return $part1$part2$part3
gt
52 Header
The complete header part is loaded from the file headerphp
ltphpfunction head()
$start_page = indexphp$part1 = ltdivgtn$part2 = tlta class=rsquobrand-logorsquo href=rsquo$start_pagersquogtltagtn$part3 = tltp class=rsquobrand-namersquogtWebshop Pencil AGltpgtn$part4 = ltdivgtnreturn $part1$part2$part3$part4
17
Shop Documentation Release 001
gt
53 Footer
The same is done witht the page footers
ltphpfunction foot()
$class1 = rsquoltdiv class=footergtrsquon$class2 = rsquoltdivgtrsquon$text = ltpgtampcopy Pencil AG getYear()rsquoltpgtrsquonreturn $class1$text$class2
function getYear()return date(Y)
gt
18 Kapitel 5 External files
KAPITEL 6
Input processing
61 ldquoBuy Nowrdquo links
The ldquoBuy Nowrdquo links are attached to the Products page Every entry has itrsquos own link which lead to a detail page Thelinks are using hidden form elements to transfer the data
ltphp$products = array(array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquoHBrsquo rsquo1rsquo)
array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquoBrsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquo2Brsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquoFrsquo rsquo12rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquoHrsquo rsquo12rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquo2Hrsquo rsquo12rsquo)
)foreach ($products as $product =gt $details)
echo lttrgtnforeach ($details as $detail)
echo lttdgt$detaillttdgtnecho lttdgtnecho ltform action=rsquoproductphprsquo method=rsquogetrsquo name=rsquopencilrsquogtnecho ltinput type=rsquohiddenrsquo name=rsquotypersquo value=rsquo$details[0]rsquogtnecho ltinput type=rsquohiddenrsquo name=rsquooptionsrsquo value=rsquo$details[1]rsquogtnecho ltinput type=rsquohiddenrsquo name=rsquocolorrsquo value=rsquo$details[2]rsquogtnecho ltinput type=rsquohiddenrsquo name=rsquohardnessrsquo value=rsquo$details[3]rsquogtnecho ltinput type=rsquohiddenrsquo name=rsquopricersquo value=rsquo$details[4]rsquogtnecho ltinput type=rsquosubmitrsquo class=rsquobtn btn-defaultrsquo value=rsquoKauf michrsquogtnecho ltformgtnecho lttdgtnecho lttrgtn
gt
And the detail page contains the code fragement mentioned below
ltphp$type=$_GET[rsquotypersquo]$color=$_GET[rsquocolorrsquo]$hardness=$_GET[rsquohardnessrsquo]$options=$_GET[rsquooptionsrsquo]$price=$_GET[rsquopricersquo]echo I am a $type in $color and a hardness of $hardness I have $options as an option and my price is $price CHF
gt
19
Shop Documentation Release 001
Bemerkung The Products page was modified in the process of the development
62 Select options
The signupbilling page contains a dropdown element that all days of a month for the entry of the userrsquos birthday
ltselect name=daygtltoptiongtDayltoptiongt
ltphp$days = range(31 1)foreach ($days as $day)
echo rsquoltoption value=rsquo$dayrsquogtrsquo$dayrsquoltoptiongtrsquo
gtltselectgt
20 Kapitel 6 Input processing
KAPITEL 7
Javascript
Over the years Javascript became a very popular programming language The webshop is using Javascript at a coupleof places
71 Simple use case
Javascript makes it easy to access elements in the DOM Setting the focus is a nice way to support the user with inputform
ltscript language=javascriptgtfunction setFocus()
documentforms[login][username]focus()
ltscriptgtltheadgtltbody onload=setFocus()gt
Another one is to check if something was entered in an input field
function validateForm() var username = documentforms[rdquologinrdquo][rdquousernamerdquo]value if (username== null || username == ldquordquo)
documentforms[rdquologinrdquo][rdquousernamerdquo]stylebackgroundColor = ldquoFF9999rdquo docu-mentforms[rdquologinrdquo][rdquousernamerdquo]placeholder = ldquoPlease your usernamerdquo docu-mentforms[rdquologinrdquo][rdquousernamerdquo]focus() return false
A simple message is informing the user about an action which was taken against the database
echo ltscript type=textjavascriptgtalert(New entry $entry added successfully)windowlocation = tablesphp
ltscriptgt
The delete process is only executed if the user confirm to delete a record
ltform action=scriptsdelete-processphp onSubmit=return confirm(rsquoAre you sure to delete this entryrsquo) method=POSTgtltinput type=hidden name=table value=$sectiongtltinput type=hidden name=id value=$result-gtidgtltinput type=submit name=Submit value=Deletegt
ltformgt
For additional Javascript please check the source of the indexphp file and the reflsquowebservicelsquo_ section
21
Shop Documentation Release 001
22 Kapitel 7 Javascript
KAPITEL 8
Cookies and Sessions
The built-in support for sessions in PHP is handling all cookie manipulation to provide persistent variables that areaccessible from different pages and across multiple visits to the site
81 Cookies
A cookie is used to track the last time a visitor check the front page The cookie is set when a visitor arrives
function lastVisit($name $expire) $value = getDateDMY() - getTimeHM()setcookie($name $value time() + $expire rsquorsquo $_SERVER[rsquoSERVER_NAMErsquo] true true)
In the footer of the index page the details are presented
ltphpif(isset($_COOKIE[rsquoLastVisitrsquo]))
$last = $_COOKIE[rsquoLastVisitrsquo]echo You last visited us on $last
else echo This is your first visit
gt
82 Hit counter
As a simple show case for PHP sessions a hit counter for the front page is available
ltphpsession_start()
$_SESSION[rsquohitsrsquo] = $_SESSION[rsquohitsrsquo] + 1gt
Included in the footer it shous the users the total of visits
echo Total $_SESSION[rsquohitsrsquo] visits of this page
23
Shop Documentation Release 001
83 Language selection
84 User Accounts
24 Kapitel 8 Cookies and Sessions
KAPITEL 9
Database
The database backend for the webshop will be MariaDB which is the drop-in replacement for MySQL
For the setup please check the Development section in this documentation
91 Tables
The following tables are needed for the webshop to work
bull products
bull customers
bull pencils
bull colors
bull hardness
bull options
bull users
Please use the develwebshopsql to setup the database
92 PHP
Below you find the configuration file for a default installation of the webshop This file is a template and filled duringthe setup process
ltphp$host = localhost$user = root$password = webshop$dbase = webshop$connection = new mysqli($host $user $password $dbase)
if ($connection-gtconnect_errno) echo Failed to connect to MariaDBMySQL ($connection-gtconnect_errno) $connection-gtconnect_error
mysqli_report(MYSQLI_REPORT_ERROR)
gt
25
Shop Documentation Release 001
All connections to the database are done in the same way Below you find an example Everything is done in theobject-oriented style
ltphprequire_once(rsquoconfigdbconnectphprsquo)if ($connection-gtconnect_errno == 0)
$sql = SELECT FROM products$results = $connection-gtquery($sql)echo $results-gtnum_rows$results-gtclose()
else echo Database connection error
gt
26 Kapitel 9 Database
KAPITEL 10
Web service
Tow web services are integrated to take advantages of online available data sources
101 Map
Leafletjs a JavaScript library for working with interactive maps from OpenStreetMap (OSM) is implemented as ashow case for a simple web service
The basic steps to integrate a map is shown below
ltdiv id=map class=map style=width 600px height 400pxgtltdivgt
ltscript src=scriptsleafletjsgtltscriptgtltscript src=scriptsleaflet-providersjsgtltscriptgtltscriptgtvar map = Lmap(rsquomaprsquo
center [250472 -773255]zoom 12zoomControl true
)
var defaultLayer = LtileLayerprovider(rsquoOpenStreetMapMapnikrsquo)addTo(map)ltscriptgt
102 Weather
The OpenWeatherMap service provides free weather data and a forecast API for web applications
ltphp Details about the API httpbugsopenweathermaporgprojectsapiwikiApi_2_5_weather$url = rsquohttpapiopenweathermaporgdata25weatherq=Bernechampunit=metricsampmode=jsonrsquo
$json = file_get_contents($url)$data = json_decode($json)
$tempC = round((27315 - $data-gtmain-gttemp)100) 100$humidity = $data-gtmain-gthumidity$pressure = $data-gtmain-gtpressure
27
Shop Documentation Release 001
echo ltpgtTemperatur $tempC degCltbrgtnecho Luftfeuchtigkeit $humidity ltbrgtnecho Luftdruck $pressure Paltpgtn
gt
28 Kapitel 10 Web service
KAPITEL 11
Data export
111 PDF
FPDF is a PHP class that allows to generate PDF files with pure PHP As a showcase for that the product specificationsfor a given product are filled in a pdf and showed in the browser The user can then decide to download or print thefile
112 JSON
JavaScript Object Notation (JSON) is a lightweight data-interchange format The format is language independent andPHP support the encoding and the decoding JSON with json_encode($data) and json_decode($data)$rows = array()$sql = SELECT FROM products$results = $connection-gtquery($sql)while ($result = $results-gtfetch_object())
$rows[] = $result$results-gtclose()
Writing all rows to a JSON file$fp = fopen(rsquopencilsjsonrsquo rsquowrsquo)fwrite($fp json_encode($rows))fclose($fp)gt
and for reading it
ltphp$json = file_get_contents(rsquopencilsjsonrsquo)print_r(json_decode($json))
gt
29
Shop Documentation Release 001
30 Kapitel 11 Data export
KAPITEL 12
Messaging
Beside standard email messages the webshop supports sending MQ Telemetry Transport protocol (MQTT) messagesas an additional feature The MQTT messages are small
121 MQTT
Mosquitto-PHP is used as a PHP wrapper for MQTT Please check the Projectrsquos README for details about theinstallation and the setup
1211 Broker
Mosquitto is a message broker that implements the MQ Telemetry Transport protocol Check if mosquitto is run-ning
$ sudo systemctl status mosquittoservice
If not start it
$ systemctl start mosquittoservice
All messages are published to the topic webshop
1212 Publishing
After the installation of Mosquitto-PHP the snipplet shown below sends a single message
ltphpdefine(rsquoBROKERrsquo rsquolocalhostrsquo)define(rsquoPORTrsquo 1883)define(rsquoCLIENT_IDrsquo webshop_ + getmypid())$topic = webshop$subtopic = test$completeTopic = $topic$subtopic
$client = new MosquittoClient(CLIENT_ID)$client-gtconnect(BROKER PORT 60)
$message = Test message from webshop at date(Y-m-d His)$client-gtpublish($completeTopic $message 0 false)
gt
31
Shop Documentation Release 001
1213 Subscribing
To read the messages sent by the webshop a client is needed The Mosquitto broker contain a simple command-linetool for subscribing to various topics
$ mosquitto_sub -h localhost -t webshop
122 Email
This section doesnrsquot describe the installation and configuration of a local MTA There are enough resources thatcontains information about the setup of postfix for local delivery only
If you want to test the email feature add the following code in one of PHP pages
ltphp mail(rsquorootlocalhostrsquo rsquoTest message from webshoprsquo rsquoThe webshop is selling pencilsrsquo) gt
By default SELinux is running in Enforcing mode which is restrictive about about what a web server can do Toallow sending email the following SELinux boolean needs to changed
setsebool -P httpd_can_network_connect=1 setsebool -P httpd_can_sendmail=1
32 Kapitel 12 Messaging
KAPITEL 13
Localisation (L10n)
There are several ways to add localisation to a web site For small projects arrays with string can work but this is notvery efficient and user-friendly With Gettext is a toolset available that provide a framework to produce multi-lingualcontent in a wide area of programming languages
Make sure that the php-gettext package is available on your system If not install it
$ sudo yum -y install php-php-gettext
Check if gettext support is available
ltphpif (function_exists(gettext))
echo gettext is not installednelse
echo gettext is supportedn
gt
Make sure that all locales your want are available on the server
locale -a
The first step is to mark all string which should be translatable as shown below For further details please refer to theGettext documentation
echo _(rsquoSome textrsquo)
The next step is to extract all strings
xgettext --from-code=UTF-8 -o localewebshoppot php scriptsphp
To re-generate the file after an update join the strings
xgettext -j --from-code=UTF-8 -o localewebshoppot php scriptsphp
For every language a po file is needed for the transations Generate it with the command mentioned below
msginit --no-translator -l de_CH -o localede_CHpo -i localewebshoppot
Once created there are only updates of the message catalog needed in the futures
msgmerge -U localede_CHpo localewebshoppot
If you re finish create the mo file for the specific language
33
Shop Documentation Release 001
msgfmt -c -v -o localede_CHLC_MESSAGESwebshopmo localede_CHpo
34 Kapitel 13 Localisation (L10n)
KAPITEL 14
Templates
Beside other solutions Savant3 is a lightweight object-oriented template system for PHP This solution does not needa lot of additional configuration
141 Template
A simple template file looks like the one shown below
lthtmlgtltheadgt
lttitlegtltphp echo $this-gteprint($this-gttitle) gtlttitlegtltheadgtltbodygt
ltphp echo $this-gteprint($this-gtcontent) gtltbodygt
lthtmlgt
For a more detailed intro check this article on Zend Developer Zone
142 Content
To fill the template with data all wished variables needs to be defined in a seperate PHP file
ltphprequire_once rsquoscriptsSavant3phprsquo$tpl = new Savant3()
Create a title$title = Simple sample page
Create the content of the page$content = Some sample text to show
Assign values to the Savant instance$tpl-gttitle = $title$tpl-gtcontent = $content
Define the template source file to show$tpl-gtdisplay(rsquosimpletplphprsquo)
gt
35
Shop Documentation Release 001
The webshop contains a page (master)
36 Kapitel 14 Templates
KAPITEL 15
Development
This sections describes the configuration of the development and runtime environment for the web shop
151 Web server
Instead of Apache the project is running on Lighttpd The reasons are that Lighttpd provides faster setup easierconfiguration and better performance Lighttpd is running with FastCGI
The path of the web server is varwwwlighttpd and the SELinux configuration are still the defaults
The web server is running in SSL-only mode and the certificate is generated during the server setup process
152 Database server
For persistence storage the drop-in replacement MariaDB is used MySQL will work to but this is not tested phpMyAd-min is available under phpmyadmin on the web server beside the command-line tools for easy administration
The default credentials for phpMyAdmin are rootwebshop or the entry you made in the Ansible playbookdevelvariablessensitiveyml
153 Versions
The web shop is built with the below listed components and tested Other releases can be used and may work but thiswill not be tested Probably it will work with different releases
bull Operating system Fedora 20
bull Kernel 3135-202fc20x86_64
bull Lighttpd 1434
bull PHP 557
bull MariaDB 5534
For communication postfix and mosquitto are needed additionally
37
Shop Documentation Release 001
154 Setup infrastructure
1541 Configuration management
For the creation of reproducable and identical environment for the development and the run-time across differentsystems Ansible is used as configuration management solution All needed steps of the installation are automated Theconfiguration doesnrsquot differentiate between local or remote installations This matters only for the deployment of theweb content
For local development itrsquos possible to use an LX container
$ sudo ansible-playbook develcontaineryml
To get everything running some additional steps (check the network inside the container generate keys etc) areneeded After you are done check it
$ sudo ansible webshop -m setup
From the management system
$ sudo ssh-copy-id -i rootsshid_rsapub root[IP address of your managed node]
The configuration of Ansible itself (adding the system to etcansiblehosts and copying the SSH keys) isnot documented at this place There are various resources available like here All playbooks are located in the folderdevel Start the setup with the command shown below
$ sudo ansible-playbook develsetupyml
The used group name in etcansiblehosts is webshop
If the setup completes without errors then the web server is accessible and show a default page Please keep in mindthat the server is only accessible over https unencrypted traffic is not allowed
1542 DeploymentSetup website
For the simple deployment of the lastest version of the shop a playbook called deployyml is provided Thisplaybook put all files in place
$ sudo ansible-playbook develdeployyml
To full deploy the webshop all tables in the database must exist The file webshopsql contains all needed SQLcommands and sample data for the web application
Itrsquos possible to deploy the website manually but this is not recommended A couple of files are depending on templateswhich are created during the deployment
Itrsquos also not recommanded to clone everything into your webserver root This would save you the trouble of doing itby hand but third-party features are missing then Those missing parts are the template engine the pdf generation theconnection to Openstreetmap and probably other things not mentioned here
155 Git respository
All project relevante informations (Source code templates documentation etc) is located in a public Git repositoryon Github
38 Kapitel 15 Development
Shop Documentation Release 001
156 Documentation
The documentation is using reStructuredText as markup language For a local build Sphinx is needed Sphinx isavailable in the Fedora Package Collection and can be installed with yum or any other package management tool
yum -y install python-sphinx python-docutils
The source files of the documentation are located under docs
$ cd docs$ make html
The output is stored under docs_buildhtml
After every push to Github a hook launch a rebuild of the documentation The latest release will be published on Readthe Docs automatically
httpsshoprtfdorg
156 Documentation 39
Shop Documentation Release 001
40 Kapitel 15 Development
KAPITEL 16
Indices and tables
bull genindex
bull modindex
bull search
41
- Basics
-
- Products
- Personas
- Use cases
- Design principles
-
- Web shop Design
-
- General
- Layout
- Sitemap
- Main page
-
- Style and design
-
- Cascading Style Sheets
- Pages
-
- Dynamics
-
- Setup
- Current year
- Navigation Menu
- List of Products
- Company details
-
- External files
-
- Navigation Menu
- Header
- Footer
-
- Input processing
-
- ``Buy Now links
- Select options
-
- Javascript
-
- Simple use case
-
- Cookies and Sessions
-
- Cookies
- Hit counter
- Language selection
- User Accounts
-
- Database
-
- Tables
- PHP
-
- Web service
-
- Map
- Weather
-
- Data export
-
- JSON
-
- Messaging
-
- MQTT
-
- Localisation (L10n)
- Templates
-
- Template
- Content
-
- Development
-
- Web server
- Database server
- Versions
- Setup infrastructure
- Git respository
- Documentation
-
- Indices and tables
-
Shop Documentation Release 001
gt
53 Footer
The same is done witht the page footers
ltphpfunction foot()
$class1 = rsquoltdiv class=footergtrsquon$class2 = rsquoltdivgtrsquon$text = ltpgtampcopy Pencil AG getYear()rsquoltpgtrsquonreturn $class1$text$class2
function getYear()return date(Y)
gt
18 Kapitel 5 External files
KAPITEL 6
Input processing
61 ldquoBuy Nowrdquo links
The ldquoBuy Nowrdquo links are attached to the Products page Every entry has itrsquos own link which lead to a detail page Thelinks are using hidden form elements to transfer the data
ltphp$products = array(array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquoHBrsquo rsquo1rsquo)
array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquoBrsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquo2Brsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquoFrsquo rsquo12rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquoHrsquo rsquo12rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquo2Hrsquo rsquo12rsquo)
)foreach ($products as $product =gt $details)
echo lttrgtnforeach ($details as $detail)
echo lttdgt$detaillttdgtnecho lttdgtnecho ltform action=rsquoproductphprsquo method=rsquogetrsquo name=rsquopencilrsquogtnecho ltinput type=rsquohiddenrsquo name=rsquotypersquo value=rsquo$details[0]rsquogtnecho ltinput type=rsquohiddenrsquo name=rsquooptionsrsquo value=rsquo$details[1]rsquogtnecho ltinput type=rsquohiddenrsquo name=rsquocolorrsquo value=rsquo$details[2]rsquogtnecho ltinput type=rsquohiddenrsquo name=rsquohardnessrsquo value=rsquo$details[3]rsquogtnecho ltinput type=rsquohiddenrsquo name=rsquopricersquo value=rsquo$details[4]rsquogtnecho ltinput type=rsquosubmitrsquo class=rsquobtn btn-defaultrsquo value=rsquoKauf michrsquogtnecho ltformgtnecho lttdgtnecho lttrgtn
gt
And the detail page contains the code fragement mentioned below
ltphp$type=$_GET[rsquotypersquo]$color=$_GET[rsquocolorrsquo]$hardness=$_GET[rsquohardnessrsquo]$options=$_GET[rsquooptionsrsquo]$price=$_GET[rsquopricersquo]echo I am a $type in $color and a hardness of $hardness I have $options as an option and my price is $price CHF
gt
19
Shop Documentation Release 001
Bemerkung The Products page was modified in the process of the development
62 Select options
The signupbilling page contains a dropdown element that all days of a month for the entry of the userrsquos birthday
ltselect name=daygtltoptiongtDayltoptiongt
ltphp$days = range(31 1)foreach ($days as $day)
echo rsquoltoption value=rsquo$dayrsquogtrsquo$dayrsquoltoptiongtrsquo
gtltselectgt
20 Kapitel 6 Input processing
KAPITEL 7
Javascript
Over the years Javascript became a very popular programming language The webshop is using Javascript at a coupleof places
71 Simple use case
Javascript makes it easy to access elements in the DOM Setting the focus is a nice way to support the user with inputform
ltscript language=javascriptgtfunction setFocus()
documentforms[login][username]focus()
ltscriptgtltheadgtltbody onload=setFocus()gt
Another one is to check if something was entered in an input field
function validateForm() var username = documentforms[rdquologinrdquo][rdquousernamerdquo]value if (username== null || username == ldquordquo)
documentforms[rdquologinrdquo][rdquousernamerdquo]stylebackgroundColor = ldquoFF9999rdquo docu-mentforms[rdquologinrdquo][rdquousernamerdquo]placeholder = ldquoPlease your usernamerdquo docu-mentforms[rdquologinrdquo][rdquousernamerdquo]focus() return false
A simple message is informing the user about an action which was taken against the database
echo ltscript type=textjavascriptgtalert(New entry $entry added successfully)windowlocation = tablesphp
ltscriptgt
The delete process is only executed if the user confirm to delete a record
ltform action=scriptsdelete-processphp onSubmit=return confirm(rsquoAre you sure to delete this entryrsquo) method=POSTgtltinput type=hidden name=table value=$sectiongtltinput type=hidden name=id value=$result-gtidgtltinput type=submit name=Submit value=Deletegt
ltformgt
For additional Javascript please check the source of the indexphp file and the reflsquowebservicelsquo_ section
21
Shop Documentation Release 001
22 Kapitel 7 Javascript
KAPITEL 8
Cookies and Sessions
The built-in support for sessions in PHP is handling all cookie manipulation to provide persistent variables that areaccessible from different pages and across multiple visits to the site
81 Cookies
A cookie is used to track the last time a visitor check the front page The cookie is set when a visitor arrives
function lastVisit($name $expire) $value = getDateDMY() - getTimeHM()setcookie($name $value time() + $expire rsquorsquo $_SERVER[rsquoSERVER_NAMErsquo] true true)
In the footer of the index page the details are presented
ltphpif(isset($_COOKIE[rsquoLastVisitrsquo]))
$last = $_COOKIE[rsquoLastVisitrsquo]echo You last visited us on $last
else echo This is your first visit
gt
82 Hit counter
As a simple show case for PHP sessions a hit counter for the front page is available
ltphpsession_start()
$_SESSION[rsquohitsrsquo] = $_SESSION[rsquohitsrsquo] + 1gt
Included in the footer it shous the users the total of visits
echo Total $_SESSION[rsquohitsrsquo] visits of this page
23
Shop Documentation Release 001
83 Language selection
84 User Accounts
24 Kapitel 8 Cookies and Sessions
KAPITEL 9
Database
The database backend for the webshop will be MariaDB which is the drop-in replacement for MySQL
For the setup please check the Development section in this documentation
91 Tables
The following tables are needed for the webshop to work
bull products
bull customers
bull pencils
bull colors
bull hardness
bull options
bull users
Please use the develwebshopsql to setup the database
92 PHP
Below you find the configuration file for a default installation of the webshop This file is a template and filled duringthe setup process
ltphp$host = localhost$user = root$password = webshop$dbase = webshop$connection = new mysqli($host $user $password $dbase)
if ($connection-gtconnect_errno) echo Failed to connect to MariaDBMySQL ($connection-gtconnect_errno) $connection-gtconnect_error
mysqli_report(MYSQLI_REPORT_ERROR)
gt
25
Shop Documentation Release 001
All connections to the database are done in the same way Below you find an example Everything is done in theobject-oriented style
ltphprequire_once(rsquoconfigdbconnectphprsquo)if ($connection-gtconnect_errno == 0)
$sql = SELECT FROM products$results = $connection-gtquery($sql)echo $results-gtnum_rows$results-gtclose()
else echo Database connection error
gt
26 Kapitel 9 Database
KAPITEL 10
Web service
Tow web services are integrated to take advantages of online available data sources
101 Map
Leafletjs a JavaScript library for working with interactive maps from OpenStreetMap (OSM) is implemented as ashow case for a simple web service
The basic steps to integrate a map is shown below
ltdiv id=map class=map style=width 600px height 400pxgtltdivgt
ltscript src=scriptsleafletjsgtltscriptgtltscript src=scriptsleaflet-providersjsgtltscriptgtltscriptgtvar map = Lmap(rsquomaprsquo
center [250472 -773255]zoom 12zoomControl true
)
var defaultLayer = LtileLayerprovider(rsquoOpenStreetMapMapnikrsquo)addTo(map)ltscriptgt
102 Weather
The OpenWeatherMap service provides free weather data and a forecast API for web applications
ltphp Details about the API httpbugsopenweathermaporgprojectsapiwikiApi_2_5_weather$url = rsquohttpapiopenweathermaporgdata25weatherq=Bernechampunit=metricsampmode=jsonrsquo
$json = file_get_contents($url)$data = json_decode($json)
$tempC = round((27315 - $data-gtmain-gttemp)100) 100$humidity = $data-gtmain-gthumidity$pressure = $data-gtmain-gtpressure
27
Shop Documentation Release 001
echo ltpgtTemperatur $tempC degCltbrgtnecho Luftfeuchtigkeit $humidity ltbrgtnecho Luftdruck $pressure Paltpgtn
gt
28 Kapitel 10 Web service
KAPITEL 11
Data export
111 PDF
FPDF is a PHP class that allows to generate PDF files with pure PHP As a showcase for that the product specificationsfor a given product are filled in a pdf and showed in the browser The user can then decide to download or print thefile
112 JSON
JavaScript Object Notation (JSON) is a lightweight data-interchange format The format is language independent andPHP support the encoding and the decoding JSON with json_encode($data) and json_decode($data)$rows = array()$sql = SELECT FROM products$results = $connection-gtquery($sql)while ($result = $results-gtfetch_object())
$rows[] = $result$results-gtclose()
Writing all rows to a JSON file$fp = fopen(rsquopencilsjsonrsquo rsquowrsquo)fwrite($fp json_encode($rows))fclose($fp)gt
and for reading it
ltphp$json = file_get_contents(rsquopencilsjsonrsquo)print_r(json_decode($json))
gt
29
Shop Documentation Release 001
30 Kapitel 11 Data export
KAPITEL 12
Messaging
Beside standard email messages the webshop supports sending MQ Telemetry Transport protocol (MQTT) messagesas an additional feature The MQTT messages are small
121 MQTT
Mosquitto-PHP is used as a PHP wrapper for MQTT Please check the Projectrsquos README for details about theinstallation and the setup
1211 Broker
Mosquitto is a message broker that implements the MQ Telemetry Transport protocol Check if mosquitto is run-ning
$ sudo systemctl status mosquittoservice
If not start it
$ systemctl start mosquittoservice
All messages are published to the topic webshop
1212 Publishing
After the installation of Mosquitto-PHP the snipplet shown below sends a single message
ltphpdefine(rsquoBROKERrsquo rsquolocalhostrsquo)define(rsquoPORTrsquo 1883)define(rsquoCLIENT_IDrsquo webshop_ + getmypid())$topic = webshop$subtopic = test$completeTopic = $topic$subtopic
$client = new MosquittoClient(CLIENT_ID)$client-gtconnect(BROKER PORT 60)
$message = Test message from webshop at date(Y-m-d His)$client-gtpublish($completeTopic $message 0 false)
gt
31
Shop Documentation Release 001
1213 Subscribing
To read the messages sent by the webshop a client is needed The Mosquitto broker contain a simple command-linetool for subscribing to various topics
$ mosquitto_sub -h localhost -t webshop
122 Email
This section doesnrsquot describe the installation and configuration of a local MTA There are enough resources thatcontains information about the setup of postfix for local delivery only
If you want to test the email feature add the following code in one of PHP pages
ltphp mail(rsquorootlocalhostrsquo rsquoTest message from webshoprsquo rsquoThe webshop is selling pencilsrsquo) gt
By default SELinux is running in Enforcing mode which is restrictive about about what a web server can do Toallow sending email the following SELinux boolean needs to changed
setsebool -P httpd_can_network_connect=1 setsebool -P httpd_can_sendmail=1
32 Kapitel 12 Messaging
KAPITEL 13
Localisation (L10n)
There are several ways to add localisation to a web site For small projects arrays with string can work but this is notvery efficient and user-friendly With Gettext is a toolset available that provide a framework to produce multi-lingualcontent in a wide area of programming languages
Make sure that the php-gettext package is available on your system If not install it
$ sudo yum -y install php-php-gettext
Check if gettext support is available
ltphpif (function_exists(gettext))
echo gettext is not installednelse
echo gettext is supportedn
gt
Make sure that all locales your want are available on the server
locale -a
The first step is to mark all string which should be translatable as shown below For further details please refer to theGettext documentation
echo _(rsquoSome textrsquo)
The next step is to extract all strings
xgettext --from-code=UTF-8 -o localewebshoppot php scriptsphp
To re-generate the file after an update join the strings
xgettext -j --from-code=UTF-8 -o localewebshoppot php scriptsphp
For every language a po file is needed for the transations Generate it with the command mentioned below
msginit --no-translator -l de_CH -o localede_CHpo -i localewebshoppot
Once created there are only updates of the message catalog needed in the futures
msgmerge -U localede_CHpo localewebshoppot
If you re finish create the mo file for the specific language
33
Shop Documentation Release 001
msgfmt -c -v -o localede_CHLC_MESSAGESwebshopmo localede_CHpo
34 Kapitel 13 Localisation (L10n)
KAPITEL 14
Templates
Beside other solutions Savant3 is a lightweight object-oriented template system for PHP This solution does not needa lot of additional configuration
141 Template
A simple template file looks like the one shown below
lthtmlgtltheadgt
lttitlegtltphp echo $this-gteprint($this-gttitle) gtlttitlegtltheadgtltbodygt
ltphp echo $this-gteprint($this-gtcontent) gtltbodygt
lthtmlgt
For a more detailed intro check this article on Zend Developer Zone
142 Content
To fill the template with data all wished variables needs to be defined in a seperate PHP file
ltphprequire_once rsquoscriptsSavant3phprsquo$tpl = new Savant3()
Create a title$title = Simple sample page
Create the content of the page$content = Some sample text to show
Assign values to the Savant instance$tpl-gttitle = $title$tpl-gtcontent = $content
Define the template source file to show$tpl-gtdisplay(rsquosimpletplphprsquo)
gt
35
Shop Documentation Release 001
The webshop contains a page (master)
36 Kapitel 14 Templates
KAPITEL 15
Development
This sections describes the configuration of the development and runtime environment for the web shop
151 Web server
Instead of Apache the project is running on Lighttpd The reasons are that Lighttpd provides faster setup easierconfiguration and better performance Lighttpd is running with FastCGI
The path of the web server is varwwwlighttpd and the SELinux configuration are still the defaults
The web server is running in SSL-only mode and the certificate is generated during the server setup process
152 Database server
For persistence storage the drop-in replacement MariaDB is used MySQL will work to but this is not tested phpMyAd-min is available under phpmyadmin on the web server beside the command-line tools for easy administration
The default credentials for phpMyAdmin are rootwebshop or the entry you made in the Ansible playbookdevelvariablessensitiveyml
153 Versions
The web shop is built with the below listed components and tested Other releases can be used and may work but thiswill not be tested Probably it will work with different releases
bull Operating system Fedora 20
bull Kernel 3135-202fc20x86_64
bull Lighttpd 1434
bull PHP 557
bull MariaDB 5534
For communication postfix and mosquitto are needed additionally
37
Shop Documentation Release 001
154 Setup infrastructure
1541 Configuration management
For the creation of reproducable and identical environment for the development and the run-time across differentsystems Ansible is used as configuration management solution All needed steps of the installation are automated Theconfiguration doesnrsquot differentiate between local or remote installations This matters only for the deployment of theweb content
For local development itrsquos possible to use an LX container
$ sudo ansible-playbook develcontaineryml
To get everything running some additional steps (check the network inside the container generate keys etc) areneeded After you are done check it
$ sudo ansible webshop -m setup
From the management system
$ sudo ssh-copy-id -i rootsshid_rsapub root[IP address of your managed node]
The configuration of Ansible itself (adding the system to etcansiblehosts and copying the SSH keys) isnot documented at this place There are various resources available like here All playbooks are located in the folderdevel Start the setup with the command shown below
$ sudo ansible-playbook develsetupyml
The used group name in etcansiblehosts is webshop
If the setup completes without errors then the web server is accessible and show a default page Please keep in mindthat the server is only accessible over https unencrypted traffic is not allowed
1542 DeploymentSetup website
For the simple deployment of the lastest version of the shop a playbook called deployyml is provided Thisplaybook put all files in place
$ sudo ansible-playbook develdeployyml
To full deploy the webshop all tables in the database must exist The file webshopsql contains all needed SQLcommands and sample data for the web application
Itrsquos possible to deploy the website manually but this is not recommended A couple of files are depending on templateswhich are created during the deployment
Itrsquos also not recommanded to clone everything into your webserver root This would save you the trouble of doing itby hand but third-party features are missing then Those missing parts are the template engine the pdf generation theconnection to Openstreetmap and probably other things not mentioned here
155 Git respository
All project relevante informations (Source code templates documentation etc) is located in a public Git repositoryon Github
38 Kapitel 15 Development
Shop Documentation Release 001
156 Documentation
The documentation is using reStructuredText as markup language For a local build Sphinx is needed Sphinx isavailable in the Fedora Package Collection and can be installed with yum or any other package management tool
yum -y install python-sphinx python-docutils
The source files of the documentation are located under docs
$ cd docs$ make html
The output is stored under docs_buildhtml
After every push to Github a hook launch a rebuild of the documentation The latest release will be published on Readthe Docs automatically
httpsshoprtfdorg
156 Documentation 39
Shop Documentation Release 001
40 Kapitel 15 Development
KAPITEL 16
Indices and tables
bull genindex
bull modindex
bull search
41
- Basics
-
- Products
- Personas
- Use cases
- Design principles
-
- Web shop Design
-
- General
- Layout
- Sitemap
- Main page
-
- Style and design
-
- Cascading Style Sheets
- Pages
-
- Dynamics
-
- Setup
- Current year
- Navigation Menu
- List of Products
- Company details
-
- External files
-
- Navigation Menu
- Header
- Footer
-
- Input processing
-
- ``Buy Now links
- Select options
-
- Javascript
-
- Simple use case
-
- Cookies and Sessions
-
- Cookies
- Hit counter
- Language selection
- User Accounts
-
- Database
-
- Tables
- PHP
-
- Web service
-
- Map
- Weather
-
- Data export
-
- JSON
-
- Messaging
-
- MQTT
-
- Localisation (L10n)
- Templates
-
- Template
- Content
-
- Development
-
- Web server
- Database server
- Versions
- Setup infrastructure
- Git respository
- Documentation
-
- Indices and tables
-
KAPITEL 6
Input processing
61 ldquoBuy Nowrdquo links
The ldquoBuy Nowrdquo links are attached to the Products page Every entry has itrsquos own link which lead to a detail page Thelinks are using hidden form elements to transfer the data
ltphp$products = array(array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquoHBrsquo rsquo1rsquo)
array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquoBrsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquorotrsquo rsquo2Brsquo rsquo1rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquoFrsquo rsquo12rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquoHrsquo rsquo12rsquo)array(rsquoBleistiftrsquo rsquokeinersquo rsquogelbrsquo rsquo2Hrsquo rsquo12rsquo)
)foreach ($products as $product =gt $details)
echo lttrgtnforeach ($details as $detail)
echo lttdgt$detaillttdgtnecho lttdgtnecho ltform action=rsquoproductphprsquo method=rsquogetrsquo name=rsquopencilrsquogtnecho ltinput type=rsquohiddenrsquo name=rsquotypersquo value=rsquo$details[0]rsquogtnecho ltinput type=rsquohiddenrsquo name=rsquooptionsrsquo value=rsquo$details[1]rsquogtnecho ltinput type=rsquohiddenrsquo name=rsquocolorrsquo value=rsquo$details[2]rsquogtnecho ltinput type=rsquohiddenrsquo name=rsquohardnessrsquo value=rsquo$details[3]rsquogtnecho ltinput type=rsquohiddenrsquo name=rsquopricersquo value=rsquo$details[4]rsquogtnecho ltinput type=rsquosubmitrsquo class=rsquobtn btn-defaultrsquo value=rsquoKauf michrsquogtnecho ltformgtnecho lttdgtnecho lttrgtn
gt
And the detail page contains the code fragement mentioned below
ltphp$type=$_GET[rsquotypersquo]$color=$_GET[rsquocolorrsquo]$hardness=$_GET[rsquohardnessrsquo]$options=$_GET[rsquooptionsrsquo]$price=$_GET[rsquopricersquo]echo I am a $type in $color and a hardness of $hardness I have $options as an option and my price is $price CHF
gt
19
Shop Documentation Release 001
Bemerkung The Products page was modified in the process of the development
62 Select options
The signupbilling page contains a dropdown element that all days of a month for the entry of the userrsquos birthday
ltselect name=daygtltoptiongtDayltoptiongt
ltphp$days = range(31 1)foreach ($days as $day)
echo rsquoltoption value=rsquo$dayrsquogtrsquo$dayrsquoltoptiongtrsquo
gtltselectgt
20 Kapitel 6 Input processing
KAPITEL 7
Javascript
Over the years Javascript became a very popular programming language The webshop is using Javascript at a coupleof places
71 Simple use case
Javascript makes it easy to access elements in the DOM Setting the focus is a nice way to support the user with inputform
ltscript language=javascriptgtfunction setFocus()
documentforms[login][username]focus()
ltscriptgtltheadgtltbody onload=setFocus()gt
Another one is to check if something was entered in an input field
function validateForm() var username = documentforms[rdquologinrdquo][rdquousernamerdquo]value if (username== null || username == ldquordquo)
documentforms[rdquologinrdquo][rdquousernamerdquo]stylebackgroundColor = ldquoFF9999rdquo docu-mentforms[rdquologinrdquo][rdquousernamerdquo]placeholder = ldquoPlease your usernamerdquo docu-mentforms[rdquologinrdquo][rdquousernamerdquo]focus() return false
A simple message is informing the user about an action which was taken against the database
echo ltscript type=textjavascriptgtalert(New entry $entry added successfully)windowlocation = tablesphp
ltscriptgt
The delete process is only executed if the user confirm to delete a record
ltform action=scriptsdelete-processphp onSubmit=return confirm(rsquoAre you sure to delete this entryrsquo) method=POSTgtltinput type=hidden name=table value=$sectiongtltinput type=hidden name=id value=$result-gtidgtltinput type=submit name=Submit value=Deletegt
ltformgt
For additional Javascript please check the source of the indexphp file and the reflsquowebservicelsquo_ section
21
Shop Documentation Release 001
22 Kapitel 7 Javascript
KAPITEL 8
Cookies and Sessions
The built-in support for sessions in PHP is handling all cookie manipulation to provide persistent variables that areaccessible from different pages and across multiple visits to the site
81 Cookies
A cookie is used to track the last time a visitor check the front page The cookie is set when a visitor arrives
function lastVisit($name $expire) $value = getDateDMY() - getTimeHM()setcookie($name $value time() + $expire rsquorsquo $_SERVER[rsquoSERVER_NAMErsquo] true true)
In the footer of the index page the details are presented
ltphpif(isset($_COOKIE[rsquoLastVisitrsquo]))
$last = $_COOKIE[rsquoLastVisitrsquo]echo You last visited us on $last
else echo This is your first visit
gt
82 Hit counter
As a simple show case for PHP sessions a hit counter for the front page is available
ltphpsession_start()
$_SESSION[rsquohitsrsquo] = $_SESSION[rsquohitsrsquo] + 1gt
Included in the footer it shous the users the total of visits
echo Total $_SESSION[rsquohitsrsquo] visits of this page
23
Shop Documentation Release 001
83 Language selection
84 User Accounts
24 Kapitel 8 Cookies and Sessions
KAPITEL 9
Database
The database backend for the webshop will be MariaDB which is the drop-in replacement for MySQL
For the setup please check the Development section in this documentation
91 Tables
The following tables are needed for the webshop to work
bull products
bull customers
bull pencils
bull colors
bull hardness
bull options
bull users
Please use the develwebshopsql to setup the database
92 PHP
Below you find the configuration file for a default installation of the webshop This file is a template and filled duringthe setup process
ltphp$host = localhost$user = root$password = webshop$dbase = webshop$connection = new mysqli($host $user $password $dbase)
if ($connection-gtconnect_errno) echo Failed to connect to MariaDBMySQL ($connection-gtconnect_errno) $connection-gtconnect_error
mysqli_report(MYSQLI_REPORT_ERROR)
gt
25
Shop Documentation Release 001
All connections to the database are done in the same way Below you find an example Everything is done in theobject-oriented style
ltphprequire_once(rsquoconfigdbconnectphprsquo)if ($connection-gtconnect_errno == 0)
$sql = SELECT FROM products$results = $connection-gtquery($sql)echo $results-gtnum_rows$results-gtclose()
else echo Database connection error
gt
26 Kapitel 9 Database
KAPITEL 10
Web service
Tow web services are integrated to take advantages of online available data sources
101 Map
Leafletjs a JavaScript library for working with interactive maps from OpenStreetMap (OSM) is implemented as ashow case for a simple web service
The basic steps to integrate a map is shown below
ltdiv id=map class=map style=width 600px height 400pxgtltdivgt
ltscript src=scriptsleafletjsgtltscriptgtltscript src=scriptsleaflet-providersjsgtltscriptgtltscriptgtvar map = Lmap(rsquomaprsquo
center [250472 -773255]zoom 12zoomControl true
)
var defaultLayer = LtileLayerprovider(rsquoOpenStreetMapMapnikrsquo)addTo(map)ltscriptgt
102 Weather
The OpenWeatherMap service provides free weather data and a forecast API for web applications
ltphp Details about the API httpbugsopenweathermaporgprojectsapiwikiApi_2_5_weather$url = rsquohttpapiopenweathermaporgdata25weatherq=Bernechampunit=metricsampmode=jsonrsquo
$json = file_get_contents($url)$data = json_decode($json)
$tempC = round((27315 - $data-gtmain-gttemp)100) 100$humidity = $data-gtmain-gthumidity$pressure = $data-gtmain-gtpressure
27
Shop Documentation Release 001
echo ltpgtTemperatur $tempC degCltbrgtnecho Luftfeuchtigkeit $humidity ltbrgtnecho Luftdruck $pressure Paltpgtn
gt
28 Kapitel 10 Web service
KAPITEL 11
Data export
111 PDF
FPDF is a PHP class that allows to generate PDF files with pure PHP As a showcase for that the product specificationsfor a given product are filled in a pdf and showed in the browser The user can then decide to download or print thefile
112 JSON
JavaScript Object Notation (JSON) is a lightweight data-interchange format The format is language independent andPHP support the encoding and the decoding JSON with json_encode($data) and json_decode($data)$rows = array()$sql = SELECT FROM products$results = $connection-gtquery($sql)while ($result = $results-gtfetch_object())
$rows[] = $result$results-gtclose()
Writing all rows to a JSON file$fp = fopen(rsquopencilsjsonrsquo rsquowrsquo)fwrite($fp json_encode($rows))fclose($fp)gt
and for reading it
ltphp$json = file_get_contents(rsquopencilsjsonrsquo)print_r(json_decode($json))
gt
29
Shop Documentation Release 001
30 Kapitel 11 Data export
KAPITEL 12
Messaging
Beside standard email messages the webshop supports sending MQ Telemetry Transport protocol (MQTT) messagesas an additional feature The MQTT messages are small
121 MQTT
Mosquitto-PHP is used as a PHP wrapper for MQTT Please check the Projectrsquos README for details about theinstallation and the setup
1211 Broker
Mosquitto is a message broker that implements the MQ Telemetry Transport protocol Check if mosquitto is run-ning
$ sudo systemctl status mosquittoservice
If not start it
$ systemctl start mosquittoservice
All messages are published to the topic webshop
1212 Publishing
After the installation of Mosquitto-PHP the snipplet shown below sends a single message
ltphpdefine(rsquoBROKERrsquo rsquolocalhostrsquo)define(rsquoPORTrsquo 1883)define(rsquoCLIENT_IDrsquo webshop_ + getmypid())$topic = webshop$subtopic = test$completeTopic = $topic$subtopic
$client = new MosquittoClient(CLIENT_ID)$client-gtconnect(BROKER PORT 60)
$message = Test message from webshop at date(Y-m-d His)$client-gtpublish($completeTopic $message 0 false)
gt
31
Shop Documentation Release 001
1213 Subscribing
To read the messages sent by the webshop a client is needed The Mosquitto broker contain a simple command-linetool for subscribing to various topics
$ mosquitto_sub -h localhost -t webshop
122 Email
This section doesnrsquot describe the installation and configuration of a local MTA There are enough resources thatcontains information about the setup of postfix for local delivery only
If you want to test the email feature add the following code in one of PHP pages
ltphp mail(rsquorootlocalhostrsquo rsquoTest message from webshoprsquo rsquoThe webshop is selling pencilsrsquo) gt
By default SELinux is running in Enforcing mode which is restrictive about about what a web server can do Toallow sending email the following SELinux boolean needs to changed
setsebool -P httpd_can_network_connect=1 setsebool -P httpd_can_sendmail=1
32 Kapitel 12 Messaging
KAPITEL 13
Localisation (L10n)
There are several ways to add localisation to a web site For small projects arrays with string can work but this is notvery efficient and user-friendly With Gettext is a toolset available that provide a framework to produce multi-lingualcontent in a wide area of programming languages
Make sure that the php-gettext package is available on your system If not install it
$ sudo yum -y install php-php-gettext
Check if gettext support is available
ltphpif (function_exists(gettext))
echo gettext is not installednelse
echo gettext is supportedn
gt
Make sure that all locales your want are available on the server
locale -a
The first step is to mark all string which should be translatable as shown below For further details please refer to theGettext documentation
echo _(rsquoSome textrsquo)
The next step is to extract all strings
xgettext --from-code=UTF-8 -o localewebshoppot php scriptsphp
To re-generate the file after an update join the strings
xgettext -j --from-code=UTF-8 -o localewebshoppot php scriptsphp
For every language a po file is needed for the transations Generate it with the command mentioned below
msginit --no-translator -l de_CH -o localede_CHpo -i localewebshoppot
Once created there are only updates of the message catalog needed in the futures
msgmerge -U localede_CHpo localewebshoppot
If you re finish create the mo file for the specific language
33
Shop Documentation Release 001
msgfmt -c -v -o localede_CHLC_MESSAGESwebshopmo localede_CHpo
34 Kapitel 13 Localisation (L10n)
KAPITEL 14
Templates
Beside other solutions Savant3 is a lightweight object-oriented template system for PHP This solution does not needa lot of additional configuration
141 Template
A simple template file looks like the one shown below
lthtmlgtltheadgt
lttitlegtltphp echo $this-gteprint($this-gttitle) gtlttitlegtltheadgtltbodygt
ltphp echo $this-gteprint($this-gtcontent) gtltbodygt
lthtmlgt
For a more detailed intro check this article on Zend Developer Zone
142 Content
To fill the template with data all wished variables needs to be defined in a seperate PHP file
ltphprequire_once rsquoscriptsSavant3phprsquo$tpl = new Savant3()
Create a title$title = Simple sample page
Create the content of the page$content = Some sample text to show
Assign values to the Savant instance$tpl-gttitle = $title$tpl-gtcontent = $content
Define the template source file to show$tpl-gtdisplay(rsquosimpletplphprsquo)
gt
35
Shop Documentation Release 001
The webshop contains a page (master)
36 Kapitel 14 Templates
KAPITEL 15
Development
This sections describes the configuration of the development and runtime environment for the web shop
151 Web server
Instead of Apache the project is running on Lighttpd The reasons are that Lighttpd provides faster setup easierconfiguration and better performance Lighttpd is running with FastCGI
The path of the web server is varwwwlighttpd and the SELinux configuration are still the defaults
The web server is running in SSL-only mode and the certificate is generated during the server setup process
152 Database server
For persistence storage the drop-in replacement MariaDB is used MySQL will work to but this is not tested phpMyAd-min is available under phpmyadmin on the web server beside the command-line tools for easy administration
The default credentials for phpMyAdmin are rootwebshop or the entry you made in the Ansible playbookdevelvariablessensitiveyml
153 Versions
The web shop is built with the below listed components and tested Other releases can be used and may work but thiswill not be tested Probably it will work with different releases
bull Operating system Fedora 20
bull Kernel 3135-202fc20x86_64
bull Lighttpd 1434
bull PHP 557
bull MariaDB 5534
For communication postfix and mosquitto are needed additionally
37
Shop Documentation Release 001
154 Setup infrastructure
1541 Configuration management
For the creation of reproducable and identical environment for the development and the run-time across differentsystems Ansible is used as configuration management solution All needed steps of the installation are automated Theconfiguration doesnrsquot differentiate between local or remote installations This matters only for the deployment of theweb content
For local development itrsquos possible to use an LX container
$ sudo ansible-playbook develcontaineryml
To get everything running some additional steps (check the network inside the container generate keys etc) areneeded After you are done check it
$ sudo ansible webshop -m setup
From the management system
$ sudo ssh-copy-id -i rootsshid_rsapub root[IP address of your managed node]
The configuration of Ansible itself (adding the system to etcansiblehosts and copying the SSH keys) isnot documented at this place There are various resources available like here All playbooks are located in the folderdevel Start the setup with the command shown below
$ sudo ansible-playbook develsetupyml
The used group name in etcansiblehosts is webshop
If the setup completes without errors then the web server is accessible and show a default page Please keep in mindthat the server is only accessible over https unencrypted traffic is not allowed
1542 DeploymentSetup website
For the simple deployment of the lastest version of the shop a playbook called deployyml is provided Thisplaybook put all files in place
$ sudo ansible-playbook develdeployyml
To full deploy the webshop all tables in the database must exist The file webshopsql contains all needed SQLcommands and sample data for the web application
Itrsquos possible to deploy the website manually but this is not recommended A couple of files are depending on templateswhich are created during the deployment
Itrsquos also not recommanded to clone everything into your webserver root This would save you the trouble of doing itby hand but third-party features are missing then Those missing parts are the template engine the pdf generation theconnection to Openstreetmap and probably other things not mentioned here
155 Git respository
All project relevante informations (Source code templates documentation etc) is located in a public Git repositoryon Github
38 Kapitel 15 Development
Shop Documentation Release 001
156 Documentation
The documentation is using reStructuredText as markup language For a local build Sphinx is needed Sphinx isavailable in the Fedora Package Collection and can be installed with yum or any other package management tool
yum -y install python-sphinx python-docutils
The source files of the documentation are located under docs
$ cd docs$ make html
The output is stored under docs_buildhtml
After every push to Github a hook launch a rebuild of the documentation The latest release will be published on Readthe Docs automatically
httpsshoprtfdorg
156 Documentation 39
Shop Documentation Release 001
40 Kapitel 15 Development
KAPITEL 16
Indices and tables
bull genindex
bull modindex
bull search
41
- Basics
-
- Products
- Personas
- Use cases
- Design principles
-
- Web shop Design
-
- General
- Layout
- Sitemap
- Main page
-
- Style and design
-
- Cascading Style Sheets
- Pages
-
- Dynamics
-
- Setup
- Current year
- Navigation Menu
- List of Products
- Company details
-
- External files
-
- Navigation Menu
- Header
- Footer
-
- Input processing
-
- ``Buy Now links
- Select options
-
- Javascript
-
- Simple use case
-
- Cookies and Sessions
-
- Cookies
- Hit counter
- Language selection
- User Accounts
-
- Database
-
- Tables
- PHP
-
- Web service
-
- Map
- Weather
-
- Data export
-
- JSON
-
- Messaging
-
- MQTT
-
- Localisation (L10n)
- Templates
-
- Template
- Content
-
- Development
-
- Web server
- Database server
- Versions
- Setup infrastructure
- Git respository
- Documentation
-
- Indices and tables
-
Shop Documentation Release 001
Bemerkung The Products page was modified in the process of the development
62 Select options
The signupbilling page contains a dropdown element that all days of a month for the entry of the userrsquos birthday
ltselect name=daygtltoptiongtDayltoptiongt
ltphp$days = range(31 1)foreach ($days as $day)
echo rsquoltoption value=rsquo$dayrsquogtrsquo$dayrsquoltoptiongtrsquo
gtltselectgt
20 Kapitel 6 Input processing
KAPITEL 7
Javascript
Over the years Javascript became a very popular programming language The webshop is using Javascript at a coupleof places
71 Simple use case
Javascript makes it easy to access elements in the DOM Setting the focus is a nice way to support the user with inputform
ltscript language=javascriptgtfunction setFocus()
documentforms[login][username]focus()
ltscriptgtltheadgtltbody onload=setFocus()gt
Another one is to check if something was entered in an input field
function validateForm() var username = documentforms[rdquologinrdquo][rdquousernamerdquo]value if (username== null || username == ldquordquo)
documentforms[rdquologinrdquo][rdquousernamerdquo]stylebackgroundColor = ldquoFF9999rdquo docu-mentforms[rdquologinrdquo][rdquousernamerdquo]placeholder = ldquoPlease your usernamerdquo docu-mentforms[rdquologinrdquo][rdquousernamerdquo]focus() return false
A simple message is informing the user about an action which was taken against the database
echo ltscript type=textjavascriptgtalert(New entry $entry added successfully)windowlocation = tablesphp
ltscriptgt
The delete process is only executed if the user confirm to delete a record
ltform action=scriptsdelete-processphp onSubmit=return confirm(rsquoAre you sure to delete this entryrsquo) method=POSTgtltinput type=hidden name=table value=$sectiongtltinput type=hidden name=id value=$result-gtidgtltinput type=submit name=Submit value=Deletegt
ltformgt
For additional Javascript please check the source of the indexphp file and the reflsquowebservicelsquo_ section
21
Shop Documentation Release 001
22 Kapitel 7 Javascript
KAPITEL 8
Cookies and Sessions
The built-in support for sessions in PHP is handling all cookie manipulation to provide persistent variables that areaccessible from different pages and across multiple visits to the site
81 Cookies
A cookie is used to track the last time a visitor check the front page The cookie is set when a visitor arrives
function lastVisit($name $expire) $value = getDateDMY() - getTimeHM()setcookie($name $value time() + $expire rsquorsquo $_SERVER[rsquoSERVER_NAMErsquo] true true)
In the footer of the index page the details are presented
ltphpif(isset($_COOKIE[rsquoLastVisitrsquo]))
$last = $_COOKIE[rsquoLastVisitrsquo]echo You last visited us on $last
else echo This is your first visit
gt
82 Hit counter
As a simple show case for PHP sessions a hit counter for the front page is available
ltphpsession_start()
$_SESSION[rsquohitsrsquo] = $_SESSION[rsquohitsrsquo] + 1gt
Included in the footer it shous the users the total of visits
echo Total $_SESSION[rsquohitsrsquo] visits of this page
23
Shop Documentation Release 001
83 Language selection
84 User Accounts
24 Kapitel 8 Cookies and Sessions
KAPITEL 9
Database
The database backend for the webshop will be MariaDB which is the drop-in replacement for MySQL
For the setup please check the Development section in this documentation
91 Tables
The following tables are needed for the webshop to work
bull products
bull customers
bull pencils
bull colors
bull hardness
bull options
bull users
Please use the develwebshopsql to setup the database
92 PHP
Below you find the configuration file for a default installation of the webshop This file is a template and filled duringthe setup process
ltphp$host = localhost$user = root$password = webshop$dbase = webshop$connection = new mysqli($host $user $password $dbase)
if ($connection-gtconnect_errno) echo Failed to connect to MariaDBMySQL ($connection-gtconnect_errno) $connection-gtconnect_error
mysqli_report(MYSQLI_REPORT_ERROR)
gt
25
Shop Documentation Release 001
All connections to the database are done in the same way Below you find an example Everything is done in theobject-oriented style
ltphprequire_once(rsquoconfigdbconnectphprsquo)if ($connection-gtconnect_errno == 0)
$sql = SELECT FROM products$results = $connection-gtquery($sql)echo $results-gtnum_rows$results-gtclose()
else echo Database connection error
gt
26 Kapitel 9 Database
KAPITEL 10
Web service
Tow web services are integrated to take advantages of online available data sources
101 Map
Leafletjs a JavaScript library for working with interactive maps from OpenStreetMap (OSM) is implemented as ashow case for a simple web service
The basic steps to integrate a map is shown below
ltdiv id=map class=map style=width 600px height 400pxgtltdivgt
ltscript src=scriptsleafletjsgtltscriptgtltscript src=scriptsleaflet-providersjsgtltscriptgtltscriptgtvar map = Lmap(rsquomaprsquo
center [250472 -773255]zoom 12zoomControl true
)
var defaultLayer = LtileLayerprovider(rsquoOpenStreetMapMapnikrsquo)addTo(map)ltscriptgt
102 Weather
The OpenWeatherMap service provides free weather data and a forecast API for web applications
ltphp Details about the API httpbugsopenweathermaporgprojectsapiwikiApi_2_5_weather$url = rsquohttpapiopenweathermaporgdata25weatherq=Bernechampunit=metricsampmode=jsonrsquo
$json = file_get_contents($url)$data = json_decode($json)
$tempC = round((27315 - $data-gtmain-gttemp)100) 100$humidity = $data-gtmain-gthumidity$pressure = $data-gtmain-gtpressure
27
Shop Documentation Release 001
echo ltpgtTemperatur $tempC degCltbrgtnecho Luftfeuchtigkeit $humidity ltbrgtnecho Luftdruck $pressure Paltpgtn
gt
28 Kapitel 10 Web service
KAPITEL 11
Data export
111 PDF
FPDF is a PHP class that allows to generate PDF files with pure PHP As a showcase for that the product specificationsfor a given product are filled in a pdf and showed in the browser The user can then decide to download or print thefile
112 JSON
JavaScript Object Notation (JSON) is a lightweight data-interchange format The format is language independent andPHP support the encoding and the decoding JSON with json_encode($data) and json_decode($data)$rows = array()$sql = SELECT FROM products$results = $connection-gtquery($sql)while ($result = $results-gtfetch_object())
$rows[] = $result$results-gtclose()
Writing all rows to a JSON file$fp = fopen(rsquopencilsjsonrsquo rsquowrsquo)fwrite($fp json_encode($rows))fclose($fp)gt
and for reading it
ltphp$json = file_get_contents(rsquopencilsjsonrsquo)print_r(json_decode($json))
gt
29
Shop Documentation Release 001
30 Kapitel 11 Data export
KAPITEL 12
Messaging
Beside standard email messages the webshop supports sending MQ Telemetry Transport protocol (MQTT) messagesas an additional feature The MQTT messages are small
121 MQTT
Mosquitto-PHP is used as a PHP wrapper for MQTT Please check the Projectrsquos README for details about theinstallation and the setup
1211 Broker
Mosquitto is a message broker that implements the MQ Telemetry Transport protocol Check if mosquitto is run-ning
$ sudo systemctl status mosquittoservice
If not start it
$ systemctl start mosquittoservice
All messages are published to the topic webshop
1212 Publishing
After the installation of Mosquitto-PHP the snipplet shown below sends a single message
ltphpdefine(rsquoBROKERrsquo rsquolocalhostrsquo)define(rsquoPORTrsquo 1883)define(rsquoCLIENT_IDrsquo webshop_ + getmypid())$topic = webshop$subtopic = test$completeTopic = $topic$subtopic
$client = new MosquittoClient(CLIENT_ID)$client-gtconnect(BROKER PORT 60)
$message = Test message from webshop at date(Y-m-d His)$client-gtpublish($completeTopic $message 0 false)
gt
31
Shop Documentation Release 001
1213 Subscribing
To read the messages sent by the webshop a client is needed The Mosquitto broker contain a simple command-linetool for subscribing to various topics
$ mosquitto_sub -h localhost -t webshop
122 Email
This section doesnrsquot describe the installation and configuration of a local MTA There are enough resources thatcontains information about the setup of postfix for local delivery only
If you want to test the email feature add the following code in one of PHP pages
ltphp mail(rsquorootlocalhostrsquo rsquoTest message from webshoprsquo rsquoThe webshop is selling pencilsrsquo) gt
By default SELinux is running in Enforcing mode which is restrictive about about what a web server can do Toallow sending email the following SELinux boolean needs to changed
setsebool -P httpd_can_network_connect=1 setsebool -P httpd_can_sendmail=1
32 Kapitel 12 Messaging
KAPITEL 13
Localisation (L10n)
There are several ways to add localisation to a web site For small projects arrays with string can work but this is notvery efficient and user-friendly With Gettext is a toolset available that provide a framework to produce multi-lingualcontent in a wide area of programming languages
Make sure that the php-gettext package is available on your system If not install it
$ sudo yum -y install php-php-gettext
Check if gettext support is available
ltphpif (function_exists(gettext))
echo gettext is not installednelse
echo gettext is supportedn
gt
Make sure that all locales your want are available on the server
locale -a
The first step is to mark all string which should be translatable as shown below For further details please refer to theGettext documentation
echo _(rsquoSome textrsquo)
The next step is to extract all strings
xgettext --from-code=UTF-8 -o localewebshoppot php scriptsphp
To re-generate the file after an update join the strings
xgettext -j --from-code=UTF-8 -o localewebshoppot php scriptsphp
For every language a po file is needed for the transations Generate it with the command mentioned below
msginit --no-translator -l de_CH -o localede_CHpo -i localewebshoppot
Once created there are only updates of the message catalog needed in the futures
msgmerge -U localede_CHpo localewebshoppot
If you re finish create the mo file for the specific language
33
Shop Documentation Release 001
msgfmt -c -v -o localede_CHLC_MESSAGESwebshopmo localede_CHpo
34 Kapitel 13 Localisation (L10n)
KAPITEL 14
Templates
Beside other solutions Savant3 is a lightweight object-oriented template system for PHP This solution does not needa lot of additional configuration
141 Template
A simple template file looks like the one shown below
lthtmlgtltheadgt
lttitlegtltphp echo $this-gteprint($this-gttitle) gtlttitlegtltheadgtltbodygt
ltphp echo $this-gteprint($this-gtcontent) gtltbodygt
lthtmlgt
For a more detailed intro check this article on Zend Developer Zone
142 Content
To fill the template with data all wished variables needs to be defined in a seperate PHP file
ltphprequire_once rsquoscriptsSavant3phprsquo$tpl = new Savant3()
Create a title$title = Simple sample page
Create the content of the page$content = Some sample text to show
Assign values to the Savant instance$tpl-gttitle = $title$tpl-gtcontent = $content
Define the template source file to show$tpl-gtdisplay(rsquosimpletplphprsquo)
gt
35
Shop Documentation Release 001
The webshop contains a page (master)
36 Kapitel 14 Templates
KAPITEL 15
Development
This sections describes the configuration of the development and runtime environment for the web shop
151 Web server
Instead of Apache the project is running on Lighttpd The reasons are that Lighttpd provides faster setup easierconfiguration and better performance Lighttpd is running with FastCGI
The path of the web server is varwwwlighttpd and the SELinux configuration are still the defaults
The web server is running in SSL-only mode and the certificate is generated during the server setup process
152 Database server
For persistence storage the drop-in replacement MariaDB is used MySQL will work to but this is not tested phpMyAd-min is available under phpmyadmin on the web server beside the command-line tools for easy administration
The default credentials for phpMyAdmin are rootwebshop or the entry you made in the Ansible playbookdevelvariablessensitiveyml
153 Versions
The web shop is built with the below listed components and tested Other releases can be used and may work but thiswill not be tested Probably it will work with different releases
bull Operating system Fedora 20
bull Kernel 3135-202fc20x86_64
bull Lighttpd 1434
bull PHP 557
bull MariaDB 5534
For communication postfix and mosquitto are needed additionally
37
Shop Documentation Release 001
154 Setup infrastructure
1541 Configuration management
For the creation of reproducable and identical environment for the development and the run-time across differentsystems Ansible is used as configuration management solution All needed steps of the installation are automated Theconfiguration doesnrsquot differentiate between local or remote installations This matters only for the deployment of theweb content
For local development itrsquos possible to use an LX container
$ sudo ansible-playbook develcontaineryml
To get everything running some additional steps (check the network inside the container generate keys etc) areneeded After you are done check it
$ sudo ansible webshop -m setup
From the management system
$ sudo ssh-copy-id -i rootsshid_rsapub root[IP address of your managed node]
The configuration of Ansible itself (adding the system to etcansiblehosts and copying the SSH keys) isnot documented at this place There are various resources available like here All playbooks are located in the folderdevel Start the setup with the command shown below
$ sudo ansible-playbook develsetupyml
The used group name in etcansiblehosts is webshop
If the setup completes without errors then the web server is accessible and show a default page Please keep in mindthat the server is only accessible over https unencrypted traffic is not allowed
1542 DeploymentSetup website
For the simple deployment of the lastest version of the shop a playbook called deployyml is provided Thisplaybook put all files in place
$ sudo ansible-playbook develdeployyml
To full deploy the webshop all tables in the database must exist The file webshopsql contains all needed SQLcommands and sample data for the web application
Itrsquos possible to deploy the website manually but this is not recommended A couple of files are depending on templateswhich are created during the deployment
Itrsquos also not recommanded to clone everything into your webserver root This would save you the trouble of doing itby hand but third-party features are missing then Those missing parts are the template engine the pdf generation theconnection to Openstreetmap and probably other things not mentioned here
155 Git respository
All project relevante informations (Source code templates documentation etc) is located in a public Git repositoryon Github
38 Kapitel 15 Development
Shop Documentation Release 001
156 Documentation
The documentation is using reStructuredText as markup language For a local build Sphinx is needed Sphinx isavailable in the Fedora Package Collection and can be installed with yum or any other package management tool
yum -y install python-sphinx python-docutils
The source files of the documentation are located under docs
$ cd docs$ make html
The output is stored under docs_buildhtml
After every push to Github a hook launch a rebuild of the documentation The latest release will be published on Readthe Docs automatically
httpsshoprtfdorg
156 Documentation 39
Shop Documentation Release 001
40 Kapitel 15 Development
KAPITEL 16
Indices and tables
bull genindex
bull modindex
bull search
41
- Basics
-
- Products
- Personas
- Use cases
- Design principles
-
- Web shop Design
-
- General
- Layout
- Sitemap
- Main page
-
- Style and design
-
- Cascading Style Sheets
- Pages
-
- Dynamics
-
- Setup
- Current year
- Navigation Menu
- List of Products
- Company details
-
- External files
-
- Navigation Menu
- Header
- Footer
-
- Input processing
-
- ``Buy Now links
- Select options
-
- Javascript
-
- Simple use case
-
- Cookies and Sessions
-
- Cookies
- Hit counter
- Language selection
- User Accounts
-
- Database
-
- Tables
- PHP
-
- Web service
-
- Map
- Weather
-
- Data export
-
- JSON
-
- Messaging
-
- MQTT
-
- Localisation (L10n)
- Templates
-
- Template
- Content
-
- Development
-
- Web server
- Database server
- Versions
- Setup infrastructure
- Git respository
- Documentation
-
- Indices and tables
-
KAPITEL 7
Javascript
Over the years Javascript became a very popular programming language The webshop is using Javascript at a coupleof places
71 Simple use case
Javascript makes it easy to access elements in the DOM Setting the focus is a nice way to support the user with inputform
ltscript language=javascriptgtfunction setFocus()
documentforms[login][username]focus()
ltscriptgtltheadgtltbody onload=setFocus()gt
Another one is to check if something was entered in an input field
function validateForm() var username = documentforms[rdquologinrdquo][rdquousernamerdquo]value if (username== null || username == ldquordquo)
documentforms[rdquologinrdquo][rdquousernamerdquo]stylebackgroundColor = ldquoFF9999rdquo docu-mentforms[rdquologinrdquo][rdquousernamerdquo]placeholder = ldquoPlease your usernamerdquo docu-mentforms[rdquologinrdquo][rdquousernamerdquo]focus() return false
A simple message is informing the user about an action which was taken against the database
echo ltscript type=textjavascriptgtalert(New entry $entry added successfully)windowlocation = tablesphp
ltscriptgt
The delete process is only executed if the user confirm to delete a record
ltform action=scriptsdelete-processphp onSubmit=return confirm(rsquoAre you sure to delete this entryrsquo) method=POSTgtltinput type=hidden name=table value=$sectiongtltinput type=hidden name=id value=$result-gtidgtltinput type=submit name=Submit value=Deletegt
ltformgt
For additional Javascript please check the source of the indexphp file and the reflsquowebservicelsquo_ section
21
Shop Documentation Release 001
22 Kapitel 7 Javascript
KAPITEL 8
Cookies and Sessions
The built-in support for sessions in PHP is handling all cookie manipulation to provide persistent variables that areaccessible from different pages and across multiple visits to the site
81 Cookies
A cookie is used to track the last time a visitor check the front page The cookie is set when a visitor arrives
function lastVisit($name $expire) $value = getDateDMY() - getTimeHM()setcookie($name $value time() + $expire rsquorsquo $_SERVER[rsquoSERVER_NAMErsquo] true true)
In the footer of the index page the details are presented
ltphpif(isset($_COOKIE[rsquoLastVisitrsquo]))
$last = $_COOKIE[rsquoLastVisitrsquo]echo You last visited us on $last
else echo This is your first visit
gt
82 Hit counter
As a simple show case for PHP sessions a hit counter for the front page is available
ltphpsession_start()
$_SESSION[rsquohitsrsquo] = $_SESSION[rsquohitsrsquo] + 1gt
Included in the footer it shous the users the total of visits
echo Total $_SESSION[rsquohitsrsquo] visits of this page
23
Shop Documentation Release 001
83 Language selection
84 User Accounts
24 Kapitel 8 Cookies and Sessions
KAPITEL 9
Database
The database backend for the webshop will be MariaDB which is the drop-in replacement for MySQL
For the setup please check the Development section in this documentation
91 Tables
The following tables are needed for the webshop to work
bull products
bull customers
bull pencils
bull colors
bull hardness
bull options
bull users
Please use the develwebshopsql to setup the database
92 PHP
Below you find the configuration file for a default installation of the webshop This file is a template and filled duringthe setup process
ltphp$host = localhost$user = root$password = webshop$dbase = webshop$connection = new mysqli($host $user $password $dbase)
if ($connection-gtconnect_errno) echo Failed to connect to MariaDBMySQL ($connection-gtconnect_errno) $connection-gtconnect_error
mysqli_report(MYSQLI_REPORT_ERROR)
gt
25
Shop Documentation Release 001
All connections to the database are done in the same way Below you find an example Everything is done in theobject-oriented style
ltphprequire_once(rsquoconfigdbconnectphprsquo)if ($connection-gtconnect_errno == 0)
$sql = SELECT FROM products$results = $connection-gtquery($sql)echo $results-gtnum_rows$results-gtclose()
else echo Database connection error
gt
26 Kapitel 9 Database
KAPITEL 10
Web service
Tow web services are integrated to take advantages of online available data sources
101 Map
Leafletjs a JavaScript library for working with interactive maps from OpenStreetMap (OSM) is implemented as ashow case for a simple web service
The basic steps to integrate a map is shown below
ltdiv id=map class=map style=width 600px height 400pxgtltdivgt
ltscript src=scriptsleafletjsgtltscriptgtltscript src=scriptsleaflet-providersjsgtltscriptgtltscriptgtvar map = Lmap(rsquomaprsquo
center [250472 -773255]zoom 12zoomControl true
)
var defaultLayer = LtileLayerprovider(rsquoOpenStreetMapMapnikrsquo)addTo(map)ltscriptgt
102 Weather
The OpenWeatherMap service provides free weather data and a forecast API for web applications
ltphp Details about the API httpbugsopenweathermaporgprojectsapiwikiApi_2_5_weather$url = rsquohttpapiopenweathermaporgdata25weatherq=Bernechampunit=metricsampmode=jsonrsquo
$json = file_get_contents($url)$data = json_decode($json)
$tempC = round((27315 - $data-gtmain-gttemp)100) 100$humidity = $data-gtmain-gthumidity$pressure = $data-gtmain-gtpressure
27
Shop Documentation Release 001
echo ltpgtTemperatur $tempC degCltbrgtnecho Luftfeuchtigkeit $humidity ltbrgtnecho Luftdruck $pressure Paltpgtn
gt
28 Kapitel 10 Web service
KAPITEL 11
Data export
111 PDF
FPDF is a PHP class that allows to generate PDF files with pure PHP As a showcase for that the product specificationsfor a given product are filled in a pdf and showed in the browser The user can then decide to download or print thefile
112 JSON
JavaScript Object Notation (JSON) is a lightweight data-interchange format The format is language independent andPHP support the encoding and the decoding JSON with json_encode($data) and json_decode($data)$rows = array()$sql = SELECT FROM products$results = $connection-gtquery($sql)while ($result = $results-gtfetch_object())
$rows[] = $result$results-gtclose()
Writing all rows to a JSON file$fp = fopen(rsquopencilsjsonrsquo rsquowrsquo)fwrite($fp json_encode($rows))fclose($fp)gt
and for reading it
ltphp$json = file_get_contents(rsquopencilsjsonrsquo)print_r(json_decode($json))
gt
29
Shop Documentation Release 001
30 Kapitel 11 Data export
KAPITEL 12
Messaging
Beside standard email messages the webshop supports sending MQ Telemetry Transport protocol (MQTT) messagesas an additional feature The MQTT messages are small
121 MQTT
Mosquitto-PHP is used as a PHP wrapper for MQTT Please check the Projectrsquos README for details about theinstallation and the setup
1211 Broker
Mosquitto is a message broker that implements the MQ Telemetry Transport protocol Check if mosquitto is run-ning
$ sudo systemctl status mosquittoservice
If not start it
$ systemctl start mosquittoservice
All messages are published to the topic webshop
1212 Publishing
After the installation of Mosquitto-PHP the snipplet shown below sends a single message
ltphpdefine(rsquoBROKERrsquo rsquolocalhostrsquo)define(rsquoPORTrsquo 1883)define(rsquoCLIENT_IDrsquo webshop_ + getmypid())$topic = webshop$subtopic = test$completeTopic = $topic$subtopic
$client = new MosquittoClient(CLIENT_ID)$client-gtconnect(BROKER PORT 60)
$message = Test message from webshop at date(Y-m-d His)$client-gtpublish($completeTopic $message 0 false)
gt
31
Shop Documentation Release 001
1213 Subscribing
To read the messages sent by the webshop a client is needed The Mosquitto broker contain a simple command-linetool for subscribing to various topics
$ mosquitto_sub -h localhost -t webshop
122 Email
This section doesnrsquot describe the installation and configuration of a local MTA There are enough resources thatcontains information about the setup of postfix for local delivery only
If you want to test the email feature add the following code in one of PHP pages
ltphp mail(rsquorootlocalhostrsquo rsquoTest message from webshoprsquo rsquoThe webshop is selling pencilsrsquo) gt
By default SELinux is running in Enforcing mode which is restrictive about about what a web server can do Toallow sending email the following SELinux boolean needs to changed
setsebool -P httpd_can_network_connect=1 setsebool -P httpd_can_sendmail=1
32 Kapitel 12 Messaging
KAPITEL 13
Localisation (L10n)
There are several ways to add localisation to a web site For small projects arrays with string can work but this is notvery efficient and user-friendly With Gettext is a toolset available that provide a framework to produce multi-lingualcontent in a wide area of programming languages
Make sure that the php-gettext package is available on your system If not install it
$ sudo yum -y install php-php-gettext
Check if gettext support is available
ltphpif (function_exists(gettext))
echo gettext is not installednelse
echo gettext is supportedn
gt
Make sure that all locales your want are available on the server
locale -a
The first step is to mark all string which should be translatable as shown below For further details please refer to theGettext documentation
echo _(rsquoSome textrsquo)
The next step is to extract all strings
xgettext --from-code=UTF-8 -o localewebshoppot php scriptsphp
To re-generate the file after an update join the strings
xgettext -j --from-code=UTF-8 -o localewebshoppot php scriptsphp
For every language a po file is needed for the transations Generate it with the command mentioned below
msginit --no-translator -l de_CH -o localede_CHpo -i localewebshoppot
Once created there are only updates of the message catalog needed in the futures
msgmerge -U localede_CHpo localewebshoppot
If you re finish create the mo file for the specific language
33
Shop Documentation Release 001
msgfmt -c -v -o localede_CHLC_MESSAGESwebshopmo localede_CHpo
34 Kapitel 13 Localisation (L10n)
KAPITEL 14
Templates
Beside other solutions Savant3 is a lightweight object-oriented template system for PHP This solution does not needa lot of additional configuration
141 Template
A simple template file looks like the one shown below
lthtmlgtltheadgt
lttitlegtltphp echo $this-gteprint($this-gttitle) gtlttitlegtltheadgtltbodygt
ltphp echo $this-gteprint($this-gtcontent) gtltbodygt
lthtmlgt
For a more detailed intro check this article on Zend Developer Zone
142 Content
To fill the template with data all wished variables needs to be defined in a seperate PHP file
ltphprequire_once rsquoscriptsSavant3phprsquo$tpl = new Savant3()
Create a title$title = Simple sample page
Create the content of the page$content = Some sample text to show
Assign values to the Savant instance$tpl-gttitle = $title$tpl-gtcontent = $content
Define the template source file to show$tpl-gtdisplay(rsquosimpletplphprsquo)
gt
35
Shop Documentation Release 001
The webshop contains a page (master)
36 Kapitel 14 Templates
KAPITEL 15
Development
This sections describes the configuration of the development and runtime environment for the web shop
151 Web server
Instead of Apache the project is running on Lighttpd The reasons are that Lighttpd provides faster setup easierconfiguration and better performance Lighttpd is running with FastCGI
The path of the web server is varwwwlighttpd and the SELinux configuration are still the defaults
The web server is running in SSL-only mode and the certificate is generated during the server setup process
152 Database server
For persistence storage the drop-in replacement MariaDB is used MySQL will work to but this is not tested phpMyAd-min is available under phpmyadmin on the web server beside the command-line tools for easy administration
The default credentials for phpMyAdmin are rootwebshop or the entry you made in the Ansible playbookdevelvariablessensitiveyml
153 Versions
The web shop is built with the below listed components and tested Other releases can be used and may work but thiswill not be tested Probably it will work with different releases
bull Operating system Fedora 20
bull Kernel 3135-202fc20x86_64
bull Lighttpd 1434
bull PHP 557
bull MariaDB 5534
For communication postfix and mosquitto are needed additionally
37
Shop Documentation Release 001
154 Setup infrastructure
1541 Configuration management
For the creation of reproducable and identical environment for the development and the run-time across differentsystems Ansible is used as configuration management solution All needed steps of the installation are automated Theconfiguration doesnrsquot differentiate between local or remote installations This matters only for the deployment of theweb content
For local development itrsquos possible to use an LX container
$ sudo ansible-playbook develcontaineryml
To get everything running some additional steps (check the network inside the container generate keys etc) areneeded After you are done check it
$ sudo ansible webshop -m setup
From the management system
$ sudo ssh-copy-id -i rootsshid_rsapub root[IP address of your managed node]
The configuration of Ansible itself (adding the system to etcansiblehosts and copying the SSH keys) isnot documented at this place There are various resources available like here All playbooks are located in the folderdevel Start the setup with the command shown below
$ sudo ansible-playbook develsetupyml
The used group name in etcansiblehosts is webshop
If the setup completes without errors then the web server is accessible and show a default page Please keep in mindthat the server is only accessible over https unencrypted traffic is not allowed
1542 DeploymentSetup website
For the simple deployment of the lastest version of the shop a playbook called deployyml is provided Thisplaybook put all files in place
$ sudo ansible-playbook develdeployyml
To full deploy the webshop all tables in the database must exist The file webshopsql contains all needed SQLcommands and sample data for the web application
Itrsquos possible to deploy the website manually but this is not recommended A couple of files are depending on templateswhich are created during the deployment
Itrsquos also not recommanded to clone everything into your webserver root This would save you the trouble of doing itby hand but third-party features are missing then Those missing parts are the template engine the pdf generation theconnection to Openstreetmap and probably other things not mentioned here
155 Git respository
All project relevante informations (Source code templates documentation etc) is located in a public Git repositoryon Github
38 Kapitel 15 Development
Shop Documentation Release 001
156 Documentation
The documentation is using reStructuredText as markup language For a local build Sphinx is needed Sphinx isavailable in the Fedora Package Collection and can be installed with yum or any other package management tool
yum -y install python-sphinx python-docutils
The source files of the documentation are located under docs
$ cd docs$ make html
The output is stored under docs_buildhtml
After every push to Github a hook launch a rebuild of the documentation The latest release will be published on Readthe Docs automatically
httpsshoprtfdorg
156 Documentation 39
Shop Documentation Release 001
40 Kapitel 15 Development
KAPITEL 16
Indices and tables
bull genindex
bull modindex
bull search
41
- Basics
-
- Products
- Personas
- Use cases
- Design principles
-
- Web shop Design
-
- General
- Layout
- Sitemap
- Main page
-
- Style and design
-
- Cascading Style Sheets
- Pages
-
- Dynamics
-
- Setup
- Current year
- Navigation Menu
- List of Products
- Company details
-
- External files
-
- Navigation Menu
- Header
- Footer
-
- Input processing
-
- ``Buy Now links
- Select options
-
- Javascript
-
- Simple use case
-
- Cookies and Sessions
-
- Cookies
- Hit counter
- Language selection
- User Accounts
-
- Database
-
- Tables
- PHP
-
- Web service
-
- Map
- Weather
-
- Data export
-
- JSON
-
- Messaging
-
- MQTT
-
- Localisation (L10n)
- Templates
-
- Template
- Content
-
- Development
-
- Web server
- Database server
- Versions
- Setup infrastructure
- Git respository
- Documentation
-
- Indices and tables
-
Shop Documentation Release 001
22 Kapitel 7 Javascript
KAPITEL 8
Cookies and Sessions
The built-in support for sessions in PHP is handling all cookie manipulation to provide persistent variables that areaccessible from different pages and across multiple visits to the site
81 Cookies
A cookie is used to track the last time a visitor check the front page The cookie is set when a visitor arrives
function lastVisit($name $expire) $value = getDateDMY() - getTimeHM()setcookie($name $value time() + $expire rsquorsquo $_SERVER[rsquoSERVER_NAMErsquo] true true)
In the footer of the index page the details are presented
ltphpif(isset($_COOKIE[rsquoLastVisitrsquo]))
$last = $_COOKIE[rsquoLastVisitrsquo]echo You last visited us on $last
else echo This is your first visit
gt
82 Hit counter
As a simple show case for PHP sessions a hit counter for the front page is available
ltphpsession_start()
$_SESSION[rsquohitsrsquo] = $_SESSION[rsquohitsrsquo] + 1gt
Included in the footer it shous the users the total of visits
echo Total $_SESSION[rsquohitsrsquo] visits of this page
23
Shop Documentation Release 001
83 Language selection
84 User Accounts
24 Kapitel 8 Cookies and Sessions
KAPITEL 9
Database
The database backend for the webshop will be MariaDB which is the drop-in replacement for MySQL
For the setup please check the Development section in this documentation
91 Tables
The following tables are needed for the webshop to work
bull products
bull customers
bull pencils
bull colors
bull hardness
bull options
bull users
Please use the develwebshopsql to setup the database
92 PHP
Below you find the configuration file for a default installation of the webshop This file is a template and filled duringthe setup process
ltphp$host = localhost$user = root$password = webshop$dbase = webshop$connection = new mysqli($host $user $password $dbase)
if ($connection-gtconnect_errno) echo Failed to connect to MariaDBMySQL ($connection-gtconnect_errno) $connection-gtconnect_error
mysqli_report(MYSQLI_REPORT_ERROR)
gt
25
Shop Documentation Release 001
All connections to the database are done in the same way Below you find an example Everything is done in theobject-oriented style
ltphprequire_once(rsquoconfigdbconnectphprsquo)if ($connection-gtconnect_errno == 0)
$sql = SELECT FROM products$results = $connection-gtquery($sql)echo $results-gtnum_rows$results-gtclose()
else echo Database connection error
gt
26 Kapitel 9 Database
KAPITEL 10
Web service
Tow web services are integrated to take advantages of online available data sources
101 Map
Leafletjs a JavaScript library for working with interactive maps from OpenStreetMap (OSM) is implemented as ashow case for a simple web service
The basic steps to integrate a map is shown below
ltdiv id=map class=map style=width 600px height 400pxgtltdivgt
ltscript src=scriptsleafletjsgtltscriptgtltscript src=scriptsleaflet-providersjsgtltscriptgtltscriptgtvar map = Lmap(rsquomaprsquo
center [250472 -773255]zoom 12zoomControl true
)
var defaultLayer = LtileLayerprovider(rsquoOpenStreetMapMapnikrsquo)addTo(map)ltscriptgt
102 Weather
The OpenWeatherMap service provides free weather data and a forecast API for web applications
ltphp Details about the API httpbugsopenweathermaporgprojectsapiwikiApi_2_5_weather$url = rsquohttpapiopenweathermaporgdata25weatherq=Bernechampunit=metricsampmode=jsonrsquo
$json = file_get_contents($url)$data = json_decode($json)
$tempC = round((27315 - $data-gtmain-gttemp)100) 100$humidity = $data-gtmain-gthumidity$pressure = $data-gtmain-gtpressure
27
Shop Documentation Release 001
echo ltpgtTemperatur $tempC degCltbrgtnecho Luftfeuchtigkeit $humidity ltbrgtnecho Luftdruck $pressure Paltpgtn
gt
28 Kapitel 10 Web service
KAPITEL 11
Data export
111 PDF
FPDF is a PHP class that allows to generate PDF files with pure PHP As a showcase for that the product specificationsfor a given product are filled in a pdf and showed in the browser The user can then decide to download or print thefile
112 JSON
JavaScript Object Notation (JSON) is a lightweight data-interchange format The format is language independent andPHP support the encoding and the decoding JSON with json_encode($data) and json_decode($data)$rows = array()$sql = SELECT FROM products$results = $connection-gtquery($sql)while ($result = $results-gtfetch_object())
$rows[] = $result$results-gtclose()
Writing all rows to a JSON file$fp = fopen(rsquopencilsjsonrsquo rsquowrsquo)fwrite($fp json_encode($rows))fclose($fp)gt
and for reading it
ltphp$json = file_get_contents(rsquopencilsjsonrsquo)print_r(json_decode($json))
gt
29
Shop Documentation Release 001
30 Kapitel 11 Data export
KAPITEL 12
Messaging
Beside standard email messages the webshop supports sending MQ Telemetry Transport protocol (MQTT) messagesas an additional feature The MQTT messages are small
121 MQTT
Mosquitto-PHP is used as a PHP wrapper for MQTT Please check the Projectrsquos README for details about theinstallation and the setup
1211 Broker
Mosquitto is a message broker that implements the MQ Telemetry Transport protocol Check if mosquitto is run-ning
$ sudo systemctl status mosquittoservice
If not start it
$ systemctl start mosquittoservice
All messages are published to the topic webshop
1212 Publishing
After the installation of Mosquitto-PHP the snipplet shown below sends a single message
ltphpdefine(rsquoBROKERrsquo rsquolocalhostrsquo)define(rsquoPORTrsquo 1883)define(rsquoCLIENT_IDrsquo webshop_ + getmypid())$topic = webshop$subtopic = test$completeTopic = $topic$subtopic
$client = new MosquittoClient(CLIENT_ID)$client-gtconnect(BROKER PORT 60)
$message = Test message from webshop at date(Y-m-d His)$client-gtpublish($completeTopic $message 0 false)
gt
31
Shop Documentation Release 001
1213 Subscribing
To read the messages sent by the webshop a client is needed The Mosquitto broker contain a simple command-linetool for subscribing to various topics
$ mosquitto_sub -h localhost -t webshop
122 Email
This section doesnrsquot describe the installation and configuration of a local MTA There are enough resources thatcontains information about the setup of postfix for local delivery only
If you want to test the email feature add the following code in one of PHP pages
ltphp mail(rsquorootlocalhostrsquo rsquoTest message from webshoprsquo rsquoThe webshop is selling pencilsrsquo) gt
By default SELinux is running in Enforcing mode which is restrictive about about what a web server can do Toallow sending email the following SELinux boolean needs to changed
setsebool -P httpd_can_network_connect=1 setsebool -P httpd_can_sendmail=1
32 Kapitel 12 Messaging
KAPITEL 13
Localisation (L10n)
There are several ways to add localisation to a web site For small projects arrays with string can work but this is notvery efficient and user-friendly With Gettext is a toolset available that provide a framework to produce multi-lingualcontent in a wide area of programming languages
Make sure that the php-gettext package is available on your system If not install it
$ sudo yum -y install php-php-gettext
Check if gettext support is available
ltphpif (function_exists(gettext))
echo gettext is not installednelse
echo gettext is supportedn
gt
Make sure that all locales your want are available on the server
locale -a
The first step is to mark all string which should be translatable as shown below For further details please refer to theGettext documentation
echo _(rsquoSome textrsquo)
The next step is to extract all strings
xgettext --from-code=UTF-8 -o localewebshoppot php scriptsphp
To re-generate the file after an update join the strings
xgettext -j --from-code=UTF-8 -o localewebshoppot php scriptsphp
For every language a po file is needed for the transations Generate it with the command mentioned below
msginit --no-translator -l de_CH -o localede_CHpo -i localewebshoppot
Once created there are only updates of the message catalog needed in the futures
msgmerge -U localede_CHpo localewebshoppot
If you re finish create the mo file for the specific language
33
Shop Documentation Release 001
msgfmt -c -v -o localede_CHLC_MESSAGESwebshopmo localede_CHpo
34 Kapitel 13 Localisation (L10n)
KAPITEL 14
Templates
Beside other solutions Savant3 is a lightweight object-oriented template system for PHP This solution does not needa lot of additional configuration
141 Template
A simple template file looks like the one shown below
lthtmlgtltheadgt
lttitlegtltphp echo $this-gteprint($this-gttitle) gtlttitlegtltheadgtltbodygt
ltphp echo $this-gteprint($this-gtcontent) gtltbodygt
lthtmlgt
For a more detailed intro check this article on Zend Developer Zone
142 Content
To fill the template with data all wished variables needs to be defined in a seperate PHP file
ltphprequire_once rsquoscriptsSavant3phprsquo$tpl = new Savant3()
Create a title$title = Simple sample page
Create the content of the page$content = Some sample text to show
Assign values to the Savant instance$tpl-gttitle = $title$tpl-gtcontent = $content
Define the template source file to show$tpl-gtdisplay(rsquosimpletplphprsquo)
gt
35
Shop Documentation Release 001
The webshop contains a page (master)
36 Kapitel 14 Templates
KAPITEL 15
Development
This sections describes the configuration of the development and runtime environment for the web shop
151 Web server
Instead of Apache the project is running on Lighttpd The reasons are that Lighttpd provides faster setup easierconfiguration and better performance Lighttpd is running with FastCGI
The path of the web server is varwwwlighttpd and the SELinux configuration are still the defaults
The web server is running in SSL-only mode and the certificate is generated during the server setup process
152 Database server
For persistence storage the drop-in replacement MariaDB is used MySQL will work to but this is not tested phpMyAd-min is available under phpmyadmin on the web server beside the command-line tools for easy administration
The default credentials for phpMyAdmin are rootwebshop or the entry you made in the Ansible playbookdevelvariablessensitiveyml
153 Versions
The web shop is built with the below listed components and tested Other releases can be used and may work but thiswill not be tested Probably it will work with different releases
bull Operating system Fedora 20
bull Kernel 3135-202fc20x86_64
bull Lighttpd 1434
bull PHP 557
bull MariaDB 5534
For communication postfix and mosquitto are needed additionally
37
Shop Documentation Release 001
154 Setup infrastructure
1541 Configuration management
For the creation of reproducable and identical environment for the development and the run-time across differentsystems Ansible is used as configuration management solution All needed steps of the installation are automated Theconfiguration doesnrsquot differentiate between local or remote installations This matters only for the deployment of theweb content
For local development itrsquos possible to use an LX container
$ sudo ansible-playbook develcontaineryml
To get everything running some additional steps (check the network inside the container generate keys etc) areneeded After you are done check it
$ sudo ansible webshop -m setup
From the management system
$ sudo ssh-copy-id -i rootsshid_rsapub root[IP address of your managed node]
The configuration of Ansible itself (adding the system to etcansiblehosts and copying the SSH keys) isnot documented at this place There are various resources available like here All playbooks are located in the folderdevel Start the setup with the command shown below
$ sudo ansible-playbook develsetupyml
The used group name in etcansiblehosts is webshop
If the setup completes without errors then the web server is accessible and show a default page Please keep in mindthat the server is only accessible over https unencrypted traffic is not allowed
1542 DeploymentSetup website
For the simple deployment of the lastest version of the shop a playbook called deployyml is provided Thisplaybook put all files in place
$ sudo ansible-playbook develdeployyml
To full deploy the webshop all tables in the database must exist The file webshopsql contains all needed SQLcommands and sample data for the web application
Itrsquos possible to deploy the website manually but this is not recommended A couple of files are depending on templateswhich are created during the deployment
Itrsquos also not recommanded to clone everything into your webserver root This would save you the trouble of doing itby hand but third-party features are missing then Those missing parts are the template engine the pdf generation theconnection to Openstreetmap and probably other things not mentioned here
155 Git respository
All project relevante informations (Source code templates documentation etc) is located in a public Git repositoryon Github
38 Kapitel 15 Development
Shop Documentation Release 001
156 Documentation
The documentation is using reStructuredText as markup language For a local build Sphinx is needed Sphinx isavailable in the Fedora Package Collection and can be installed with yum or any other package management tool
yum -y install python-sphinx python-docutils
The source files of the documentation are located under docs
$ cd docs$ make html
The output is stored under docs_buildhtml
After every push to Github a hook launch a rebuild of the documentation The latest release will be published on Readthe Docs automatically
httpsshoprtfdorg
156 Documentation 39
Shop Documentation Release 001
40 Kapitel 15 Development
KAPITEL 16
Indices and tables
bull genindex
bull modindex
bull search
41
- Basics
-
- Products
- Personas
- Use cases
- Design principles
-
- Web shop Design
-
- General
- Layout
- Sitemap
- Main page
-
- Style and design
-
- Cascading Style Sheets
- Pages
-
- Dynamics
-
- Setup
- Current year
- Navigation Menu
- List of Products
- Company details
-
- External files
-
- Navigation Menu
- Header
- Footer
-
- Input processing
-
- ``Buy Now links
- Select options
-
- Javascript
-
- Simple use case
-
- Cookies and Sessions
-
- Cookies
- Hit counter
- Language selection
- User Accounts
-
- Database
-
- Tables
- PHP
-
- Web service
-
- Map
- Weather
-
- Data export
-
- JSON
-
- Messaging
-
- MQTT
-
- Localisation (L10n)
- Templates
-
- Template
- Content
-
- Development
-
- Web server
- Database server
- Versions
- Setup infrastructure
- Git respository
- Documentation
-
- Indices and tables
-
KAPITEL 8
Cookies and Sessions
The built-in support for sessions in PHP is handling all cookie manipulation to provide persistent variables that areaccessible from different pages and across multiple visits to the site
81 Cookies
A cookie is used to track the last time a visitor check the front page The cookie is set when a visitor arrives
function lastVisit($name $expire) $value = getDateDMY() - getTimeHM()setcookie($name $value time() + $expire rsquorsquo $_SERVER[rsquoSERVER_NAMErsquo] true true)
In the footer of the index page the details are presented
ltphpif(isset($_COOKIE[rsquoLastVisitrsquo]))
$last = $_COOKIE[rsquoLastVisitrsquo]echo You last visited us on $last
else echo This is your first visit
gt
82 Hit counter
As a simple show case for PHP sessions a hit counter for the front page is available
ltphpsession_start()
$_SESSION[rsquohitsrsquo] = $_SESSION[rsquohitsrsquo] + 1gt
Included in the footer it shous the users the total of visits
echo Total $_SESSION[rsquohitsrsquo] visits of this page
23
Shop Documentation Release 001
83 Language selection
84 User Accounts
24 Kapitel 8 Cookies and Sessions
KAPITEL 9
Database
The database backend for the webshop will be MariaDB which is the drop-in replacement for MySQL
For the setup please check the Development section in this documentation
91 Tables
The following tables are needed for the webshop to work
bull products
bull customers
bull pencils
bull colors
bull hardness
bull options
bull users
Please use the develwebshopsql to setup the database
92 PHP
Below you find the configuration file for a default installation of the webshop This file is a template and filled duringthe setup process
ltphp$host = localhost$user = root$password = webshop$dbase = webshop$connection = new mysqli($host $user $password $dbase)
if ($connection-gtconnect_errno) echo Failed to connect to MariaDBMySQL ($connection-gtconnect_errno) $connection-gtconnect_error
mysqli_report(MYSQLI_REPORT_ERROR)
gt
25
Shop Documentation Release 001
All connections to the database are done in the same way Below you find an example Everything is done in theobject-oriented style
ltphprequire_once(rsquoconfigdbconnectphprsquo)if ($connection-gtconnect_errno == 0)
$sql = SELECT FROM products$results = $connection-gtquery($sql)echo $results-gtnum_rows$results-gtclose()
else echo Database connection error
gt
26 Kapitel 9 Database
KAPITEL 10
Web service
Tow web services are integrated to take advantages of online available data sources
101 Map
Leafletjs a JavaScript library for working with interactive maps from OpenStreetMap (OSM) is implemented as ashow case for a simple web service
The basic steps to integrate a map is shown below
ltdiv id=map class=map style=width 600px height 400pxgtltdivgt
ltscript src=scriptsleafletjsgtltscriptgtltscript src=scriptsleaflet-providersjsgtltscriptgtltscriptgtvar map = Lmap(rsquomaprsquo
center [250472 -773255]zoom 12zoomControl true
)
var defaultLayer = LtileLayerprovider(rsquoOpenStreetMapMapnikrsquo)addTo(map)ltscriptgt
102 Weather
The OpenWeatherMap service provides free weather data and a forecast API for web applications
ltphp Details about the API httpbugsopenweathermaporgprojectsapiwikiApi_2_5_weather$url = rsquohttpapiopenweathermaporgdata25weatherq=Bernechampunit=metricsampmode=jsonrsquo
$json = file_get_contents($url)$data = json_decode($json)
$tempC = round((27315 - $data-gtmain-gttemp)100) 100$humidity = $data-gtmain-gthumidity$pressure = $data-gtmain-gtpressure
27
Shop Documentation Release 001
echo ltpgtTemperatur $tempC degCltbrgtnecho Luftfeuchtigkeit $humidity ltbrgtnecho Luftdruck $pressure Paltpgtn
gt
28 Kapitel 10 Web service
KAPITEL 11
Data export
111 PDF
FPDF is a PHP class that allows to generate PDF files with pure PHP As a showcase for that the product specificationsfor a given product are filled in a pdf and showed in the browser The user can then decide to download or print thefile
112 JSON
JavaScript Object Notation (JSON) is a lightweight data-interchange format The format is language independent andPHP support the encoding and the decoding JSON with json_encode($data) and json_decode($data)$rows = array()$sql = SELECT FROM products$results = $connection-gtquery($sql)while ($result = $results-gtfetch_object())
$rows[] = $result$results-gtclose()
Writing all rows to a JSON file$fp = fopen(rsquopencilsjsonrsquo rsquowrsquo)fwrite($fp json_encode($rows))fclose($fp)gt
and for reading it
ltphp$json = file_get_contents(rsquopencilsjsonrsquo)print_r(json_decode($json))
gt
29
Shop Documentation Release 001
30 Kapitel 11 Data export
KAPITEL 12
Messaging
Beside standard email messages the webshop supports sending MQ Telemetry Transport protocol (MQTT) messagesas an additional feature The MQTT messages are small
121 MQTT
Mosquitto-PHP is used as a PHP wrapper for MQTT Please check the Projectrsquos README for details about theinstallation and the setup
1211 Broker
Mosquitto is a message broker that implements the MQ Telemetry Transport protocol Check if mosquitto is run-ning
$ sudo systemctl status mosquittoservice
If not start it
$ systemctl start mosquittoservice
All messages are published to the topic webshop
1212 Publishing
After the installation of Mosquitto-PHP the snipplet shown below sends a single message
ltphpdefine(rsquoBROKERrsquo rsquolocalhostrsquo)define(rsquoPORTrsquo 1883)define(rsquoCLIENT_IDrsquo webshop_ + getmypid())$topic = webshop$subtopic = test$completeTopic = $topic$subtopic
$client = new MosquittoClient(CLIENT_ID)$client-gtconnect(BROKER PORT 60)
$message = Test message from webshop at date(Y-m-d His)$client-gtpublish($completeTopic $message 0 false)
gt
31
Shop Documentation Release 001
1213 Subscribing
To read the messages sent by the webshop a client is needed The Mosquitto broker contain a simple command-linetool for subscribing to various topics
$ mosquitto_sub -h localhost -t webshop
122 Email
This section doesnrsquot describe the installation and configuration of a local MTA There are enough resources thatcontains information about the setup of postfix for local delivery only
If you want to test the email feature add the following code in one of PHP pages
ltphp mail(rsquorootlocalhostrsquo rsquoTest message from webshoprsquo rsquoThe webshop is selling pencilsrsquo) gt
By default SELinux is running in Enforcing mode which is restrictive about about what a web server can do Toallow sending email the following SELinux boolean needs to changed
setsebool -P httpd_can_network_connect=1 setsebool -P httpd_can_sendmail=1
32 Kapitel 12 Messaging
KAPITEL 13
Localisation (L10n)
There are several ways to add localisation to a web site For small projects arrays with string can work but this is notvery efficient and user-friendly With Gettext is a toolset available that provide a framework to produce multi-lingualcontent in a wide area of programming languages
Make sure that the php-gettext package is available on your system If not install it
$ sudo yum -y install php-php-gettext
Check if gettext support is available
ltphpif (function_exists(gettext))
echo gettext is not installednelse
echo gettext is supportedn
gt
Make sure that all locales your want are available on the server
locale -a
The first step is to mark all string which should be translatable as shown below For further details please refer to theGettext documentation
echo _(rsquoSome textrsquo)
The next step is to extract all strings
xgettext --from-code=UTF-8 -o localewebshoppot php scriptsphp
To re-generate the file after an update join the strings
xgettext -j --from-code=UTF-8 -o localewebshoppot php scriptsphp
For every language a po file is needed for the transations Generate it with the command mentioned below
msginit --no-translator -l de_CH -o localede_CHpo -i localewebshoppot
Once created there are only updates of the message catalog needed in the futures
msgmerge -U localede_CHpo localewebshoppot
If you re finish create the mo file for the specific language
33
Shop Documentation Release 001
msgfmt -c -v -o localede_CHLC_MESSAGESwebshopmo localede_CHpo
34 Kapitel 13 Localisation (L10n)
KAPITEL 14
Templates
Beside other solutions Savant3 is a lightweight object-oriented template system for PHP This solution does not needa lot of additional configuration
141 Template
A simple template file looks like the one shown below
lthtmlgtltheadgt
lttitlegtltphp echo $this-gteprint($this-gttitle) gtlttitlegtltheadgtltbodygt
ltphp echo $this-gteprint($this-gtcontent) gtltbodygt
lthtmlgt
For a more detailed intro check this article on Zend Developer Zone
142 Content
To fill the template with data all wished variables needs to be defined in a seperate PHP file
ltphprequire_once rsquoscriptsSavant3phprsquo$tpl = new Savant3()
Create a title$title = Simple sample page
Create the content of the page$content = Some sample text to show
Assign values to the Savant instance$tpl-gttitle = $title$tpl-gtcontent = $content
Define the template source file to show$tpl-gtdisplay(rsquosimpletplphprsquo)
gt
35
Shop Documentation Release 001
The webshop contains a page (master)
36 Kapitel 14 Templates
KAPITEL 15
Development
This sections describes the configuration of the development and runtime environment for the web shop
151 Web server
Instead of Apache the project is running on Lighttpd The reasons are that Lighttpd provides faster setup easierconfiguration and better performance Lighttpd is running with FastCGI
The path of the web server is varwwwlighttpd and the SELinux configuration are still the defaults
The web server is running in SSL-only mode and the certificate is generated during the server setup process
152 Database server
For persistence storage the drop-in replacement MariaDB is used MySQL will work to but this is not tested phpMyAd-min is available under phpmyadmin on the web server beside the command-line tools for easy administration
The default credentials for phpMyAdmin are rootwebshop or the entry you made in the Ansible playbookdevelvariablessensitiveyml
153 Versions
The web shop is built with the below listed components and tested Other releases can be used and may work but thiswill not be tested Probably it will work with different releases
bull Operating system Fedora 20
bull Kernel 3135-202fc20x86_64
bull Lighttpd 1434
bull PHP 557
bull MariaDB 5534
For communication postfix and mosquitto are needed additionally
37
Shop Documentation Release 001
154 Setup infrastructure
1541 Configuration management
For the creation of reproducable and identical environment for the development and the run-time across differentsystems Ansible is used as configuration management solution All needed steps of the installation are automated Theconfiguration doesnrsquot differentiate between local or remote installations This matters only for the deployment of theweb content
For local development itrsquos possible to use an LX container
$ sudo ansible-playbook develcontaineryml
To get everything running some additional steps (check the network inside the container generate keys etc) areneeded After you are done check it
$ sudo ansible webshop -m setup
From the management system
$ sudo ssh-copy-id -i rootsshid_rsapub root[IP address of your managed node]
The configuration of Ansible itself (adding the system to etcansiblehosts and copying the SSH keys) isnot documented at this place There are various resources available like here All playbooks are located in the folderdevel Start the setup with the command shown below
$ sudo ansible-playbook develsetupyml
The used group name in etcansiblehosts is webshop
If the setup completes without errors then the web server is accessible and show a default page Please keep in mindthat the server is only accessible over https unencrypted traffic is not allowed
1542 DeploymentSetup website
For the simple deployment of the lastest version of the shop a playbook called deployyml is provided Thisplaybook put all files in place
$ sudo ansible-playbook develdeployyml
To full deploy the webshop all tables in the database must exist The file webshopsql contains all needed SQLcommands and sample data for the web application
Itrsquos possible to deploy the website manually but this is not recommended A couple of files are depending on templateswhich are created during the deployment
Itrsquos also not recommanded to clone everything into your webserver root This would save you the trouble of doing itby hand but third-party features are missing then Those missing parts are the template engine the pdf generation theconnection to Openstreetmap and probably other things not mentioned here
155 Git respository
All project relevante informations (Source code templates documentation etc) is located in a public Git repositoryon Github
38 Kapitel 15 Development
Shop Documentation Release 001
156 Documentation
The documentation is using reStructuredText as markup language For a local build Sphinx is needed Sphinx isavailable in the Fedora Package Collection and can be installed with yum or any other package management tool
yum -y install python-sphinx python-docutils
The source files of the documentation are located under docs
$ cd docs$ make html
The output is stored under docs_buildhtml
After every push to Github a hook launch a rebuild of the documentation The latest release will be published on Readthe Docs automatically
httpsshoprtfdorg
156 Documentation 39
Shop Documentation Release 001
40 Kapitel 15 Development
KAPITEL 16
Indices and tables
bull genindex
bull modindex
bull search
41
- Basics
-
- Products
- Personas
- Use cases
- Design principles
-
- Web shop Design
-
- General
- Layout
- Sitemap
- Main page
-
- Style and design
-
- Cascading Style Sheets
- Pages
-
- Dynamics
-
- Setup
- Current year
- Navigation Menu
- List of Products
- Company details
-
- External files
-
- Navigation Menu
- Header
- Footer
-
- Input processing
-
- ``Buy Now links
- Select options
-
- Javascript
-
- Simple use case
-
- Cookies and Sessions
-
- Cookies
- Hit counter
- Language selection
- User Accounts
-
- Database
-
- Tables
- PHP
-
- Web service
-
- Map
- Weather
-
- Data export
-
- JSON
-
- Messaging
-
- MQTT
-
- Localisation (L10n)
- Templates
-
- Template
- Content
-
- Development
-
- Web server
- Database server
- Versions
- Setup infrastructure
- Git respository
- Documentation
-
- Indices and tables
-
Shop Documentation Release 001
83 Language selection
84 User Accounts
24 Kapitel 8 Cookies and Sessions
KAPITEL 9
Database
The database backend for the webshop will be MariaDB which is the drop-in replacement for MySQL
For the setup please check the Development section in this documentation
91 Tables
The following tables are needed for the webshop to work
bull products
bull customers
bull pencils
bull colors
bull hardness
bull options
bull users
Please use the develwebshopsql to setup the database
92 PHP
Below you find the configuration file for a default installation of the webshop This file is a template and filled duringthe setup process
ltphp$host = localhost$user = root$password = webshop$dbase = webshop$connection = new mysqli($host $user $password $dbase)
if ($connection-gtconnect_errno) echo Failed to connect to MariaDBMySQL ($connection-gtconnect_errno) $connection-gtconnect_error
mysqli_report(MYSQLI_REPORT_ERROR)
gt
25
Shop Documentation Release 001
All connections to the database are done in the same way Below you find an example Everything is done in theobject-oriented style
ltphprequire_once(rsquoconfigdbconnectphprsquo)if ($connection-gtconnect_errno == 0)
$sql = SELECT FROM products$results = $connection-gtquery($sql)echo $results-gtnum_rows$results-gtclose()
else echo Database connection error
gt
26 Kapitel 9 Database
KAPITEL 10
Web service
Tow web services are integrated to take advantages of online available data sources
101 Map
Leafletjs a JavaScript library for working with interactive maps from OpenStreetMap (OSM) is implemented as ashow case for a simple web service
The basic steps to integrate a map is shown below
ltdiv id=map class=map style=width 600px height 400pxgtltdivgt
ltscript src=scriptsleafletjsgtltscriptgtltscript src=scriptsleaflet-providersjsgtltscriptgtltscriptgtvar map = Lmap(rsquomaprsquo
center [250472 -773255]zoom 12zoomControl true
)
var defaultLayer = LtileLayerprovider(rsquoOpenStreetMapMapnikrsquo)addTo(map)ltscriptgt
102 Weather
The OpenWeatherMap service provides free weather data and a forecast API for web applications
ltphp Details about the API httpbugsopenweathermaporgprojectsapiwikiApi_2_5_weather$url = rsquohttpapiopenweathermaporgdata25weatherq=Bernechampunit=metricsampmode=jsonrsquo
$json = file_get_contents($url)$data = json_decode($json)
$tempC = round((27315 - $data-gtmain-gttemp)100) 100$humidity = $data-gtmain-gthumidity$pressure = $data-gtmain-gtpressure
27
Shop Documentation Release 001
echo ltpgtTemperatur $tempC degCltbrgtnecho Luftfeuchtigkeit $humidity ltbrgtnecho Luftdruck $pressure Paltpgtn
gt
28 Kapitel 10 Web service
KAPITEL 11
Data export
111 PDF
FPDF is a PHP class that allows to generate PDF files with pure PHP As a showcase for that the product specificationsfor a given product are filled in a pdf and showed in the browser The user can then decide to download or print thefile
112 JSON
JavaScript Object Notation (JSON) is a lightweight data-interchange format The format is language independent andPHP support the encoding and the decoding JSON with json_encode($data) and json_decode($data)$rows = array()$sql = SELECT FROM products$results = $connection-gtquery($sql)while ($result = $results-gtfetch_object())
$rows[] = $result$results-gtclose()
Writing all rows to a JSON file$fp = fopen(rsquopencilsjsonrsquo rsquowrsquo)fwrite($fp json_encode($rows))fclose($fp)gt
and for reading it
ltphp$json = file_get_contents(rsquopencilsjsonrsquo)print_r(json_decode($json))
gt
29
Shop Documentation Release 001
30 Kapitel 11 Data export
KAPITEL 12
Messaging
Beside standard email messages the webshop supports sending MQ Telemetry Transport protocol (MQTT) messagesas an additional feature The MQTT messages are small
121 MQTT
Mosquitto-PHP is used as a PHP wrapper for MQTT Please check the Projectrsquos README for details about theinstallation and the setup
1211 Broker
Mosquitto is a message broker that implements the MQ Telemetry Transport protocol Check if mosquitto is run-ning
$ sudo systemctl status mosquittoservice
If not start it
$ systemctl start mosquittoservice
All messages are published to the topic webshop
1212 Publishing
After the installation of Mosquitto-PHP the snipplet shown below sends a single message
ltphpdefine(rsquoBROKERrsquo rsquolocalhostrsquo)define(rsquoPORTrsquo 1883)define(rsquoCLIENT_IDrsquo webshop_ + getmypid())$topic = webshop$subtopic = test$completeTopic = $topic$subtopic
$client = new MosquittoClient(CLIENT_ID)$client-gtconnect(BROKER PORT 60)
$message = Test message from webshop at date(Y-m-d His)$client-gtpublish($completeTopic $message 0 false)
gt
31
Shop Documentation Release 001
1213 Subscribing
To read the messages sent by the webshop a client is needed The Mosquitto broker contain a simple command-linetool for subscribing to various topics
$ mosquitto_sub -h localhost -t webshop
122 Email
This section doesnrsquot describe the installation and configuration of a local MTA There are enough resources thatcontains information about the setup of postfix for local delivery only
If you want to test the email feature add the following code in one of PHP pages
ltphp mail(rsquorootlocalhostrsquo rsquoTest message from webshoprsquo rsquoThe webshop is selling pencilsrsquo) gt
By default SELinux is running in Enforcing mode which is restrictive about about what a web server can do Toallow sending email the following SELinux boolean needs to changed
setsebool -P httpd_can_network_connect=1 setsebool -P httpd_can_sendmail=1
32 Kapitel 12 Messaging
KAPITEL 13
Localisation (L10n)
There are several ways to add localisation to a web site For small projects arrays with string can work but this is notvery efficient and user-friendly With Gettext is a toolset available that provide a framework to produce multi-lingualcontent in a wide area of programming languages
Make sure that the php-gettext package is available on your system If not install it
$ sudo yum -y install php-php-gettext
Check if gettext support is available
ltphpif (function_exists(gettext))
echo gettext is not installednelse
echo gettext is supportedn
gt
Make sure that all locales your want are available on the server
locale -a
The first step is to mark all string which should be translatable as shown below For further details please refer to theGettext documentation
echo _(rsquoSome textrsquo)
The next step is to extract all strings
xgettext --from-code=UTF-8 -o localewebshoppot php scriptsphp
To re-generate the file after an update join the strings
xgettext -j --from-code=UTF-8 -o localewebshoppot php scriptsphp
For every language a po file is needed for the transations Generate it with the command mentioned below
msginit --no-translator -l de_CH -o localede_CHpo -i localewebshoppot
Once created there are only updates of the message catalog needed in the futures
msgmerge -U localede_CHpo localewebshoppot
If you re finish create the mo file for the specific language
33
Shop Documentation Release 001
msgfmt -c -v -o localede_CHLC_MESSAGESwebshopmo localede_CHpo
34 Kapitel 13 Localisation (L10n)
KAPITEL 14
Templates
Beside other solutions Savant3 is a lightweight object-oriented template system for PHP This solution does not needa lot of additional configuration
141 Template
A simple template file looks like the one shown below
lthtmlgtltheadgt
lttitlegtltphp echo $this-gteprint($this-gttitle) gtlttitlegtltheadgtltbodygt
ltphp echo $this-gteprint($this-gtcontent) gtltbodygt
lthtmlgt
For a more detailed intro check this article on Zend Developer Zone
142 Content
To fill the template with data all wished variables needs to be defined in a seperate PHP file
ltphprequire_once rsquoscriptsSavant3phprsquo$tpl = new Savant3()
Create a title$title = Simple sample page
Create the content of the page$content = Some sample text to show
Assign values to the Savant instance$tpl-gttitle = $title$tpl-gtcontent = $content
Define the template source file to show$tpl-gtdisplay(rsquosimpletplphprsquo)
gt
35
Shop Documentation Release 001
The webshop contains a page (master)
36 Kapitel 14 Templates
KAPITEL 15
Development
This sections describes the configuration of the development and runtime environment for the web shop
151 Web server
Instead of Apache the project is running on Lighttpd The reasons are that Lighttpd provides faster setup easierconfiguration and better performance Lighttpd is running with FastCGI
The path of the web server is varwwwlighttpd and the SELinux configuration are still the defaults
The web server is running in SSL-only mode and the certificate is generated during the server setup process
152 Database server
For persistence storage the drop-in replacement MariaDB is used MySQL will work to but this is not tested phpMyAd-min is available under phpmyadmin on the web server beside the command-line tools for easy administration
The default credentials for phpMyAdmin are rootwebshop or the entry you made in the Ansible playbookdevelvariablessensitiveyml
153 Versions
The web shop is built with the below listed components and tested Other releases can be used and may work but thiswill not be tested Probably it will work with different releases
bull Operating system Fedora 20
bull Kernel 3135-202fc20x86_64
bull Lighttpd 1434
bull PHP 557
bull MariaDB 5534
For communication postfix and mosquitto are needed additionally
37
Shop Documentation Release 001
154 Setup infrastructure
1541 Configuration management
For the creation of reproducable and identical environment for the development and the run-time across differentsystems Ansible is used as configuration management solution All needed steps of the installation are automated Theconfiguration doesnrsquot differentiate between local or remote installations This matters only for the deployment of theweb content
For local development itrsquos possible to use an LX container
$ sudo ansible-playbook develcontaineryml
To get everything running some additional steps (check the network inside the container generate keys etc) areneeded After you are done check it
$ sudo ansible webshop -m setup
From the management system
$ sudo ssh-copy-id -i rootsshid_rsapub root[IP address of your managed node]
The configuration of Ansible itself (adding the system to etcansiblehosts and copying the SSH keys) isnot documented at this place There are various resources available like here All playbooks are located in the folderdevel Start the setup with the command shown below
$ sudo ansible-playbook develsetupyml
The used group name in etcansiblehosts is webshop
If the setup completes without errors then the web server is accessible and show a default page Please keep in mindthat the server is only accessible over https unencrypted traffic is not allowed
1542 DeploymentSetup website
For the simple deployment of the lastest version of the shop a playbook called deployyml is provided Thisplaybook put all files in place
$ sudo ansible-playbook develdeployyml
To full deploy the webshop all tables in the database must exist The file webshopsql contains all needed SQLcommands and sample data for the web application
Itrsquos possible to deploy the website manually but this is not recommended A couple of files are depending on templateswhich are created during the deployment
Itrsquos also not recommanded to clone everything into your webserver root This would save you the trouble of doing itby hand but third-party features are missing then Those missing parts are the template engine the pdf generation theconnection to Openstreetmap and probably other things not mentioned here
155 Git respository
All project relevante informations (Source code templates documentation etc) is located in a public Git repositoryon Github
38 Kapitel 15 Development
Shop Documentation Release 001
156 Documentation
The documentation is using reStructuredText as markup language For a local build Sphinx is needed Sphinx isavailable in the Fedora Package Collection and can be installed with yum or any other package management tool
yum -y install python-sphinx python-docutils
The source files of the documentation are located under docs
$ cd docs$ make html
The output is stored under docs_buildhtml
After every push to Github a hook launch a rebuild of the documentation The latest release will be published on Readthe Docs automatically
httpsshoprtfdorg
156 Documentation 39
Shop Documentation Release 001
40 Kapitel 15 Development
KAPITEL 16
Indices and tables
bull genindex
bull modindex
bull search
41
- Basics
-
- Products
- Personas
- Use cases
- Design principles
-
- Web shop Design
-
- General
- Layout
- Sitemap
- Main page
-
- Style and design
-
- Cascading Style Sheets
- Pages
-
- Dynamics
-
- Setup
- Current year
- Navigation Menu
- List of Products
- Company details
-
- External files
-
- Navigation Menu
- Header
- Footer
-
- Input processing
-
- ``Buy Now links
- Select options
-
- Javascript
-
- Simple use case
-
- Cookies and Sessions
-
- Cookies
- Hit counter
- Language selection
- User Accounts
-
- Database
-
- Tables
- PHP
-
- Web service
-
- Map
- Weather
-
- Data export
-
- JSON
-
- Messaging
-
- MQTT
-
- Localisation (L10n)
- Templates
-
- Template
- Content
-
- Development
-
- Web server
- Database server
- Versions
- Setup infrastructure
- Git respository
- Documentation
-
- Indices and tables
-
KAPITEL 9
Database
The database backend for the webshop will be MariaDB which is the drop-in replacement for MySQL
For the setup please check the Development section in this documentation
91 Tables
The following tables are needed for the webshop to work
bull products
bull customers
bull pencils
bull colors
bull hardness
bull options
bull users
Please use the develwebshopsql to setup the database
92 PHP
Below you find the configuration file for a default installation of the webshop This file is a template and filled duringthe setup process
ltphp$host = localhost$user = root$password = webshop$dbase = webshop$connection = new mysqli($host $user $password $dbase)
if ($connection-gtconnect_errno) echo Failed to connect to MariaDBMySQL ($connection-gtconnect_errno) $connection-gtconnect_error
mysqli_report(MYSQLI_REPORT_ERROR)
gt
25
Shop Documentation Release 001
All connections to the database are done in the same way Below you find an example Everything is done in theobject-oriented style
ltphprequire_once(rsquoconfigdbconnectphprsquo)if ($connection-gtconnect_errno == 0)
$sql = SELECT FROM products$results = $connection-gtquery($sql)echo $results-gtnum_rows$results-gtclose()
else echo Database connection error
gt
26 Kapitel 9 Database
KAPITEL 10
Web service
Tow web services are integrated to take advantages of online available data sources
101 Map
Leafletjs a JavaScript library for working with interactive maps from OpenStreetMap (OSM) is implemented as ashow case for a simple web service
The basic steps to integrate a map is shown below
ltdiv id=map class=map style=width 600px height 400pxgtltdivgt
ltscript src=scriptsleafletjsgtltscriptgtltscript src=scriptsleaflet-providersjsgtltscriptgtltscriptgtvar map = Lmap(rsquomaprsquo
center [250472 -773255]zoom 12zoomControl true
)
var defaultLayer = LtileLayerprovider(rsquoOpenStreetMapMapnikrsquo)addTo(map)ltscriptgt
102 Weather
The OpenWeatherMap service provides free weather data and a forecast API for web applications
ltphp Details about the API httpbugsopenweathermaporgprojectsapiwikiApi_2_5_weather$url = rsquohttpapiopenweathermaporgdata25weatherq=Bernechampunit=metricsampmode=jsonrsquo
$json = file_get_contents($url)$data = json_decode($json)
$tempC = round((27315 - $data-gtmain-gttemp)100) 100$humidity = $data-gtmain-gthumidity$pressure = $data-gtmain-gtpressure
27
Shop Documentation Release 001
echo ltpgtTemperatur $tempC degCltbrgtnecho Luftfeuchtigkeit $humidity ltbrgtnecho Luftdruck $pressure Paltpgtn
gt
28 Kapitel 10 Web service
KAPITEL 11
Data export
111 PDF
FPDF is a PHP class that allows to generate PDF files with pure PHP As a showcase for that the product specificationsfor a given product are filled in a pdf and showed in the browser The user can then decide to download or print thefile
112 JSON
JavaScript Object Notation (JSON) is a lightweight data-interchange format The format is language independent andPHP support the encoding and the decoding JSON with json_encode($data) and json_decode($data)$rows = array()$sql = SELECT FROM products$results = $connection-gtquery($sql)while ($result = $results-gtfetch_object())
$rows[] = $result$results-gtclose()
Writing all rows to a JSON file$fp = fopen(rsquopencilsjsonrsquo rsquowrsquo)fwrite($fp json_encode($rows))fclose($fp)gt
and for reading it
ltphp$json = file_get_contents(rsquopencilsjsonrsquo)print_r(json_decode($json))
gt
29
Shop Documentation Release 001
30 Kapitel 11 Data export
KAPITEL 12
Messaging
Beside standard email messages the webshop supports sending MQ Telemetry Transport protocol (MQTT) messagesas an additional feature The MQTT messages are small
121 MQTT
Mosquitto-PHP is used as a PHP wrapper for MQTT Please check the Projectrsquos README for details about theinstallation and the setup
1211 Broker
Mosquitto is a message broker that implements the MQ Telemetry Transport protocol Check if mosquitto is run-ning
$ sudo systemctl status mosquittoservice
If not start it
$ systemctl start mosquittoservice
All messages are published to the topic webshop
1212 Publishing
After the installation of Mosquitto-PHP the snipplet shown below sends a single message
ltphpdefine(rsquoBROKERrsquo rsquolocalhostrsquo)define(rsquoPORTrsquo 1883)define(rsquoCLIENT_IDrsquo webshop_ + getmypid())$topic = webshop$subtopic = test$completeTopic = $topic$subtopic
$client = new MosquittoClient(CLIENT_ID)$client-gtconnect(BROKER PORT 60)
$message = Test message from webshop at date(Y-m-d His)$client-gtpublish($completeTopic $message 0 false)
gt
31
Shop Documentation Release 001
1213 Subscribing
To read the messages sent by the webshop a client is needed The Mosquitto broker contain a simple command-linetool for subscribing to various topics
$ mosquitto_sub -h localhost -t webshop
122 Email
This section doesnrsquot describe the installation and configuration of a local MTA There are enough resources thatcontains information about the setup of postfix for local delivery only
If you want to test the email feature add the following code in one of PHP pages
ltphp mail(rsquorootlocalhostrsquo rsquoTest message from webshoprsquo rsquoThe webshop is selling pencilsrsquo) gt
By default SELinux is running in Enforcing mode which is restrictive about about what a web server can do Toallow sending email the following SELinux boolean needs to changed
setsebool -P httpd_can_network_connect=1 setsebool -P httpd_can_sendmail=1
32 Kapitel 12 Messaging
KAPITEL 13
Localisation (L10n)
There are several ways to add localisation to a web site For small projects arrays with string can work but this is notvery efficient and user-friendly With Gettext is a toolset available that provide a framework to produce multi-lingualcontent in a wide area of programming languages
Make sure that the php-gettext package is available on your system If not install it
$ sudo yum -y install php-php-gettext
Check if gettext support is available
ltphpif (function_exists(gettext))
echo gettext is not installednelse
echo gettext is supportedn
gt
Make sure that all locales your want are available on the server
locale -a
The first step is to mark all string which should be translatable as shown below For further details please refer to theGettext documentation
echo _(rsquoSome textrsquo)
The next step is to extract all strings
xgettext --from-code=UTF-8 -o localewebshoppot php scriptsphp
To re-generate the file after an update join the strings
xgettext -j --from-code=UTF-8 -o localewebshoppot php scriptsphp
For every language a po file is needed for the transations Generate it with the command mentioned below
msginit --no-translator -l de_CH -o localede_CHpo -i localewebshoppot
Once created there are only updates of the message catalog needed in the futures
msgmerge -U localede_CHpo localewebshoppot
If you re finish create the mo file for the specific language
33
Shop Documentation Release 001
msgfmt -c -v -o localede_CHLC_MESSAGESwebshopmo localede_CHpo
34 Kapitel 13 Localisation (L10n)
KAPITEL 14
Templates
Beside other solutions Savant3 is a lightweight object-oriented template system for PHP This solution does not needa lot of additional configuration
141 Template
A simple template file looks like the one shown below
lthtmlgtltheadgt
lttitlegtltphp echo $this-gteprint($this-gttitle) gtlttitlegtltheadgtltbodygt
ltphp echo $this-gteprint($this-gtcontent) gtltbodygt
lthtmlgt
For a more detailed intro check this article on Zend Developer Zone
142 Content
To fill the template with data all wished variables needs to be defined in a seperate PHP file
ltphprequire_once rsquoscriptsSavant3phprsquo$tpl = new Savant3()
Create a title$title = Simple sample page
Create the content of the page$content = Some sample text to show
Assign values to the Savant instance$tpl-gttitle = $title$tpl-gtcontent = $content
Define the template source file to show$tpl-gtdisplay(rsquosimpletplphprsquo)
gt
35
Shop Documentation Release 001
The webshop contains a page (master)
36 Kapitel 14 Templates
KAPITEL 15
Development
This sections describes the configuration of the development and runtime environment for the web shop
151 Web server
Instead of Apache the project is running on Lighttpd The reasons are that Lighttpd provides faster setup easierconfiguration and better performance Lighttpd is running with FastCGI
The path of the web server is varwwwlighttpd and the SELinux configuration are still the defaults
The web server is running in SSL-only mode and the certificate is generated during the server setup process
152 Database server
For persistence storage the drop-in replacement MariaDB is used MySQL will work to but this is not tested phpMyAd-min is available under phpmyadmin on the web server beside the command-line tools for easy administration
The default credentials for phpMyAdmin are rootwebshop or the entry you made in the Ansible playbookdevelvariablessensitiveyml
153 Versions
The web shop is built with the below listed components and tested Other releases can be used and may work but thiswill not be tested Probably it will work with different releases
bull Operating system Fedora 20
bull Kernel 3135-202fc20x86_64
bull Lighttpd 1434
bull PHP 557
bull MariaDB 5534
For communication postfix and mosquitto are needed additionally
37
Shop Documentation Release 001
154 Setup infrastructure
1541 Configuration management
For the creation of reproducable and identical environment for the development and the run-time across differentsystems Ansible is used as configuration management solution All needed steps of the installation are automated Theconfiguration doesnrsquot differentiate between local or remote installations This matters only for the deployment of theweb content
For local development itrsquos possible to use an LX container
$ sudo ansible-playbook develcontaineryml
To get everything running some additional steps (check the network inside the container generate keys etc) areneeded After you are done check it
$ sudo ansible webshop -m setup
From the management system
$ sudo ssh-copy-id -i rootsshid_rsapub root[IP address of your managed node]
The configuration of Ansible itself (adding the system to etcansiblehosts and copying the SSH keys) isnot documented at this place There are various resources available like here All playbooks are located in the folderdevel Start the setup with the command shown below
$ sudo ansible-playbook develsetupyml
The used group name in etcansiblehosts is webshop
If the setup completes without errors then the web server is accessible and show a default page Please keep in mindthat the server is only accessible over https unencrypted traffic is not allowed
1542 DeploymentSetup website
For the simple deployment of the lastest version of the shop a playbook called deployyml is provided Thisplaybook put all files in place
$ sudo ansible-playbook develdeployyml
To full deploy the webshop all tables in the database must exist The file webshopsql contains all needed SQLcommands and sample data for the web application
Itrsquos possible to deploy the website manually but this is not recommended A couple of files are depending on templateswhich are created during the deployment
Itrsquos also not recommanded to clone everything into your webserver root This would save you the trouble of doing itby hand but third-party features are missing then Those missing parts are the template engine the pdf generation theconnection to Openstreetmap and probably other things not mentioned here
155 Git respository
All project relevante informations (Source code templates documentation etc) is located in a public Git repositoryon Github
38 Kapitel 15 Development
Shop Documentation Release 001
156 Documentation
The documentation is using reStructuredText as markup language For a local build Sphinx is needed Sphinx isavailable in the Fedora Package Collection and can be installed with yum or any other package management tool
yum -y install python-sphinx python-docutils
The source files of the documentation are located under docs
$ cd docs$ make html
The output is stored under docs_buildhtml
After every push to Github a hook launch a rebuild of the documentation The latest release will be published on Readthe Docs automatically
httpsshoprtfdorg
156 Documentation 39
Shop Documentation Release 001
40 Kapitel 15 Development
KAPITEL 16
Indices and tables
bull genindex
bull modindex
bull search
41
- Basics
-
- Products
- Personas
- Use cases
- Design principles
-
- Web shop Design
-
- General
- Layout
- Sitemap
- Main page
-
- Style and design
-
- Cascading Style Sheets
- Pages
-
- Dynamics
-
- Setup
- Current year
- Navigation Menu
- List of Products
- Company details
-
- External files
-
- Navigation Menu
- Header
- Footer
-
- Input processing
-
- ``Buy Now links
- Select options
-
- Javascript
-
- Simple use case
-
- Cookies and Sessions
-
- Cookies
- Hit counter
- Language selection
- User Accounts
-
- Database
-
- Tables
- PHP
-
- Web service
-
- Map
- Weather
-
- Data export
-
- JSON
-
- Messaging
-
- MQTT
-
- Localisation (L10n)
- Templates
-
- Template
- Content
-
- Development
-
- Web server
- Database server
- Versions
- Setup infrastructure
- Git respository
- Documentation
-
- Indices and tables
-
Shop Documentation Release 001
All connections to the database are done in the same way Below you find an example Everything is done in theobject-oriented style
ltphprequire_once(rsquoconfigdbconnectphprsquo)if ($connection-gtconnect_errno == 0)
$sql = SELECT FROM products$results = $connection-gtquery($sql)echo $results-gtnum_rows$results-gtclose()
else echo Database connection error
gt
26 Kapitel 9 Database
KAPITEL 10
Web service
Tow web services are integrated to take advantages of online available data sources
101 Map
Leafletjs a JavaScript library for working with interactive maps from OpenStreetMap (OSM) is implemented as ashow case for a simple web service
The basic steps to integrate a map is shown below
ltdiv id=map class=map style=width 600px height 400pxgtltdivgt
ltscript src=scriptsleafletjsgtltscriptgtltscript src=scriptsleaflet-providersjsgtltscriptgtltscriptgtvar map = Lmap(rsquomaprsquo
center [250472 -773255]zoom 12zoomControl true
)
var defaultLayer = LtileLayerprovider(rsquoOpenStreetMapMapnikrsquo)addTo(map)ltscriptgt
102 Weather
The OpenWeatherMap service provides free weather data and a forecast API for web applications
ltphp Details about the API httpbugsopenweathermaporgprojectsapiwikiApi_2_5_weather$url = rsquohttpapiopenweathermaporgdata25weatherq=Bernechampunit=metricsampmode=jsonrsquo
$json = file_get_contents($url)$data = json_decode($json)
$tempC = round((27315 - $data-gtmain-gttemp)100) 100$humidity = $data-gtmain-gthumidity$pressure = $data-gtmain-gtpressure
27
Shop Documentation Release 001
echo ltpgtTemperatur $tempC degCltbrgtnecho Luftfeuchtigkeit $humidity ltbrgtnecho Luftdruck $pressure Paltpgtn
gt
28 Kapitel 10 Web service
KAPITEL 11
Data export
111 PDF
FPDF is a PHP class that allows to generate PDF files with pure PHP As a showcase for that the product specificationsfor a given product are filled in a pdf and showed in the browser The user can then decide to download or print thefile
112 JSON
JavaScript Object Notation (JSON) is a lightweight data-interchange format The format is language independent andPHP support the encoding and the decoding JSON with json_encode($data) and json_decode($data)$rows = array()$sql = SELECT FROM products$results = $connection-gtquery($sql)while ($result = $results-gtfetch_object())
$rows[] = $result$results-gtclose()
Writing all rows to a JSON file$fp = fopen(rsquopencilsjsonrsquo rsquowrsquo)fwrite($fp json_encode($rows))fclose($fp)gt
and for reading it
ltphp$json = file_get_contents(rsquopencilsjsonrsquo)print_r(json_decode($json))
gt
29
Shop Documentation Release 001
30 Kapitel 11 Data export
KAPITEL 12
Messaging
Beside standard email messages the webshop supports sending MQ Telemetry Transport protocol (MQTT) messagesas an additional feature The MQTT messages are small
121 MQTT
Mosquitto-PHP is used as a PHP wrapper for MQTT Please check the Projectrsquos README for details about theinstallation and the setup
1211 Broker
Mosquitto is a message broker that implements the MQ Telemetry Transport protocol Check if mosquitto is run-ning
$ sudo systemctl status mosquittoservice
If not start it
$ systemctl start mosquittoservice
All messages are published to the topic webshop
1212 Publishing
After the installation of Mosquitto-PHP the snipplet shown below sends a single message
ltphpdefine(rsquoBROKERrsquo rsquolocalhostrsquo)define(rsquoPORTrsquo 1883)define(rsquoCLIENT_IDrsquo webshop_ + getmypid())$topic = webshop$subtopic = test$completeTopic = $topic$subtopic
$client = new MosquittoClient(CLIENT_ID)$client-gtconnect(BROKER PORT 60)
$message = Test message from webshop at date(Y-m-d His)$client-gtpublish($completeTopic $message 0 false)
gt
31
Shop Documentation Release 001
1213 Subscribing
To read the messages sent by the webshop a client is needed The Mosquitto broker contain a simple command-linetool for subscribing to various topics
$ mosquitto_sub -h localhost -t webshop
122 Email
This section doesnrsquot describe the installation and configuration of a local MTA There are enough resources thatcontains information about the setup of postfix for local delivery only
If you want to test the email feature add the following code in one of PHP pages
ltphp mail(rsquorootlocalhostrsquo rsquoTest message from webshoprsquo rsquoThe webshop is selling pencilsrsquo) gt
By default SELinux is running in Enforcing mode which is restrictive about about what a web server can do Toallow sending email the following SELinux boolean needs to changed
setsebool -P httpd_can_network_connect=1 setsebool -P httpd_can_sendmail=1
32 Kapitel 12 Messaging
KAPITEL 13
Localisation (L10n)
There are several ways to add localisation to a web site For small projects arrays with string can work but this is notvery efficient and user-friendly With Gettext is a toolset available that provide a framework to produce multi-lingualcontent in a wide area of programming languages
Make sure that the php-gettext package is available on your system If not install it
$ sudo yum -y install php-php-gettext
Check if gettext support is available
ltphpif (function_exists(gettext))
echo gettext is not installednelse
echo gettext is supportedn
gt
Make sure that all locales your want are available on the server
locale -a
The first step is to mark all string which should be translatable as shown below For further details please refer to theGettext documentation
echo _(rsquoSome textrsquo)
The next step is to extract all strings
xgettext --from-code=UTF-8 -o localewebshoppot php scriptsphp
To re-generate the file after an update join the strings
xgettext -j --from-code=UTF-8 -o localewebshoppot php scriptsphp
For every language a po file is needed for the transations Generate it with the command mentioned below
msginit --no-translator -l de_CH -o localede_CHpo -i localewebshoppot
Once created there are only updates of the message catalog needed in the futures
msgmerge -U localede_CHpo localewebshoppot
If you re finish create the mo file for the specific language
33
Shop Documentation Release 001
msgfmt -c -v -o localede_CHLC_MESSAGESwebshopmo localede_CHpo
34 Kapitel 13 Localisation (L10n)
KAPITEL 14
Templates
Beside other solutions Savant3 is a lightweight object-oriented template system for PHP This solution does not needa lot of additional configuration
141 Template
A simple template file looks like the one shown below
lthtmlgtltheadgt
lttitlegtltphp echo $this-gteprint($this-gttitle) gtlttitlegtltheadgtltbodygt
ltphp echo $this-gteprint($this-gtcontent) gtltbodygt
lthtmlgt
For a more detailed intro check this article on Zend Developer Zone
142 Content
To fill the template with data all wished variables needs to be defined in a seperate PHP file
ltphprequire_once rsquoscriptsSavant3phprsquo$tpl = new Savant3()
Create a title$title = Simple sample page
Create the content of the page$content = Some sample text to show
Assign values to the Savant instance$tpl-gttitle = $title$tpl-gtcontent = $content
Define the template source file to show$tpl-gtdisplay(rsquosimpletplphprsquo)
gt
35
Shop Documentation Release 001
The webshop contains a page (master)
36 Kapitel 14 Templates
KAPITEL 15
Development
This sections describes the configuration of the development and runtime environment for the web shop
151 Web server
Instead of Apache the project is running on Lighttpd The reasons are that Lighttpd provides faster setup easierconfiguration and better performance Lighttpd is running with FastCGI
The path of the web server is varwwwlighttpd and the SELinux configuration are still the defaults
The web server is running in SSL-only mode and the certificate is generated during the server setup process
152 Database server
For persistence storage the drop-in replacement MariaDB is used MySQL will work to but this is not tested phpMyAd-min is available under phpmyadmin on the web server beside the command-line tools for easy administration
The default credentials for phpMyAdmin are rootwebshop or the entry you made in the Ansible playbookdevelvariablessensitiveyml
153 Versions
The web shop is built with the below listed components and tested Other releases can be used and may work but thiswill not be tested Probably it will work with different releases
bull Operating system Fedora 20
bull Kernel 3135-202fc20x86_64
bull Lighttpd 1434
bull PHP 557
bull MariaDB 5534
For communication postfix and mosquitto are needed additionally
37
Shop Documentation Release 001
154 Setup infrastructure
1541 Configuration management
For the creation of reproducable and identical environment for the development and the run-time across differentsystems Ansible is used as configuration management solution All needed steps of the installation are automated Theconfiguration doesnrsquot differentiate between local or remote installations This matters only for the deployment of theweb content
For local development itrsquos possible to use an LX container
$ sudo ansible-playbook develcontaineryml
To get everything running some additional steps (check the network inside the container generate keys etc) areneeded After you are done check it
$ sudo ansible webshop -m setup
From the management system
$ sudo ssh-copy-id -i rootsshid_rsapub root[IP address of your managed node]
The configuration of Ansible itself (adding the system to etcansiblehosts and copying the SSH keys) isnot documented at this place There are various resources available like here All playbooks are located in the folderdevel Start the setup with the command shown below
$ sudo ansible-playbook develsetupyml
The used group name in etcansiblehosts is webshop
If the setup completes without errors then the web server is accessible and show a default page Please keep in mindthat the server is only accessible over https unencrypted traffic is not allowed
1542 DeploymentSetup website
For the simple deployment of the lastest version of the shop a playbook called deployyml is provided Thisplaybook put all files in place
$ sudo ansible-playbook develdeployyml
To full deploy the webshop all tables in the database must exist The file webshopsql contains all needed SQLcommands and sample data for the web application
Itrsquos possible to deploy the website manually but this is not recommended A couple of files are depending on templateswhich are created during the deployment
Itrsquos also not recommanded to clone everything into your webserver root This would save you the trouble of doing itby hand but third-party features are missing then Those missing parts are the template engine the pdf generation theconnection to Openstreetmap and probably other things not mentioned here
155 Git respository
All project relevante informations (Source code templates documentation etc) is located in a public Git repositoryon Github
38 Kapitel 15 Development
Shop Documentation Release 001
156 Documentation
The documentation is using reStructuredText as markup language For a local build Sphinx is needed Sphinx isavailable in the Fedora Package Collection and can be installed with yum or any other package management tool
yum -y install python-sphinx python-docutils
The source files of the documentation are located under docs
$ cd docs$ make html
The output is stored under docs_buildhtml
After every push to Github a hook launch a rebuild of the documentation The latest release will be published on Readthe Docs automatically
httpsshoprtfdorg
156 Documentation 39
Shop Documentation Release 001
40 Kapitel 15 Development
KAPITEL 16
Indices and tables
bull genindex
bull modindex
bull search
41
- Basics
-
- Products
- Personas
- Use cases
- Design principles
-
- Web shop Design
-
- General
- Layout
- Sitemap
- Main page
-
- Style and design
-
- Cascading Style Sheets
- Pages
-
- Dynamics
-
- Setup
- Current year
- Navigation Menu
- List of Products
- Company details
-
- External files
-
- Navigation Menu
- Header
- Footer
-
- Input processing
-
- ``Buy Now links
- Select options
-
- Javascript
-
- Simple use case
-
- Cookies and Sessions
-
- Cookies
- Hit counter
- Language selection
- User Accounts
-
- Database
-
- Tables
- PHP
-
- Web service
-
- Map
- Weather
-
- Data export
-
- JSON
-
- Messaging
-
- MQTT
-
- Localisation (L10n)
- Templates
-
- Template
- Content
-
- Development
-
- Web server
- Database server
- Versions
- Setup infrastructure
- Git respository
- Documentation
-
- Indices and tables
-
KAPITEL 10
Web service
Tow web services are integrated to take advantages of online available data sources
101 Map
Leafletjs a JavaScript library for working with interactive maps from OpenStreetMap (OSM) is implemented as ashow case for a simple web service
The basic steps to integrate a map is shown below
ltdiv id=map class=map style=width 600px height 400pxgtltdivgt
ltscript src=scriptsleafletjsgtltscriptgtltscript src=scriptsleaflet-providersjsgtltscriptgtltscriptgtvar map = Lmap(rsquomaprsquo
center [250472 -773255]zoom 12zoomControl true
)
var defaultLayer = LtileLayerprovider(rsquoOpenStreetMapMapnikrsquo)addTo(map)ltscriptgt
102 Weather
The OpenWeatherMap service provides free weather data and a forecast API for web applications
ltphp Details about the API httpbugsopenweathermaporgprojectsapiwikiApi_2_5_weather$url = rsquohttpapiopenweathermaporgdata25weatherq=Bernechampunit=metricsampmode=jsonrsquo
$json = file_get_contents($url)$data = json_decode($json)
$tempC = round((27315 - $data-gtmain-gttemp)100) 100$humidity = $data-gtmain-gthumidity$pressure = $data-gtmain-gtpressure
27
Shop Documentation Release 001
echo ltpgtTemperatur $tempC degCltbrgtnecho Luftfeuchtigkeit $humidity ltbrgtnecho Luftdruck $pressure Paltpgtn
gt
28 Kapitel 10 Web service
KAPITEL 11
Data export
111 PDF
FPDF is a PHP class that allows to generate PDF files with pure PHP As a showcase for that the product specificationsfor a given product are filled in a pdf and showed in the browser The user can then decide to download or print thefile
112 JSON
JavaScript Object Notation (JSON) is a lightweight data-interchange format The format is language independent andPHP support the encoding and the decoding JSON with json_encode($data) and json_decode($data)$rows = array()$sql = SELECT FROM products$results = $connection-gtquery($sql)while ($result = $results-gtfetch_object())
$rows[] = $result$results-gtclose()
Writing all rows to a JSON file$fp = fopen(rsquopencilsjsonrsquo rsquowrsquo)fwrite($fp json_encode($rows))fclose($fp)gt
and for reading it
ltphp$json = file_get_contents(rsquopencilsjsonrsquo)print_r(json_decode($json))
gt
29
Shop Documentation Release 001
30 Kapitel 11 Data export
KAPITEL 12
Messaging
Beside standard email messages the webshop supports sending MQ Telemetry Transport protocol (MQTT) messagesas an additional feature The MQTT messages are small
121 MQTT
Mosquitto-PHP is used as a PHP wrapper for MQTT Please check the Projectrsquos README for details about theinstallation and the setup
1211 Broker
Mosquitto is a message broker that implements the MQ Telemetry Transport protocol Check if mosquitto is run-ning
$ sudo systemctl status mosquittoservice
If not start it
$ systemctl start mosquittoservice
All messages are published to the topic webshop
1212 Publishing
After the installation of Mosquitto-PHP the snipplet shown below sends a single message
ltphpdefine(rsquoBROKERrsquo rsquolocalhostrsquo)define(rsquoPORTrsquo 1883)define(rsquoCLIENT_IDrsquo webshop_ + getmypid())$topic = webshop$subtopic = test$completeTopic = $topic$subtopic
$client = new MosquittoClient(CLIENT_ID)$client-gtconnect(BROKER PORT 60)
$message = Test message from webshop at date(Y-m-d His)$client-gtpublish($completeTopic $message 0 false)
gt
31
Shop Documentation Release 001
1213 Subscribing
To read the messages sent by the webshop a client is needed The Mosquitto broker contain a simple command-linetool for subscribing to various topics
$ mosquitto_sub -h localhost -t webshop
122 Email
This section doesnrsquot describe the installation and configuration of a local MTA There are enough resources thatcontains information about the setup of postfix for local delivery only
If you want to test the email feature add the following code in one of PHP pages
ltphp mail(rsquorootlocalhostrsquo rsquoTest message from webshoprsquo rsquoThe webshop is selling pencilsrsquo) gt
By default SELinux is running in Enforcing mode which is restrictive about about what a web server can do Toallow sending email the following SELinux boolean needs to changed
setsebool -P httpd_can_network_connect=1 setsebool -P httpd_can_sendmail=1
32 Kapitel 12 Messaging
KAPITEL 13
Localisation (L10n)
There are several ways to add localisation to a web site For small projects arrays with string can work but this is notvery efficient and user-friendly With Gettext is a toolset available that provide a framework to produce multi-lingualcontent in a wide area of programming languages
Make sure that the php-gettext package is available on your system If not install it
$ sudo yum -y install php-php-gettext
Check if gettext support is available
ltphpif (function_exists(gettext))
echo gettext is not installednelse
echo gettext is supportedn
gt
Make sure that all locales your want are available on the server
locale -a
The first step is to mark all string which should be translatable as shown below For further details please refer to theGettext documentation
echo _(rsquoSome textrsquo)
The next step is to extract all strings
xgettext --from-code=UTF-8 -o localewebshoppot php scriptsphp
To re-generate the file after an update join the strings
xgettext -j --from-code=UTF-8 -o localewebshoppot php scriptsphp
For every language a po file is needed for the transations Generate it with the command mentioned below
msginit --no-translator -l de_CH -o localede_CHpo -i localewebshoppot
Once created there are only updates of the message catalog needed in the futures
msgmerge -U localede_CHpo localewebshoppot
If you re finish create the mo file for the specific language
33
Shop Documentation Release 001
msgfmt -c -v -o localede_CHLC_MESSAGESwebshopmo localede_CHpo
34 Kapitel 13 Localisation (L10n)
KAPITEL 14
Templates
Beside other solutions Savant3 is a lightweight object-oriented template system for PHP This solution does not needa lot of additional configuration
141 Template
A simple template file looks like the one shown below
lthtmlgtltheadgt
lttitlegtltphp echo $this-gteprint($this-gttitle) gtlttitlegtltheadgtltbodygt
ltphp echo $this-gteprint($this-gtcontent) gtltbodygt
lthtmlgt
For a more detailed intro check this article on Zend Developer Zone
142 Content
To fill the template with data all wished variables needs to be defined in a seperate PHP file
ltphprequire_once rsquoscriptsSavant3phprsquo$tpl = new Savant3()
Create a title$title = Simple sample page
Create the content of the page$content = Some sample text to show
Assign values to the Savant instance$tpl-gttitle = $title$tpl-gtcontent = $content
Define the template source file to show$tpl-gtdisplay(rsquosimpletplphprsquo)
gt
35
Shop Documentation Release 001
The webshop contains a page (master)
36 Kapitel 14 Templates
KAPITEL 15
Development
This sections describes the configuration of the development and runtime environment for the web shop
151 Web server
Instead of Apache the project is running on Lighttpd The reasons are that Lighttpd provides faster setup easierconfiguration and better performance Lighttpd is running with FastCGI
The path of the web server is varwwwlighttpd and the SELinux configuration are still the defaults
The web server is running in SSL-only mode and the certificate is generated during the server setup process
152 Database server
For persistence storage the drop-in replacement MariaDB is used MySQL will work to but this is not tested phpMyAd-min is available under phpmyadmin on the web server beside the command-line tools for easy administration
The default credentials for phpMyAdmin are rootwebshop or the entry you made in the Ansible playbookdevelvariablessensitiveyml
153 Versions
The web shop is built with the below listed components and tested Other releases can be used and may work but thiswill not be tested Probably it will work with different releases
bull Operating system Fedora 20
bull Kernel 3135-202fc20x86_64
bull Lighttpd 1434
bull PHP 557
bull MariaDB 5534
For communication postfix and mosquitto are needed additionally
37
Shop Documentation Release 001
154 Setup infrastructure
1541 Configuration management
For the creation of reproducable and identical environment for the development and the run-time across differentsystems Ansible is used as configuration management solution All needed steps of the installation are automated Theconfiguration doesnrsquot differentiate between local or remote installations This matters only for the deployment of theweb content
For local development itrsquos possible to use an LX container
$ sudo ansible-playbook develcontaineryml
To get everything running some additional steps (check the network inside the container generate keys etc) areneeded After you are done check it
$ sudo ansible webshop -m setup
From the management system
$ sudo ssh-copy-id -i rootsshid_rsapub root[IP address of your managed node]
The configuration of Ansible itself (adding the system to etcansiblehosts and copying the SSH keys) isnot documented at this place There are various resources available like here All playbooks are located in the folderdevel Start the setup with the command shown below
$ sudo ansible-playbook develsetupyml
The used group name in etcansiblehosts is webshop
If the setup completes without errors then the web server is accessible and show a default page Please keep in mindthat the server is only accessible over https unencrypted traffic is not allowed
1542 DeploymentSetup website
For the simple deployment of the lastest version of the shop a playbook called deployyml is provided Thisplaybook put all files in place
$ sudo ansible-playbook develdeployyml
To full deploy the webshop all tables in the database must exist The file webshopsql contains all needed SQLcommands and sample data for the web application
Itrsquos possible to deploy the website manually but this is not recommended A couple of files are depending on templateswhich are created during the deployment
Itrsquos also not recommanded to clone everything into your webserver root This would save you the trouble of doing itby hand but third-party features are missing then Those missing parts are the template engine the pdf generation theconnection to Openstreetmap and probably other things not mentioned here
155 Git respository
All project relevante informations (Source code templates documentation etc) is located in a public Git repositoryon Github
38 Kapitel 15 Development
Shop Documentation Release 001
156 Documentation
The documentation is using reStructuredText as markup language For a local build Sphinx is needed Sphinx isavailable in the Fedora Package Collection and can be installed with yum or any other package management tool
yum -y install python-sphinx python-docutils
The source files of the documentation are located under docs
$ cd docs$ make html
The output is stored under docs_buildhtml
After every push to Github a hook launch a rebuild of the documentation The latest release will be published on Readthe Docs automatically
httpsshoprtfdorg
156 Documentation 39
Shop Documentation Release 001
40 Kapitel 15 Development
KAPITEL 16
Indices and tables
bull genindex
bull modindex
bull search
41
- Basics
-
- Products
- Personas
- Use cases
- Design principles
-
- Web shop Design
-
- General
- Layout
- Sitemap
- Main page
-
- Style and design
-
- Cascading Style Sheets
- Pages
-
- Dynamics
-
- Setup
- Current year
- Navigation Menu
- List of Products
- Company details
-
- External files
-
- Navigation Menu
- Header
- Footer
-
- Input processing
-
- ``Buy Now links
- Select options
-
- Javascript
-
- Simple use case
-
- Cookies and Sessions
-
- Cookies
- Hit counter
- Language selection
- User Accounts
-
- Database
-
- Tables
- PHP
-
- Web service
-
- Map
- Weather
-
- Data export
-
- JSON
-
- Messaging
-
- MQTT
-
- Localisation (L10n)
- Templates
-
- Template
- Content
-
- Development
-
- Web server
- Database server
- Versions
- Setup infrastructure
- Git respository
- Documentation
-
- Indices and tables
-
Shop Documentation Release 001
echo ltpgtTemperatur $tempC degCltbrgtnecho Luftfeuchtigkeit $humidity ltbrgtnecho Luftdruck $pressure Paltpgtn
gt
28 Kapitel 10 Web service
KAPITEL 11
Data export
111 PDF
FPDF is a PHP class that allows to generate PDF files with pure PHP As a showcase for that the product specificationsfor a given product are filled in a pdf and showed in the browser The user can then decide to download or print thefile
112 JSON
JavaScript Object Notation (JSON) is a lightweight data-interchange format The format is language independent andPHP support the encoding and the decoding JSON with json_encode($data) and json_decode($data)$rows = array()$sql = SELECT FROM products$results = $connection-gtquery($sql)while ($result = $results-gtfetch_object())
$rows[] = $result$results-gtclose()
Writing all rows to a JSON file$fp = fopen(rsquopencilsjsonrsquo rsquowrsquo)fwrite($fp json_encode($rows))fclose($fp)gt
and for reading it
ltphp$json = file_get_contents(rsquopencilsjsonrsquo)print_r(json_decode($json))
gt
29
Shop Documentation Release 001
30 Kapitel 11 Data export
KAPITEL 12
Messaging
Beside standard email messages the webshop supports sending MQ Telemetry Transport protocol (MQTT) messagesas an additional feature The MQTT messages are small
121 MQTT
Mosquitto-PHP is used as a PHP wrapper for MQTT Please check the Projectrsquos README for details about theinstallation and the setup
1211 Broker
Mosquitto is a message broker that implements the MQ Telemetry Transport protocol Check if mosquitto is run-ning
$ sudo systemctl status mosquittoservice
If not start it
$ systemctl start mosquittoservice
All messages are published to the topic webshop
1212 Publishing
After the installation of Mosquitto-PHP the snipplet shown below sends a single message
ltphpdefine(rsquoBROKERrsquo rsquolocalhostrsquo)define(rsquoPORTrsquo 1883)define(rsquoCLIENT_IDrsquo webshop_ + getmypid())$topic = webshop$subtopic = test$completeTopic = $topic$subtopic
$client = new MosquittoClient(CLIENT_ID)$client-gtconnect(BROKER PORT 60)
$message = Test message from webshop at date(Y-m-d His)$client-gtpublish($completeTopic $message 0 false)
gt
31
Shop Documentation Release 001
1213 Subscribing
To read the messages sent by the webshop a client is needed The Mosquitto broker contain a simple command-linetool for subscribing to various topics
$ mosquitto_sub -h localhost -t webshop
122 Email
This section doesnrsquot describe the installation and configuration of a local MTA There are enough resources thatcontains information about the setup of postfix for local delivery only
If you want to test the email feature add the following code in one of PHP pages
ltphp mail(rsquorootlocalhostrsquo rsquoTest message from webshoprsquo rsquoThe webshop is selling pencilsrsquo) gt
By default SELinux is running in Enforcing mode which is restrictive about about what a web server can do Toallow sending email the following SELinux boolean needs to changed
setsebool -P httpd_can_network_connect=1 setsebool -P httpd_can_sendmail=1
32 Kapitel 12 Messaging
KAPITEL 13
Localisation (L10n)
There are several ways to add localisation to a web site For small projects arrays with string can work but this is notvery efficient and user-friendly With Gettext is a toolset available that provide a framework to produce multi-lingualcontent in a wide area of programming languages
Make sure that the php-gettext package is available on your system If not install it
$ sudo yum -y install php-php-gettext
Check if gettext support is available
ltphpif (function_exists(gettext))
echo gettext is not installednelse
echo gettext is supportedn
gt
Make sure that all locales your want are available on the server
locale -a
The first step is to mark all string which should be translatable as shown below For further details please refer to theGettext documentation
echo _(rsquoSome textrsquo)
The next step is to extract all strings
xgettext --from-code=UTF-8 -o localewebshoppot php scriptsphp
To re-generate the file after an update join the strings
xgettext -j --from-code=UTF-8 -o localewebshoppot php scriptsphp
For every language a po file is needed for the transations Generate it with the command mentioned below
msginit --no-translator -l de_CH -o localede_CHpo -i localewebshoppot
Once created there are only updates of the message catalog needed in the futures
msgmerge -U localede_CHpo localewebshoppot
If you re finish create the mo file for the specific language
33
Shop Documentation Release 001
msgfmt -c -v -o localede_CHLC_MESSAGESwebshopmo localede_CHpo
34 Kapitel 13 Localisation (L10n)
KAPITEL 14
Templates
Beside other solutions Savant3 is a lightweight object-oriented template system for PHP This solution does not needa lot of additional configuration
141 Template
A simple template file looks like the one shown below
lthtmlgtltheadgt
lttitlegtltphp echo $this-gteprint($this-gttitle) gtlttitlegtltheadgtltbodygt
ltphp echo $this-gteprint($this-gtcontent) gtltbodygt
lthtmlgt
For a more detailed intro check this article on Zend Developer Zone
142 Content
To fill the template with data all wished variables needs to be defined in a seperate PHP file
ltphprequire_once rsquoscriptsSavant3phprsquo$tpl = new Savant3()
Create a title$title = Simple sample page
Create the content of the page$content = Some sample text to show
Assign values to the Savant instance$tpl-gttitle = $title$tpl-gtcontent = $content
Define the template source file to show$tpl-gtdisplay(rsquosimpletplphprsquo)
gt
35
Shop Documentation Release 001
The webshop contains a page (master)
36 Kapitel 14 Templates
KAPITEL 15
Development
This sections describes the configuration of the development and runtime environment for the web shop
151 Web server
Instead of Apache the project is running on Lighttpd The reasons are that Lighttpd provides faster setup easierconfiguration and better performance Lighttpd is running with FastCGI
The path of the web server is varwwwlighttpd and the SELinux configuration are still the defaults
The web server is running in SSL-only mode and the certificate is generated during the server setup process
152 Database server
For persistence storage the drop-in replacement MariaDB is used MySQL will work to but this is not tested phpMyAd-min is available under phpmyadmin on the web server beside the command-line tools for easy administration
The default credentials for phpMyAdmin are rootwebshop or the entry you made in the Ansible playbookdevelvariablessensitiveyml
153 Versions
The web shop is built with the below listed components and tested Other releases can be used and may work but thiswill not be tested Probably it will work with different releases
bull Operating system Fedora 20
bull Kernel 3135-202fc20x86_64
bull Lighttpd 1434
bull PHP 557
bull MariaDB 5534
For communication postfix and mosquitto are needed additionally
37
Shop Documentation Release 001
154 Setup infrastructure
1541 Configuration management
For the creation of reproducable and identical environment for the development and the run-time across differentsystems Ansible is used as configuration management solution All needed steps of the installation are automated Theconfiguration doesnrsquot differentiate between local or remote installations This matters only for the deployment of theweb content
For local development itrsquos possible to use an LX container
$ sudo ansible-playbook develcontaineryml
To get everything running some additional steps (check the network inside the container generate keys etc) areneeded After you are done check it
$ sudo ansible webshop -m setup
From the management system
$ sudo ssh-copy-id -i rootsshid_rsapub root[IP address of your managed node]
The configuration of Ansible itself (adding the system to etcansiblehosts and copying the SSH keys) isnot documented at this place There are various resources available like here All playbooks are located in the folderdevel Start the setup with the command shown below
$ sudo ansible-playbook develsetupyml
The used group name in etcansiblehosts is webshop
If the setup completes without errors then the web server is accessible and show a default page Please keep in mindthat the server is only accessible over https unencrypted traffic is not allowed
1542 DeploymentSetup website
For the simple deployment of the lastest version of the shop a playbook called deployyml is provided Thisplaybook put all files in place
$ sudo ansible-playbook develdeployyml
To full deploy the webshop all tables in the database must exist The file webshopsql contains all needed SQLcommands and sample data for the web application
Itrsquos possible to deploy the website manually but this is not recommended A couple of files are depending on templateswhich are created during the deployment
Itrsquos also not recommanded to clone everything into your webserver root This would save you the trouble of doing itby hand but third-party features are missing then Those missing parts are the template engine the pdf generation theconnection to Openstreetmap and probably other things not mentioned here
155 Git respository
All project relevante informations (Source code templates documentation etc) is located in a public Git repositoryon Github
38 Kapitel 15 Development
Shop Documentation Release 001
156 Documentation
The documentation is using reStructuredText as markup language For a local build Sphinx is needed Sphinx isavailable in the Fedora Package Collection and can be installed with yum or any other package management tool
yum -y install python-sphinx python-docutils
The source files of the documentation are located under docs
$ cd docs$ make html
The output is stored under docs_buildhtml
After every push to Github a hook launch a rebuild of the documentation The latest release will be published on Readthe Docs automatically
httpsshoprtfdorg
156 Documentation 39
Shop Documentation Release 001
40 Kapitel 15 Development
KAPITEL 16
Indices and tables
bull genindex
bull modindex
bull search
41
- Basics
-
- Products
- Personas
- Use cases
- Design principles
-
- Web shop Design
-
- General
- Layout
- Sitemap
- Main page
-
- Style and design
-
- Cascading Style Sheets
- Pages
-
- Dynamics
-
- Setup
- Current year
- Navigation Menu
- List of Products
- Company details
-
- External files
-
- Navigation Menu
- Header
- Footer
-
- Input processing
-
- ``Buy Now links
- Select options
-
- Javascript
-
- Simple use case
-
- Cookies and Sessions
-
- Cookies
- Hit counter
- Language selection
- User Accounts
-
- Database
-
- Tables
- PHP
-
- Web service
-
- Map
- Weather
-
- Data export
-
- JSON
-
- Messaging
-
- MQTT
-
- Localisation (L10n)
- Templates
-
- Template
- Content
-
- Development
-
- Web server
- Database server
- Versions
- Setup infrastructure
- Git respository
- Documentation
-
- Indices and tables
-
KAPITEL 11
Data export
111 PDF
FPDF is a PHP class that allows to generate PDF files with pure PHP As a showcase for that the product specificationsfor a given product are filled in a pdf and showed in the browser The user can then decide to download or print thefile
112 JSON
JavaScript Object Notation (JSON) is a lightweight data-interchange format The format is language independent andPHP support the encoding and the decoding JSON with json_encode($data) and json_decode($data)$rows = array()$sql = SELECT FROM products$results = $connection-gtquery($sql)while ($result = $results-gtfetch_object())
$rows[] = $result$results-gtclose()
Writing all rows to a JSON file$fp = fopen(rsquopencilsjsonrsquo rsquowrsquo)fwrite($fp json_encode($rows))fclose($fp)gt
and for reading it
ltphp$json = file_get_contents(rsquopencilsjsonrsquo)print_r(json_decode($json))
gt
29
Shop Documentation Release 001
30 Kapitel 11 Data export
KAPITEL 12
Messaging
Beside standard email messages the webshop supports sending MQ Telemetry Transport protocol (MQTT) messagesas an additional feature The MQTT messages are small
121 MQTT
Mosquitto-PHP is used as a PHP wrapper for MQTT Please check the Projectrsquos README for details about theinstallation and the setup
1211 Broker
Mosquitto is a message broker that implements the MQ Telemetry Transport protocol Check if mosquitto is run-ning
$ sudo systemctl status mosquittoservice
If not start it
$ systemctl start mosquittoservice
All messages are published to the topic webshop
1212 Publishing
After the installation of Mosquitto-PHP the snipplet shown below sends a single message
ltphpdefine(rsquoBROKERrsquo rsquolocalhostrsquo)define(rsquoPORTrsquo 1883)define(rsquoCLIENT_IDrsquo webshop_ + getmypid())$topic = webshop$subtopic = test$completeTopic = $topic$subtopic
$client = new MosquittoClient(CLIENT_ID)$client-gtconnect(BROKER PORT 60)
$message = Test message from webshop at date(Y-m-d His)$client-gtpublish($completeTopic $message 0 false)
gt
31
Shop Documentation Release 001
1213 Subscribing
To read the messages sent by the webshop a client is needed The Mosquitto broker contain a simple command-linetool for subscribing to various topics
$ mosquitto_sub -h localhost -t webshop
122 Email
This section doesnrsquot describe the installation and configuration of a local MTA There are enough resources thatcontains information about the setup of postfix for local delivery only
If you want to test the email feature add the following code in one of PHP pages
ltphp mail(rsquorootlocalhostrsquo rsquoTest message from webshoprsquo rsquoThe webshop is selling pencilsrsquo) gt
By default SELinux is running in Enforcing mode which is restrictive about about what a web server can do Toallow sending email the following SELinux boolean needs to changed
setsebool -P httpd_can_network_connect=1 setsebool -P httpd_can_sendmail=1
32 Kapitel 12 Messaging
KAPITEL 13
Localisation (L10n)
There are several ways to add localisation to a web site For small projects arrays with string can work but this is notvery efficient and user-friendly With Gettext is a toolset available that provide a framework to produce multi-lingualcontent in a wide area of programming languages
Make sure that the php-gettext package is available on your system If not install it
$ sudo yum -y install php-php-gettext
Check if gettext support is available
ltphpif (function_exists(gettext))
echo gettext is not installednelse
echo gettext is supportedn
gt
Make sure that all locales your want are available on the server
locale -a
The first step is to mark all string which should be translatable as shown below For further details please refer to theGettext documentation
echo _(rsquoSome textrsquo)
The next step is to extract all strings
xgettext --from-code=UTF-8 -o localewebshoppot php scriptsphp
To re-generate the file after an update join the strings
xgettext -j --from-code=UTF-8 -o localewebshoppot php scriptsphp
For every language a po file is needed for the transations Generate it with the command mentioned below
msginit --no-translator -l de_CH -o localede_CHpo -i localewebshoppot
Once created there are only updates of the message catalog needed in the futures
msgmerge -U localede_CHpo localewebshoppot
If you re finish create the mo file for the specific language
33
Shop Documentation Release 001
msgfmt -c -v -o localede_CHLC_MESSAGESwebshopmo localede_CHpo
34 Kapitel 13 Localisation (L10n)
KAPITEL 14
Templates
Beside other solutions Savant3 is a lightweight object-oriented template system for PHP This solution does not needa lot of additional configuration
141 Template
A simple template file looks like the one shown below
lthtmlgtltheadgt
lttitlegtltphp echo $this-gteprint($this-gttitle) gtlttitlegtltheadgtltbodygt
ltphp echo $this-gteprint($this-gtcontent) gtltbodygt
lthtmlgt
For a more detailed intro check this article on Zend Developer Zone
142 Content
To fill the template with data all wished variables needs to be defined in a seperate PHP file
ltphprequire_once rsquoscriptsSavant3phprsquo$tpl = new Savant3()
Create a title$title = Simple sample page
Create the content of the page$content = Some sample text to show
Assign values to the Savant instance$tpl-gttitle = $title$tpl-gtcontent = $content
Define the template source file to show$tpl-gtdisplay(rsquosimpletplphprsquo)
gt
35
Shop Documentation Release 001
The webshop contains a page (master)
36 Kapitel 14 Templates
KAPITEL 15
Development
This sections describes the configuration of the development and runtime environment for the web shop
151 Web server
Instead of Apache the project is running on Lighttpd The reasons are that Lighttpd provides faster setup easierconfiguration and better performance Lighttpd is running with FastCGI
The path of the web server is varwwwlighttpd and the SELinux configuration are still the defaults
The web server is running in SSL-only mode and the certificate is generated during the server setup process
152 Database server
For persistence storage the drop-in replacement MariaDB is used MySQL will work to but this is not tested phpMyAd-min is available under phpmyadmin on the web server beside the command-line tools for easy administration
The default credentials for phpMyAdmin are rootwebshop or the entry you made in the Ansible playbookdevelvariablessensitiveyml
153 Versions
The web shop is built with the below listed components and tested Other releases can be used and may work but thiswill not be tested Probably it will work with different releases
bull Operating system Fedora 20
bull Kernel 3135-202fc20x86_64
bull Lighttpd 1434
bull PHP 557
bull MariaDB 5534
For communication postfix and mosquitto are needed additionally
37
Shop Documentation Release 001
154 Setup infrastructure
1541 Configuration management
For the creation of reproducable and identical environment for the development and the run-time across differentsystems Ansible is used as configuration management solution All needed steps of the installation are automated Theconfiguration doesnrsquot differentiate between local or remote installations This matters only for the deployment of theweb content
For local development itrsquos possible to use an LX container
$ sudo ansible-playbook develcontaineryml
To get everything running some additional steps (check the network inside the container generate keys etc) areneeded After you are done check it
$ sudo ansible webshop -m setup
From the management system
$ sudo ssh-copy-id -i rootsshid_rsapub root[IP address of your managed node]
The configuration of Ansible itself (adding the system to etcansiblehosts and copying the SSH keys) isnot documented at this place There are various resources available like here All playbooks are located in the folderdevel Start the setup with the command shown below
$ sudo ansible-playbook develsetupyml
The used group name in etcansiblehosts is webshop
If the setup completes without errors then the web server is accessible and show a default page Please keep in mindthat the server is only accessible over https unencrypted traffic is not allowed
1542 DeploymentSetup website
For the simple deployment of the lastest version of the shop a playbook called deployyml is provided Thisplaybook put all files in place
$ sudo ansible-playbook develdeployyml
To full deploy the webshop all tables in the database must exist The file webshopsql contains all needed SQLcommands and sample data for the web application
Itrsquos possible to deploy the website manually but this is not recommended A couple of files are depending on templateswhich are created during the deployment
Itrsquos also not recommanded to clone everything into your webserver root This would save you the trouble of doing itby hand but third-party features are missing then Those missing parts are the template engine the pdf generation theconnection to Openstreetmap and probably other things not mentioned here
155 Git respository
All project relevante informations (Source code templates documentation etc) is located in a public Git repositoryon Github
38 Kapitel 15 Development
Shop Documentation Release 001
156 Documentation
The documentation is using reStructuredText as markup language For a local build Sphinx is needed Sphinx isavailable in the Fedora Package Collection and can be installed with yum or any other package management tool
yum -y install python-sphinx python-docutils
The source files of the documentation are located under docs
$ cd docs$ make html
The output is stored under docs_buildhtml
After every push to Github a hook launch a rebuild of the documentation The latest release will be published on Readthe Docs automatically
httpsshoprtfdorg
156 Documentation 39
Shop Documentation Release 001
40 Kapitel 15 Development
KAPITEL 16
Indices and tables
bull genindex
bull modindex
bull search
41
- Basics
-
- Products
- Personas
- Use cases
- Design principles
-
- Web shop Design
-
- General
- Layout
- Sitemap
- Main page
-
- Style and design
-
- Cascading Style Sheets
- Pages
-
- Dynamics
-
- Setup
- Current year
- Navigation Menu
- List of Products
- Company details
-
- External files
-
- Navigation Menu
- Header
- Footer
-
- Input processing
-
- ``Buy Now links
- Select options
-
- Javascript
-
- Simple use case
-
- Cookies and Sessions
-
- Cookies
- Hit counter
- Language selection
- User Accounts
-
- Database
-
- Tables
- PHP
-
- Web service
-
- Map
- Weather
-
- Data export
-
- JSON
-
- Messaging
-
- MQTT
-
- Localisation (L10n)
- Templates
-
- Template
- Content
-
- Development
-
- Web server
- Database server
- Versions
- Setup infrastructure
- Git respository
- Documentation
-
- Indices and tables
-
Shop Documentation Release 001
30 Kapitel 11 Data export
KAPITEL 12
Messaging
Beside standard email messages the webshop supports sending MQ Telemetry Transport protocol (MQTT) messagesas an additional feature The MQTT messages are small
121 MQTT
Mosquitto-PHP is used as a PHP wrapper for MQTT Please check the Projectrsquos README for details about theinstallation and the setup
1211 Broker
Mosquitto is a message broker that implements the MQ Telemetry Transport protocol Check if mosquitto is run-ning
$ sudo systemctl status mosquittoservice
If not start it
$ systemctl start mosquittoservice
All messages are published to the topic webshop
1212 Publishing
After the installation of Mosquitto-PHP the snipplet shown below sends a single message
ltphpdefine(rsquoBROKERrsquo rsquolocalhostrsquo)define(rsquoPORTrsquo 1883)define(rsquoCLIENT_IDrsquo webshop_ + getmypid())$topic = webshop$subtopic = test$completeTopic = $topic$subtopic
$client = new MosquittoClient(CLIENT_ID)$client-gtconnect(BROKER PORT 60)
$message = Test message from webshop at date(Y-m-d His)$client-gtpublish($completeTopic $message 0 false)
gt
31
Shop Documentation Release 001
1213 Subscribing
To read the messages sent by the webshop a client is needed The Mosquitto broker contain a simple command-linetool for subscribing to various topics
$ mosquitto_sub -h localhost -t webshop
122 Email
This section doesnrsquot describe the installation and configuration of a local MTA There are enough resources thatcontains information about the setup of postfix for local delivery only
If you want to test the email feature add the following code in one of PHP pages
ltphp mail(rsquorootlocalhostrsquo rsquoTest message from webshoprsquo rsquoThe webshop is selling pencilsrsquo) gt
By default SELinux is running in Enforcing mode which is restrictive about about what a web server can do Toallow sending email the following SELinux boolean needs to changed
setsebool -P httpd_can_network_connect=1 setsebool -P httpd_can_sendmail=1
32 Kapitel 12 Messaging
KAPITEL 13
Localisation (L10n)
There are several ways to add localisation to a web site For small projects arrays with string can work but this is notvery efficient and user-friendly With Gettext is a toolset available that provide a framework to produce multi-lingualcontent in a wide area of programming languages
Make sure that the php-gettext package is available on your system If not install it
$ sudo yum -y install php-php-gettext
Check if gettext support is available
ltphpif (function_exists(gettext))
echo gettext is not installednelse
echo gettext is supportedn
gt
Make sure that all locales your want are available on the server
locale -a
The first step is to mark all string which should be translatable as shown below For further details please refer to theGettext documentation
echo _(rsquoSome textrsquo)
The next step is to extract all strings
xgettext --from-code=UTF-8 -o localewebshoppot php scriptsphp
To re-generate the file after an update join the strings
xgettext -j --from-code=UTF-8 -o localewebshoppot php scriptsphp
For every language a po file is needed for the transations Generate it with the command mentioned below
msginit --no-translator -l de_CH -o localede_CHpo -i localewebshoppot
Once created there are only updates of the message catalog needed in the futures
msgmerge -U localede_CHpo localewebshoppot
If you re finish create the mo file for the specific language
33
Shop Documentation Release 001
msgfmt -c -v -o localede_CHLC_MESSAGESwebshopmo localede_CHpo
34 Kapitel 13 Localisation (L10n)
KAPITEL 14
Templates
Beside other solutions Savant3 is a lightweight object-oriented template system for PHP This solution does not needa lot of additional configuration
141 Template
A simple template file looks like the one shown below
lthtmlgtltheadgt
lttitlegtltphp echo $this-gteprint($this-gttitle) gtlttitlegtltheadgtltbodygt
ltphp echo $this-gteprint($this-gtcontent) gtltbodygt
lthtmlgt
For a more detailed intro check this article on Zend Developer Zone
142 Content
To fill the template with data all wished variables needs to be defined in a seperate PHP file
ltphprequire_once rsquoscriptsSavant3phprsquo$tpl = new Savant3()
Create a title$title = Simple sample page
Create the content of the page$content = Some sample text to show
Assign values to the Savant instance$tpl-gttitle = $title$tpl-gtcontent = $content
Define the template source file to show$tpl-gtdisplay(rsquosimpletplphprsquo)
gt
35
Shop Documentation Release 001
The webshop contains a page (master)
36 Kapitel 14 Templates
KAPITEL 15
Development
This sections describes the configuration of the development and runtime environment for the web shop
151 Web server
Instead of Apache the project is running on Lighttpd The reasons are that Lighttpd provides faster setup easierconfiguration and better performance Lighttpd is running with FastCGI
The path of the web server is varwwwlighttpd and the SELinux configuration are still the defaults
The web server is running in SSL-only mode and the certificate is generated during the server setup process
152 Database server
For persistence storage the drop-in replacement MariaDB is used MySQL will work to but this is not tested phpMyAd-min is available under phpmyadmin on the web server beside the command-line tools for easy administration
The default credentials for phpMyAdmin are rootwebshop or the entry you made in the Ansible playbookdevelvariablessensitiveyml
153 Versions
The web shop is built with the below listed components and tested Other releases can be used and may work but thiswill not be tested Probably it will work with different releases
bull Operating system Fedora 20
bull Kernel 3135-202fc20x86_64
bull Lighttpd 1434
bull PHP 557
bull MariaDB 5534
For communication postfix and mosquitto are needed additionally
37
Shop Documentation Release 001
154 Setup infrastructure
1541 Configuration management
For the creation of reproducable and identical environment for the development and the run-time across differentsystems Ansible is used as configuration management solution All needed steps of the installation are automated Theconfiguration doesnrsquot differentiate between local or remote installations This matters only for the deployment of theweb content
For local development itrsquos possible to use an LX container
$ sudo ansible-playbook develcontaineryml
To get everything running some additional steps (check the network inside the container generate keys etc) areneeded After you are done check it
$ sudo ansible webshop -m setup
From the management system
$ sudo ssh-copy-id -i rootsshid_rsapub root[IP address of your managed node]
The configuration of Ansible itself (adding the system to etcansiblehosts and copying the SSH keys) isnot documented at this place There are various resources available like here All playbooks are located in the folderdevel Start the setup with the command shown below
$ sudo ansible-playbook develsetupyml
The used group name in etcansiblehosts is webshop
If the setup completes without errors then the web server is accessible and show a default page Please keep in mindthat the server is only accessible over https unencrypted traffic is not allowed
1542 DeploymentSetup website
For the simple deployment of the lastest version of the shop a playbook called deployyml is provided Thisplaybook put all files in place
$ sudo ansible-playbook develdeployyml
To full deploy the webshop all tables in the database must exist The file webshopsql contains all needed SQLcommands and sample data for the web application
Itrsquos possible to deploy the website manually but this is not recommended A couple of files are depending on templateswhich are created during the deployment
Itrsquos also not recommanded to clone everything into your webserver root This would save you the trouble of doing itby hand but third-party features are missing then Those missing parts are the template engine the pdf generation theconnection to Openstreetmap and probably other things not mentioned here
155 Git respository
All project relevante informations (Source code templates documentation etc) is located in a public Git repositoryon Github
38 Kapitel 15 Development
Shop Documentation Release 001
156 Documentation
The documentation is using reStructuredText as markup language For a local build Sphinx is needed Sphinx isavailable in the Fedora Package Collection and can be installed with yum or any other package management tool
yum -y install python-sphinx python-docutils
The source files of the documentation are located under docs
$ cd docs$ make html
The output is stored under docs_buildhtml
After every push to Github a hook launch a rebuild of the documentation The latest release will be published on Readthe Docs automatically
httpsshoprtfdorg
156 Documentation 39
Shop Documentation Release 001
40 Kapitel 15 Development
KAPITEL 16
Indices and tables
bull genindex
bull modindex
bull search
41
- Basics
-
- Products
- Personas
- Use cases
- Design principles
-
- Web shop Design
-
- General
- Layout
- Sitemap
- Main page
-
- Style and design
-
- Cascading Style Sheets
- Pages
-
- Dynamics
-
- Setup
- Current year
- Navigation Menu
- List of Products
- Company details
-
- External files
-
- Navigation Menu
- Header
- Footer
-
- Input processing
-
- ``Buy Now links
- Select options
-
- Javascript
-
- Simple use case
-
- Cookies and Sessions
-
- Cookies
- Hit counter
- Language selection
- User Accounts
-
- Database
-
- Tables
- PHP
-
- Web service
-
- Map
- Weather
-
- Data export
-
- JSON
-
- Messaging
-
- MQTT
-
- Localisation (L10n)
- Templates
-
- Template
- Content
-
- Development
-
- Web server
- Database server
- Versions
- Setup infrastructure
- Git respository
- Documentation
-
- Indices and tables
-
KAPITEL 12
Messaging
Beside standard email messages the webshop supports sending MQ Telemetry Transport protocol (MQTT) messagesas an additional feature The MQTT messages are small
121 MQTT
Mosquitto-PHP is used as a PHP wrapper for MQTT Please check the Projectrsquos README for details about theinstallation and the setup
1211 Broker
Mosquitto is a message broker that implements the MQ Telemetry Transport protocol Check if mosquitto is run-ning
$ sudo systemctl status mosquittoservice
If not start it
$ systemctl start mosquittoservice
All messages are published to the topic webshop
1212 Publishing
After the installation of Mosquitto-PHP the snipplet shown below sends a single message
ltphpdefine(rsquoBROKERrsquo rsquolocalhostrsquo)define(rsquoPORTrsquo 1883)define(rsquoCLIENT_IDrsquo webshop_ + getmypid())$topic = webshop$subtopic = test$completeTopic = $topic$subtopic
$client = new MosquittoClient(CLIENT_ID)$client-gtconnect(BROKER PORT 60)
$message = Test message from webshop at date(Y-m-d His)$client-gtpublish($completeTopic $message 0 false)
gt
31
Shop Documentation Release 001
1213 Subscribing
To read the messages sent by the webshop a client is needed The Mosquitto broker contain a simple command-linetool for subscribing to various topics
$ mosquitto_sub -h localhost -t webshop
122 Email
This section doesnrsquot describe the installation and configuration of a local MTA There are enough resources thatcontains information about the setup of postfix for local delivery only
If you want to test the email feature add the following code in one of PHP pages
ltphp mail(rsquorootlocalhostrsquo rsquoTest message from webshoprsquo rsquoThe webshop is selling pencilsrsquo) gt
By default SELinux is running in Enforcing mode which is restrictive about about what a web server can do Toallow sending email the following SELinux boolean needs to changed
setsebool -P httpd_can_network_connect=1 setsebool -P httpd_can_sendmail=1
32 Kapitel 12 Messaging
KAPITEL 13
Localisation (L10n)
There are several ways to add localisation to a web site For small projects arrays with string can work but this is notvery efficient and user-friendly With Gettext is a toolset available that provide a framework to produce multi-lingualcontent in a wide area of programming languages
Make sure that the php-gettext package is available on your system If not install it
$ sudo yum -y install php-php-gettext
Check if gettext support is available
ltphpif (function_exists(gettext))
echo gettext is not installednelse
echo gettext is supportedn
gt
Make sure that all locales your want are available on the server
locale -a
The first step is to mark all string which should be translatable as shown below For further details please refer to theGettext documentation
echo _(rsquoSome textrsquo)
The next step is to extract all strings
xgettext --from-code=UTF-8 -o localewebshoppot php scriptsphp
To re-generate the file after an update join the strings
xgettext -j --from-code=UTF-8 -o localewebshoppot php scriptsphp
For every language a po file is needed for the transations Generate it with the command mentioned below
msginit --no-translator -l de_CH -o localede_CHpo -i localewebshoppot
Once created there are only updates of the message catalog needed in the futures
msgmerge -U localede_CHpo localewebshoppot
If you re finish create the mo file for the specific language
33
Shop Documentation Release 001
msgfmt -c -v -o localede_CHLC_MESSAGESwebshopmo localede_CHpo
34 Kapitel 13 Localisation (L10n)
KAPITEL 14
Templates
Beside other solutions Savant3 is a lightweight object-oriented template system for PHP This solution does not needa lot of additional configuration
141 Template
A simple template file looks like the one shown below
lthtmlgtltheadgt
lttitlegtltphp echo $this-gteprint($this-gttitle) gtlttitlegtltheadgtltbodygt
ltphp echo $this-gteprint($this-gtcontent) gtltbodygt
lthtmlgt
For a more detailed intro check this article on Zend Developer Zone
142 Content
To fill the template with data all wished variables needs to be defined in a seperate PHP file
ltphprequire_once rsquoscriptsSavant3phprsquo$tpl = new Savant3()
Create a title$title = Simple sample page
Create the content of the page$content = Some sample text to show
Assign values to the Savant instance$tpl-gttitle = $title$tpl-gtcontent = $content
Define the template source file to show$tpl-gtdisplay(rsquosimpletplphprsquo)
gt
35
Shop Documentation Release 001
The webshop contains a page (master)
36 Kapitel 14 Templates
KAPITEL 15
Development
This sections describes the configuration of the development and runtime environment for the web shop
151 Web server
Instead of Apache the project is running on Lighttpd The reasons are that Lighttpd provides faster setup easierconfiguration and better performance Lighttpd is running with FastCGI
The path of the web server is varwwwlighttpd and the SELinux configuration are still the defaults
The web server is running in SSL-only mode and the certificate is generated during the server setup process
152 Database server
For persistence storage the drop-in replacement MariaDB is used MySQL will work to but this is not tested phpMyAd-min is available under phpmyadmin on the web server beside the command-line tools for easy administration
The default credentials for phpMyAdmin are rootwebshop or the entry you made in the Ansible playbookdevelvariablessensitiveyml
153 Versions
The web shop is built with the below listed components and tested Other releases can be used and may work but thiswill not be tested Probably it will work with different releases
bull Operating system Fedora 20
bull Kernel 3135-202fc20x86_64
bull Lighttpd 1434
bull PHP 557
bull MariaDB 5534
For communication postfix and mosquitto are needed additionally
37
Shop Documentation Release 001
154 Setup infrastructure
1541 Configuration management
For the creation of reproducable and identical environment for the development and the run-time across differentsystems Ansible is used as configuration management solution All needed steps of the installation are automated Theconfiguration doesnrsquot differentiate between local or remote installations This matters only for the deployment of theweb content
For local development itrsquos possible to use an LX container
$ sudo ansible-playbook develcontaineryml
To get everything running some additional steps (check the network inside the container generate keys etc) areneeded After you are done check it
$ sudo ansible webshop -m setup
From the management system
$ sudo ssh-copy-id -i rootsshid_rsapub root[IP address of your managed node]
The configuration of Ansible itself (adding the system to etcansiblehosts and copying the SSH keys) isnot documented at this place There are various resources available like here All playbooks are located in the folderdevel Start the setup with the command shown below
$ sudo ansible-playbook develsetupyml
The used group name in etcansiblehosts is webshop
If the setup completes without errors then the web server is accessible and show a default page Please keep in mindthat the server is only accessible over https unencrypted traffic is not allowed
1542 DeploymentSetup website
For the simple deployment of the lastest version of the shop a playbook called deployyml is provided Thisplaybook put all files in place
$ sudo ansible-playbook develdeployyml
To full deploy the webshop all tables in the database must exist The file webshopsql contains all needed SQLcommands and sample data for the web application
Itrsquos possible to deploy the website manually but this is not recommended A couple of files are depending on templateswhich are created during the deployment
Itrsquos also not recommanded to clone everything into your webserver root This would save you the trouble of doing itby hand but third-party features are missing then Those missing parts are the template engine the pdf generation theconnection to Openstreetmap and probably other things not mentioned here
155 Git respository
All project relevante informations (Source code templates documentation etc) is located in a public Git repositoryon Github
38 Kapitel 15 Development
Shop Documentation Release 001
156 Documentation
The documentation is using reStructuredText as markup language For a local build Sphinx is needed Sphinx isavailable in the Fedora Package Collection and can be installed with yum or any other package management tool
yum -y install python-sphinx python-docutils
The source files of the documentation are located under docs
$ cd docs$ make html
The output is stored under docs_buildhtml
After every push to Github a hook launch a rebuild of the documentation The latest release will be published on Readthe Docs automatically
httpsshoprtfdorg
156 Documentation 39
Shop Documentation Release 001
40 Kapitel 15 Development
KAPITEL 16
Indices and tables
bull genindex
bull modindex
bull search
41
- Basics
-
- Products
- Personas
- Use cases
- Design principles
-
- Web shop Design
-
- General
- Layout
- Sitemap
- Main page
-
- Style and design
-
- Cascading Style Sheets
- Pages
-
- Dynamics
-
- Setup
- Current year
- Navigation Menu
- List of Products
- Company details
-
- External files
-
- Navigation Menu
- Header
- Footer
-
- Input processing
-
- ``Buy Now links
- Select options
-
- Javascript
-
- Simple use case
-
- Cookies and Sessions
-
- Cookies
- Hit counter
- Language selection
- User Accounts
-
- Database
-
- Tables
- PHP
-
- Web service
-
- Map
- Weather
-
- Data export
-
- JSON
-
- Messaging
-
- MQTT
-
- Localisation (L10n)
- Templates
-
- Template
- Content
-
- Development
-
- Web server
- Database server
- Versions
- Setup infrastructure
- Git respository
- Documentation
-
- Indices and tables
-
Shop Documentation Release 001
1213 Subscribing
To read the messages sent by the webshop a client is needed The Mosquitto broker contain a simple command-linetool for subscribing to various topics
$ mosquitto_sub -h localhost -t webshop
122 Email
This section doesnrsquot describe the installation and configuration of a local MTA There are enough resources thatcontains information about the setup of postfix for local delivery only
If you want to test the email feature add the following code in one of PHP pages
ltphp mail(rsquorootlocalhostrsquo rsquoTest message from webshoprsquo rsquoThe webshop is selling pencilsrsquo) gt
By default SELinux is running in Enforcing mode which is restrictive about about what a web server can do Toallow sending email the following SELinux boolean needs to changed
setsebool -P httpd_can_network_connect=1 setsebool -P httpd_can_sendmail=1
32 Kapitel 12 Messaging
KAPITEL 13
Localisation (L10n)
There are several ways to add localisation to a web site For small projects arrays with string can work but this is notvery efficient and user-friendly With Gettext is a toolset available that provide a framework to produce multi-lingualcontent in a wide area of programming languages
Make sure that the php-gettext package is available on your system If not install it
$ sudo yum -y install php-php-gettext
Check if gettext support is available
ltphpif (function_exists(gettext))
echo gettext is not installednelse
echo gettext is supportedn
gt
Make sure that all locales your want are available on the server
locale -a
The first step is to mark all string which should be translatable as shown below For further details please refer to theGettext documentation
echo _(rsquoSome textrsquo)
The next step is to extract all strings
xgettext --from-code=UTF-8 -o localewebshoppot php scriptsphp
To re-generate the file after an update join the strings
xgettext -j --from-code=UTF-8 -o localewebshoppot php scriptsphp
For every language a po file is needed for the transations Generate it with the command mentioned below
msginit --no-translator -l de_CH -o localede_CHpo -i localewebshoppot
Once created there are only updates of the message catalog needed in the futures
msgmerge -U localede_CHpo localewebshoppot
If you re finish create the mo file for the specific language
33
Shop Documentation Release 001
msgfmt -c -v -o localede_CHLC_MESSAGESwebshopmo localede_CHpo
34 Kapitel 13 Localisation (L10n)
KAPITEL 14
Templates
Beside other solutions Savant3 is a lightweight object-oriented template system for PHP This solution does not needa lot of additional configuration
141 Template
A simple template file looks like the one shown below
lthtmlgtltheadgt
lttitlegtltphp echo $this-gteprint($this-gttitle) gtlttitlegtltheadgtltbodygt
ltphp echo $this-gteprint($this-gtcontent) gtltbodygt
lthtmlgt
For a more detailed intro check this article on Zend Developer Zone
142 Content
To fill the template with data all wished variables needs to be defined in a seperate PHP file
ltphprequire_once rsquoscriptsSavant3phprsquo$tpl = new Savant3()
Create a title$title = Simple sample page
Create the content of the page$content = Some sample text to show
Assign values to the Savant instance$tpl-gttitle = $title$tpl-gtcontent = $content
Define the template source file to show$tpl-gtdisplay(rsquosimpletplphprsquo)
gt
35
Shop Documentation Release 001
The webshop contains a page (master)
36 Kapitel 14 Templates
KAPITEL 15
Development
This sections describes the configuration of the development and runtime environment for the web shop
151 Web server
Instead of Apache the project is running on Lighttpd The reasons are that Lighttpd provides faster setup easierconfiguration and better performance Lighttpd is running with FastCGI
The path of the web server is varwwwlighttpd and the SELinux configuration are still the defaults
The web server is running in SSL-only mode and the certificate is generated during the server setup process
152 Database server
For persistence storage the drop-in replacement MariaDB is used MySQL will work to but this is not tested phpMyAd-min is available under phpmyadmin on the web server beside the command-line tools for easy administration
The default credentials for phpMyAdmin are rootwebshop or the entry you made in the Ansible playbookdevelvariablessensitiveyml
153 Versions
The web shop is built with the below listed components and tested Other releases can be used and may work but thiswill not be tested Probably it will work with different releases
bull Operating system Fedora 20
bull Kernel 3135-202fc20x86_64
bull Lighttpd 1434
bull PHP 557
bull MariaDB 5534
For communication postfix and mosquitto are needed additionally
37
Shop Documentation Release 001
154 Setup infrastructure
1541 Configuration management
For the creation of reproducable and identical environment for the development and the run-time across differentsystems Ansible is used as configuration management solution All needed steps of the installation are automated Theconfiguration doesnrsquot differentiate between local or remote installations This matters only for the deployment of theweb content
For local development itrsquos possible to use an LX container
$ sudo ansible-playbook develcontaineryml
To get everything running some additional steps (check the network inside the container generate keys etc) areneeded After you are done check it
$ sudo ansible webshop -m setup
From the management system
$ sudo ssh-copy-id -i rootsshid_rsapub root[IP address of your managed node]
The configuration of Ansible itself (adding the system to etcansiblehosts and copying the SSH keys) isnot documented at this place There are various resources available like here All playbooks are located in the folderdevel Start the setup with the command shown below
$ sudo ansible-playbook develsetupyml
The used group name in etcansiblehosts is webshop
If the setup completes without errors then the web server is accessible and show a default page Please keep in mindthat the server is only accessible over https unencrypted traffic is not allowed
1542 DeploymentSetup website
For the simple deployment of the lastest version of the shop a playbook called deployyml is provided Thisplaybook put all files in place
$ sudo ansible-playbook develdeployyml
To full deploy the webshop all tables in the database must exist The file webshopsql contains all needed SQLcommands and sample data for the web application
Itrsquos possible to deploy the website manually but this is not recommended A couple of files are depending on templateswhich are created during the deployment
Itrsquos also not recommanded to clone everything into your webserver root This would save you the trouble of doing itby hand but third-party features are missing then Those missing parts are the template engine the pdf generation theconnection to Openstreetmap and probably other things not mentioned here
155 Git respository
All project relevante informations (Source code templates documentation etc) is located in a public Git repositoryon Github
38 Kapitel 15 Development
Shop Documentation Release 001
156 Documentation
The documentation is using reStructuredText as markup language For a local build Sphinx is needed Sphinx isavailable in the Fedora Package Collection and can be installed with yum or any other package management tool
yum -y install python-sphinx python-docutils
The source files of the documentation are located under docs
$ cd docs$ make html
The output is stored under docs_buildhtml
After every push to Github a hook launch a rebuild of the documentation The latest release will be published on Readthe Docs automatically
httpsshoprtfdorg
156 Documentation 39
Shop Documentation Release 001
40 Kapitel 15 Development
KAPITEL 16
Indices and tables
bull genindex
bull modindex
bull search
41
- Basics
-
- Products
- Personas
- Use cases
- Design principles
-
- Web shop Design
-
- General
- Layout
- Sitemap
- Main page
-
- Style and design
-
- Cascading Style Sheets
- Pages
-
- Dynamics
-
- Setup
- Current year
- Navigation Menu
- List of Products
- Company details
-
- External files
-
- Navigation Menu
- Header
- Footer
-
- Input processing
-
- ``Buy Now links
- Select options
-
- Javascript
-
- Simple use case
-
- Cookies and Sessions
-
- Cookies
- Hit counter
- Language selection
- User Accounts
-
- Database
-
- Tables
- PHP
-
- Web service
-
- Map
- Weather
-
- Data export
-
- JSON
-
- Messaging
-
- MQTT
-
- Localisation (L10n)
- Templates
-
- Template
- Content
-
- Development
-
- Web server
- Database server
- Versions
- Setup infrastructure
- Git respository
- Documentation
-
- Indices and tables
-
KAPITEL 13
Localisation (L10n)
There are several ways to add localisation to a web site For small projects arrays with string can work but this is notvery efficient and user-friendly With Gettext is a toolset available that provide a framework to produce multi-lingualcontent in a wide area of programming languages
Make sure that the php-gettext package is available on your system If not install it
$ sudo yum -y install php-php-gettext
Check if gettext support is available
ltphpif (function_exists(gettext))
echo gettext is not installednelse
echo gettext is supportedn
gt
Make sure that all locales your want are available on the server
locale -a
The first step is to mark all string which should be translatable as shown below For further details please refer to theGettext documentation
echo _(rsquoSome textrsquo)
The next step is to extract all strings
xgettext --from-code=UTF-8 -o localewebshoppot php scriptsphp
To re-generate the file after an update join the strings
xgettext -j --from-code=UTF-8 -o localewebshoppot php scriptsphp
For every language a po file is needed for the transations Generate it with the command mentioned below
msginit --no-translator -l de_CH -o localede_CHpo -i localewebshoppot
Once created there are only updates of the message catalog needed in the futures
msgmerge -U localede_CHpo localewebshoppot
If you re finish create the mo file for the specific language
33
Shop Documentation Release 001
msgfmt -c -v -o localede_CHLC_MESSAGESwebshopmo localede_CHpo
34 Kapitel 13 Localisation (L10n)
KAPITEL 14
Templates
Beside other solutions Savant3 is a lightweight object-oriented template system for PHP This solution does not needa lot of additional configuration
141 Template
A simple template file looks like the one shown below
lthtmlgtltheadgt
lttitlegtltphp echo $this-gteprint($this-gttitle) gtlttitlegtltheadgtltbodygt
ltphp echo $this-gteprint($this-gtcontent) gtltbodygt
lthtmlgt
For a more detailed intro check this article on Zend Developer Zone
142 Content
To fill the template with data all wished variables needs to be defined in a seperate PHP file
ltphprequire_once rsquoscriptsSavant3phprsquo$tpl = new Savant3()
Create a title$title = Simple sample page
Create the content of the page$content = Some sample text to show
Assign values to the Savant instance$tpl-gttitle = $title$tpl-gtcontent = $content
Define the template source file to show$tpl-gtdisplay(rsquosimpletplphprsquo)
gt
35
Shop Documentation Release 001
The webshop contains a page (master)
36 Kapitel 14 Templates
KAPITEL 15
Development
This sections describes the configuration of the development and runtime environment for the web shop
151 Web server
Instead of Apache the project is running on Lighttpd The reasons are that Lighttpd provides faster setup easierconfiguration and better performance Lighttpd is running with FastCGI
The path of the web server is varwwwlighttpd and the SELinux configuration are still the defaults
The web server is running in SSL-only mode and the certificate is generated during the server setup process
152 Database server
For persistence storage the drop-in replacement MariaDB is used MySQL will work to but this is not tested phpMyAd-min is available under phpmyadmin on the web server beside the command-line tools for easy administration
The default credentials for phpMyAdmin are rootwebshop or the entry you made in the Ansible playbookdevelvariablessensitiveyml
153 Versions
The web shop is built with the below listed components and tested Other releases can be used and may work but thiswill not be tested Probably it will work with different releases
bull Operating system Fedora 20
bull Kernel 3135-202fc20x86_64
bull Lighttpd 1434
bull PHP 557
bull MariaDB 5534
For communication postfix and mosquitto are needed additionally
37
Shop Documentation Release 001
154 Setup infrastructure
1541 Configuration management
For the creation of reproducable and identical environment for the development and the run-time across differentsystems Ansible is used as configuration management solution All needed steps of the installation are automated Theconfiguration doesnrsquot differentiate between local or remote installations This matters only for the deployment of theweb content
For local development itrsquos possible to use an LX container
$ sudo ansible-playbook develcontaineryml
To get everything running some additional steps (check the network inside the container generate keys etc) areneeded After you are done check it
$ sudo ansible webshop -m setup
From the management system
$ sudo ssh-copy-id -i rootsshid_rsapub root[IP address of your managed node]
The configuration of Ansible itself (adding the system to etcansiblehosts and copying the SSH keys) isnot documented at this place There are various resources available like here All playbooks are located in the folderdevel Start the setup with the command shown below
$ sudo ansible-playbook develsetupyml
The used group name in etcansiblehosts is webshop
If the setup completes without errors then the web server is accessible and show a default page Please keep in mindthat the server is only accessible over https unencrypted traffic is not allowed
1542 DeploymentSetup website
For the simple deployment of the lastest version of the shop a playbook called deployyml is provided Thisplaybook put all files in place
$ sudo ansible-playbook develdeployyml
To full deploy the webshop all tables in the database must exist The file webshopsql contains all needed SQLcommands and sample data for the web application
Itrsquos possible to deploy the website manually but this is not recommended A couple of files are depending on templateswhich are created during the deployment
Itrsquos also not recommanded to clone everything into your webserver root This would save you the trouble of doing itby hand but third-party features are missing then Those missing parts are the template engine the pdf generation theconnection to Openstreetmap and probably other things not mentioned here
155 Git respository
All project relevante informations (Source code templates documentation etc) is located in a public Git repositoryon Github
38 Kapitel 15 Development
Shop Documentation Release 001
156 Documentation
The documentation is using reStructuredText as markup language For a local build Sphinx is needed Sphinx isavailable in the Fedora Package Collection and can be installed with yum or any other package management tool
yum -y install python-sphinx python-docutils
The source files of the documentation are located under docs
$ cd docs$ make html
The output is stored under docs_buildhtml
After every push to Github a hook launch a rebuild of the documentation The latest release will be published on Readthe Docs automatically
httpsshoprtfdorg
156 Documentation 39
Shop Documentation Release 001
40 Kapitel 15 Development
KAPITEL 16
Indices and tables
bull genindex
bull modindex
bull search
41
- Basics
-
- Products
- Personas
- Use cases
- Design principles
-
- Web shop Design
-
- General
- Layout
- Sitemap
- Main page
-
- Style and design
-
- Cascading Style Sheets
- Pages
-
- Dynamics
-
- Setup
- Current year
- Navigation Menu
- List of Products
- Company details
-
- External files
-
- Navigation Menu
- Header
- Footer
-
- Input processing
-
- ``Buy Now links
- Select options
-
- Javascript
-
- Simple use case
-
- Cookies and Sessions
-
- Cookies
- Hit counter
- Language selection
- User Accounts
-
- Database
-
- Tables
- PHP
-
- Web service
-
- Map
- Weather
-
- Data export
-
- JSON
-
- Messaging
-
- MQTT
-
- Localisation (L10n)
- Templates
-
- Template
- Content
-
- Development
-
- Web server
- Database server
- Versions
- Setup infrastructure
- Git respository
- Documentation
-
- Indices and tables
-
Shop Documentation Release 001
msgfmt -c -v -o localede_CHLC_MESSAGESwebshopmo localede_CHpo
34 Kapitel 13 Localisation (L10n)
KAPITEL 14
Templates
Beside other solutions Savant3 is a lightweight object-oriented template system for PHP This solution does not needa lot of additional configuration
141 Template
A simple template file looks like the one shown below
lthtmlgtltheadgt
lttitlegtltphp echo $this-gteprint($this-gttitle) gtlttitlegtltheadgtltbodygt
ltphp echo $this-gteprint($this-gtcontent) gtltbodygt
lthtmlgt
For a more detailed intro check this article on Zend Developer Zone
142 Content
To fill the template with data all wished variables needs to be defined in a seperate PHP file
ltphprequire_once rsquoscriptsSavant3phprsquo$tpl = new Savant3()
Create a title$title = Simple sample page
Create the content of the page$content = Some sample text to show
Assign values to the Savant instance$tpl-gttitle = $title$tpl-gtcontent = $content
Define the template source file to show$tpl-gtdisplay(rsquosimpletplphprsquo)
gt
35
Shop Documentation Release 001
The webshop contains a page (master)
36 Kapitel 14 Templates
KAPITEL 15
Development
This sections describes the configuration of the development and runtime environment for the web shop
151 Web server
Instead of Apache the project is running on Lighttpd The reasons are that Lighttpd provides faster setup easierconfiguration and better performance Lighttpd is running with FastCGI
The path of the web server is varwwwlighttpd and the SELinux configuration are still the defaults
The web server is running in SSL-only mode and the certificate is generated during the server setup process
152 Database server
For persistence storage the drop-in replacement MariaDB is used MySQL will work to but this is not tested phpMyAd-min is available under phpmyadmin on the web server beside the command-line tools for easy administration
The default credentials for phpMyAdmin are rootwebshop or the entry you made in the Ansible playbookdevelvariablessensitiveyml
153 Versions
The web shop is built with the below listed components and tested Other releases can be used and may work but thiswill not be tested Probably it will work with different releases
bull Operating system Fedora 20
bull Kernel 3135-202fc20x86_64
bull Lighttpd 1434
bull PHP 557
bull MariaDB 5534
For communication postfix and mosquitto are needed additionally
37
Shop Documentation Release 001
154 Setup infrastructure
1541 Configuration management
For the creation of reproducable and identical environment for the development and the run-time across differentsystems Ansible is used as configuration management solution All needed steps of the installation are automated Theconfiguration doesnrsquot differentiate between local or remote installations This matters only for the deployment of theweb content
For local development itrsquos possible to use an LX container
$ sudo ansible-playbook develcontaineryml
To get everything running some additional steps (check the network inside the container generate keys etc) areneeded After you are done check it
$ sudo ansible webshop -m setup
From the management system
$ sudo ssh-copy-id -i rootsshid_rsapub root[IP address of your managed node]
The configuration of Ansible itself (adding the system to etcansiblehosts and copying the SSH keys) isnot documented at this place There are various resources available like here All playbooks are located in the folderdevel Start the setup with the command shown below
$ sudo ansible-playbook develsetupyml
The used group name in etcansiblehosts is webshop
If the setup completes without errors then the web server is accessible and show a default page Please keep in mindthat the server is only accessible over https unencrypted traffic is not allowed
1542 DeploymentSetup website
For the simple deployment of the lastest version of the shop a playbook called deployyml is provided Thisplaybook put all files in place
$ sudo ansible-playbook develdeployyml
To full deploy the webshop all tables in the database must exist The file webshopsql contains all needed SQLcommands and sample data for the web application
Itrsquos possible to deploy the website manually but this is not recommended A couple of files are depending on templateswhich are created during the deployment
Itrsquos also not recommanded to clone everything into your webserver root This would save you the trouble of doing itby hand but third-party features are missing then Those missing parts are the template engine the pdf generation theconnection to Openstreetmap and probably other things not mentioned here
155 Git respository
All project relevante informations (Source code templates documentation etc) is located in a public Git repositoryon Github
38 Kapitel 15 Development
Shop Documentation Release 001
156 Documentation
The documentation is using reStructuredText as markup language For a local build Sphinx is needed Sphinx isavailable in the Fedora Package Collection and can be installed with yum or any other package management tool
yum -y install python-sphinx python-docutils
The source files of the documentation are located under docs
$ cd docs$ make html
The output is stored under docs_buildhtml
After every push to Github a hook launch a rebuild of the documentation The latest release will be published on Readthe Docs automatically
httpsshoprtfdorg
156 Documentation 39
Shop Documentation Release 001
40 Kapitel 15 Development
KAPITEL 16
Indices and tables
bull genindex
bull modindex
bull search
41
- Basics
-
- Products
- Personas
- Use cases
- Design principles
-
- Web shop Design
-
- General
- Layout
- Sitemap
- Main page
-
- Style and design
-
- Cascading Style Sheets
- Pages
-
- Dynamics
-
- Setup
- Current year
- Navigation Menu
- List of Products
- Company details
-
- External files
-
- Navigation Menu
- Header
- Footer
-
- Input processing
-
- ``Buy Now links
- Select options
-
- Javascript
-
- Simple use case
-
- Cookies and Sessions
-
- Cookies
- Hit counter
- Language selection
- User Accounts
-
- Database
-
- Tables
- PHP
-
- Web service
-
- Map
- Weather
-
- Data export
-
- JSON
-
- Messaging
-
- MQTT
-
- Localisation (L10n)
- Templates
-
- Template
- Content
-
- Development
-
- Web server
- Database server
- Versions
- Setup infrastructure
- Git respository
- Documentation
-
- Indices and tables
-
KAPITEL 14
Templates
Beside other solutions Savant3 is a lightweight object-oriented template system for PHP This solution does not needa lot of additional configuration
141 Template
A simple template file looks like the one shown below
lthtmlgtltheadgt
lttitlegtltphp echo $this-gteprint($this-gttitle) gtlttitlegtltheadgtltbodygt
ltphp echo $this-gteprint($this-gtcontent) gtltbodygt
lthtmlgt
For a more detailed intro check this article on Zend Developer Zone
142 Content
To fill the template with data all wished variables needs to be defined in a seperate PHP file
ltphprequire_once rsquoscriptsSavant3phprsquo$tpl = new Savant3()
Create a title$title = Simple sample page
Create the content of the page$content = Some sample text to show
Assign values to the Savant instance$tpl-gttitle = $title$tpl-gtcontent = $content
Define the template source file to show$tpl-gtdisplay(rsquosimpletplphprsquo)
gt
35
Shop Documentation Release 001
The webshop contains a page (master)
36 Kapitel 14 Templates
KAPITEL 15
Development
This sections describes the configuration of the development and runtime environment for the web shop
151 Web server
Instead of Apache the project is running on Lighttpd The reasons are that Lighttpd provides faster setup easierconfiguration and better performance Lighttpd is running with FastCGI
The path of the web server is varwwwlighttpd and the SELinux configuration are still the defaults
The web server is running in SSL-only mode and the certificate is generated during the server setup process
152 Database server
For persistence storage the drop-in replacement MariaDB is used MySQL will work to but this is not tested phpMyAd-min is available under phpmyadmin on the web server beside the command-line tools for easy administration
The default credentials for phpMyAdmin are rootwebshop or the entry you made in the Ansible playbookdevelvariablessensitiveyml
153 Versions
The web shop is built with the below listed components and tested Other releases can be used and may work but thiswill not be tested Probably it will work with different releases
bull Operating system Fedora 20
bull Kernel 3135-202fc20x86_64
bull Lighttpd 1434
bull PHP 557
bull MariaDB 5534
For communication postfix and mosquitto are needed additionally
37
Shop Documentation Release 001
154 Setup infrastructure
1541 Configuration management
For the creation of reproducable and identical environment for the development and the run-time across differentsystems Ansible is used as configuration management solution All needed steps of the installation are automated Theconfiguration doesnrsquot differentiate between local or remote installations This matters only for the deployment of theweb content
For local development itrsquos possible to use an LX container
$ sudo ansible-playbook develcontaineryml
To get everything running some additional steps (check the network inside the container generate keys etc) areneeded After you are done check it
$ sudo ansible webshop -m setup
From the management system
$ sudo ssh-copy-id -i rootsshid_rsapub root[IP address of your managed node]
The configuration of Ansible itself (adding the system to etcansiblehosts and copying the SSH keys) isnot documented at this place There are various resources available like here All playbooks are located in the folderdevel Start the setup with the command shown below
$ sudo ansible-playbook develsetupyml
The used group name in etcansiblehosts is webshop
If the setup completes without errors then the web server is accessible and show a default page Please keep in mindthat the server is only accessible over https unencrypted traffic is not allowed
1542 DeploymentSetup website
For the simple deployment of the lastest version of the shop a playbook called deployyml is provided Thisplaybook put all files in place
$ sudo ansible-playbook develdeployyml
To full deploy the webshop all tables in the database must exist The file webshopsql contains all needed SQLcommands and sample data for the web application
Itrsquos possible to deploy the website manually but this is not recommended A couple of files are depending on templateswhich are created during the deployment
Itrsquos also not recommanded to clone everything into your webserver root This would save you the trouble of doing itby hand but third-party features are missing then Those missing parts are the template engine the pdf generation theconnection to Openstreetmap and probably other things not mentioned here
155 Git respository
All project relevante informations (Source code templates documentation etc) is located in a public Git repositoryon Github
38 Kapitel 15 Development
Shop Documentation Release 001
156 Documentation
The documentation is using reStructuredText as markup language For a local build Sphinx is needed Sphinx isavailable in the Fedora Package Collection and can be installed with yum or any other package management tool
yum -y install python-sphinx python-docutils
The source files of the documentation are located under docs
$ cd docs$ make html
The output is stored under docs_buildhtml
After every push to Github a hook launch a rebuild of the documentation The latest release will be published on Readthe Docs automatically
httpsshoprtfdorg
156 Documentation 39
Shop Documentation Release 001
40 Kapitel 15 Development
KAPITEL 16
Indices and tables
bull genindex
bull modindex
bull search
41
- Basics
-
- Products
- Personas
- Use cases
- Design principles
-
- Web shop Design
-
- General
- Layout
- Sitemap
- Main page
-
- Style and design
-
- Cascading Style Sheets
- Pages
-
- Dynamics
-
- Setup
- Current year
- Navigation Menu
- List of Products
- Company details
-
- External files
-
- Navigation Menu
- Header
- Footer
-
- Input processing
-
- ``Buy Now links
- Select options
-
- Javascript
-
- Simple use case
-
- Cookies and Sessions
-
- Cookies
- Hit counter
- Language selection
- User Accounts
-
- Database
-
- Tables
- PHP
-
- Web service
-
- Map
- Weather
-
- Data export
-
- JSON
-
- Messaging
-
- MQTT
-
- Localisation (L10n)
- Templates
-
- Template
- Content
-
- Development
-
- Web server
- Database server
- Versions
- Setup infrastructure
- Git respository
- Documentation
-
- Indices and tables
-
Shop Documentation Release 001
The webshop contains a page (master)
36 Kapitel 14 Templates
KAPITEL 15
Development
This sections describes the configuration of the development and runtime environment for the web shop
151 Web server
Instead of Apache the project is running on Lighttpd The reasons are that Lighttpd provides faster setup easierconfiguration and better performance Lighttpd is running with FastCGI
The path of the web server is varwwwlighttpd and the SELinux configuration are still the defaults
The web server is running in SSL-only mode and the certificate is generated during the server setup process
152 Database server
For persistence storage the drop-in replacement MariaDB is used MySQL will work to but this is not tested phpMyAd-min is available under phpmyadmin on the web server beside the command-line tools for easy administration
The default credentials for phpMyAdmin are rootwebshop or the entry you made in the Ansible playbookdevelvariablessensitiveyml
153 Versions
The web shop is built with the below listed components and tested Other releases can be used and may work but thiswill not be tested Probably it will work with different releases
bull Operating system Fedora 20
bull Kernel 3135-202fc20x86_64
bull Lighttpd 1434
bull PHP 557
bull MariaDB 5534
For communication postfix and mosquitto are needed additionally
37
Shop Documentation Release 001
154 Setup infrastructure
1541 Configuration management
For the creation of reproducable and identical environment for the development and the run-time across differentsystems Ansible is used as configuration management solution All needed steps of the installation are automated Theconfiguration doesnrsquot differentiate between local or remote installations This matters only for the deployment of theweb content
For local development itrsquos possible to use an LX container
$ sudo ansible-playbook develcontaineryml
To get everything running some additional steps (check the network inside the container generate keys etc) areneeded After you are done check it
$ sudo ansible webshop -m setup
From the management system
$ sudo ssh-copy-id -i rootsshid_rsapub root[IP address of your managed node]
The configuration of Ansible itself (adding the system to etcansiblehosts and copying the SSH keys) isnot documented at this place There are various resources available like here All playbooks are located in the folderdevel Start the setup with the command shown below
$ sudo ansible-playbook develsetupyml
The used group name in etcansiblehosts is webshop
If the setup completes without errors then the web server is accessible and show a default page Please keep in mindthat the server is only accessible over https unencrypted traffic is not allowed
1542 DeploymentSetup website
For the simple deployment of the lastest version of the shop a playbook called deployyml is provided Thisplaybook put all files in place
$ sudo ansible-playbook develdeployyml
To full deploy the webshop all tables in the database must exist The file webshopsql contains all needed SQLcommands and sample data for the web application
Itrsquos possible to deploy the website manually but this is not recommended A couple of files are depending on templateswhich are created during the deployment
Itrsquos also not recommanded to clone everything into your webserver root This would save you the trouble of doing itby hand but third-party features are missing then Those missing parts are the template engine the pdf generation theconnection to Openstreetmap and probably other things not mentioned here
155 Git respository
All project relevante informations (Source code templates documentation etc) is located in a public Git repositoryon Github
38 Kapitel 15 Development
Shop Documentation Release 001
156 Documentation
The documentation is using reStructuredText as markup language For a local build Sphinx is needed Sphinx isavailable in the Fedora Package Collection and can be installed with yum or any other package management tool
yum -y install python-sphinx python-docutils
The source files of the documentation are located under docs
$ cd docs$ make html
The output is stored under docs_buildhtml
After every push to Github a hook launch a rebuild of the documentation The latest release will be published on Readthe Docs automatically
httpsshoprtfdorg
156 Documentation 39
Shop Documentation Release 001
40 Kapitel 15 Development
KAPITEL 16
Indices and tables
bull genindex
bull modindex
bull search
41
- Basics
-
- Products
- Personas
- Use cases
- Design principles
-
- Web shop Design
-
- General
- Layout
- Sitemap
- Main page
-
- Style and design
-
- Cascading Style Sheets
- Pages
-
- Dynamics
-
- Setup
- Current year
- Navigation Menu
- List of Products
- Company details
-
- External files
-
- Navigation Menu
- Header
- Footer
-
- Input processing
-
- ``Buy Now links
- Select options
-
- Javascript
-
- Simple use case
-
- Cookies and Sessions
-
- Cookies
- Hit counter
- Language selection
- User Accounts
-
- Database
-
- Tables
- PHP
-
- Web service
-
- Map
- Weather
-
- Data export
-
- JSON
-
- Messaging
-
- MQTT
-
- Localisation (L10n)
- Templates
-
- Template
- Content
-
- Development
-
- Web server
- Database server
- Versions
- Setup infrastructure
- Git respository
- Documentation
-
- Indices and tables
-
KAPITEL 15
Development
This sections describes the configuration of the development and runtime environment for the web shop
151 Web server
Instead of Apache the project is running on Lighttpd The reasons are that Lighttpd provides faster setup easierconfiguration and better performance Lighttpd is running with FastCGI
The path of the web server is varwwwlighttpd and the SELinux configuration are still the defaults
The web server is running in SSL-only mode and the certificate is generated during the server setup process
152 Database server
For persistence storage the drop-in replacement MariaDB is used MySQL will work to but this is not tested phpMyAd-min is available under phpmyadmin on the web server beside the command-line tools for easy administration
The default credentials for phpMyAdmin are rootwebshop or the entry you made in the Ansible playbookdevelvariablessensitiveyml
153 Versions
The web shop is built with the below listed components and tested Other releases can be used and may work but thiswill not be tested Probably it will work with different releases
bull Operating system Fedora 20
bull Kernel 3135-202fc20x86_64
bull Lighttpd 1434
bull PHP 557
bull MariaDB 5534
For communication postfix and mosquitto are needed additionally
37
Shop Documentation Release 001
154 Setup infrastructure
1541 Configuration management
For the creation of reproducable and identical environment for the development and the run-time across differentsystems Ansible is used as configuration management solution All needed steps of the installation are automated Theconfiguration doesnrsquot differentiate between local or remote installations This matters only for the deployment of theweb content
For local development itrsquos possible to use an LX container
$ sudo ansible-playbook develcontaineryml
To get everything running some additional steps (check the network inside the container generate keys etc) areneeded After you are done check it
$ sudo ansible webshop -m setup
From the management system
$ sudo ssh-copy-id -i rootsshid_rsapub root[IP address of your managed node]
The configuration of Ansible itself (adding the system to etcansiblehosts and copying the SSH keys) isnot documented at this place There are various resources available like here All playbooks are located in the folderdevel Start the setup with the command shown below
$ sudo ansible-playbook develsetupyml
The used group name in etcansiblehosts is webshop
If the setup completes without errors then the web server is accessible and show a default page Please keep in mindthat the server is only accessible over https unencrypted traffic is not allowed
1542 DeploymentSetup website
For the simple deployment of the lastest version of the shop a playbook called deployyml is provided Thisplaybook put all files in place
$ sudo ansible-playbook develdeployyml
To full deploy the webshop all tables in the database must exist The file webshopsql contains all needed SQLcommands and sample data for the web application
Itrsquos possible to deploy the website manually but this is not recommended A couple of files are depending on templateswhich are created during the deployment
Itrsquos also not recommanded to clone everything into your webserver root This would save you the trouble of doing itby hand but third-party features are missing then Those missing parts are the template engine the pdf generation theconnection to Openstreetmap and probably other things not mentioned here
155 Git respository
All project relevante informations (Source code templates documentation etc) is located in a public Git repositoryon Github
38 Kapitel 15 Development
Shop Documentation Release 001
156 Documentation
The documentation is using reStructuredText as markup language For a local build Sphinx is needed Sphinx isavailable in the Fedora Package Collection and can be installed with yum or any other package management tool
yum -y install python-sphinx python-docutils
The source files of the documentation are located under docs
$ cd docs$ make html
The output is stored under docs_buildhtml
After every push to Github a hook launch a rebuild of the documentation The latest release will be published on Readthe Docs automatically
httpsshoprtfdorg
156 Documentation 39
Shop Documentation Release 001
40 Kapitel 15 Development
KAPITEL 16
Indices and tables
bull genindex
bull modindex
bull search
41
- Basics
-
- Products
- Personas
- Use cases
- Design principles
-
- Web shop Design
-
- General
- Layout
- Sitemap
- Main page
-
- Style and design
-
- Cascading Style Sheets
- Pages
-
- Dynamics
-
- Setup
- Current year
- Navigation Menu
- List of Products
- Company details
-
- External files
-
- Navigation Menu
- Header
- Footer
-
- Input processing
-
- ``Buy Now links
- Select options
-
- Javascript
-
- Simple use case
-
- Cookies and Sessions
-
- Cookies
- Hit counter
- Language selection
- User Accounts
-
- Database
-
- Tables
- PHP
-
- Web service
-
- Map
- Weather
-
- Data export
-
- JSON
-
- Messaging
-
- MQTT
-
- Localisation (L10n)
- Templates
-
- Template
- Content
-
- Development
-
- Web server
- Database server
- Versions
- Setup infrastructure
- Git respository
- Documentation
-
- Indices and tables
-
Shop Documentation Release 001
154 Setup infrastructure
1541 Configuration management
For the creation of reproducable and identical environment for the development and the run-time across differentsystems Ansible is used as configuration management solution All needed steps of the installation are automated Theconfiguration doesnrsquot differentiate between local or remote installations This matters only for the deployment of theweb content
For local development itrsquos possible to use an LX container
$ sudo ansible-playbook develcontaineryml
To get everything running some additional steps (check the network inside the container generate keys etc) areneeded After you are done check it
$ sudo ansible webshop -m setup
From the management system
$ sudo ssh-copy-id -i rootsshid_rsapub root[IP address of your managed node]
The configuration of Ansible itself (adding the system to etcansiblehosts and copying the SSH keys) isnot documented at this place There are various resources available like here All playbooks are located in the folderdevel Start the setup with the command shown below
$ sudo ansible-playbook develsetupyml
The used group name in etcansiblehosts is webshop
If the setup completes without errors then the web server is accessible and show a default page Please keep in mindthat the server is only accessible over https unencrypted traffic is not allowed
1542 DeploymentSetup website
For the simple deployment of the lastest version of the shop a playbook called deployyml is provided Thisplaybook put all files in place
$ sudo ansible-playbook develdeployyml
To full deploy the webshop all tables in the database must exist The file webshopsql contains all needed SQLcommands and sample data for the web application
Itrsquos possible to deploy the website manually but this is not recommended A couple of files are depending on templateswhich are created during the deployment
Itrsquos also not recommanded to clone everything into your webserver root This would save you the trouble of doing itby hand but third-party features are missing then Those missing parts are the template engine the pdf generation theconnection to Openstreetmap and probably other things not mentioned here
155 Git respository
All project relevante informations (Source code templates documentation etc) is located in a public Git repositoryon Github
38 Kapitel 15 Development
Shop Documentation Release 001
156 Documentation
The documentation is using reStructuredText as markup language For a local build Sphinx is needed Sphinx isavailable in the Fedora Package Collection and can be installed with yum or any other package management tool
yum -y install python-sphinx python-docutils
The source files of the documentation are located under docs
$ cd docs$ make html
The output is stored under docs_buildhtml
After every push to Github a hook launch a rebuild of the documentation The latest release will be published on Readthe Docs automatically
httpsshoprtfdorg
156 Documentation 39
Shop Documentation Release 001
40 Kapitel 15 Development
KAPITEL 16
Indices and tables
bull genindex
bull modindex
bull search
41
- Basics
-
- Products
- Personas
- Use cases
- Design principles
-
- Web shop Design
-
- General
- Layout
- Sitemap
- Main page
-
- Style and design
-
- Cascading Style Sheets
- Pages
-
- Dynamics
-
- Setup
- Current year
- Navigation Menu
- List of Products
- Company details
-
- External files
-
- Navigation Menu
- Header
- Footer
-
- Input processing
-
- ``Buy Now links
- Select options
-
- Javascript
-
- Simple use case
-
- Cookies and Sessions
-
- Cookies
- Hit counter
- Language selection
- User Accounts
-
- Database
-
- Tables
- PHP
-
- Web service
-
- Map
- Weather
-
- Data export
-
- JSON
-
- Messaging
-
- MQTT
-
- Localisation (L10n)
- Templates
-
- Template
- Content
-
- Development
-
- Web server
- Database server
- Versions
- Setup infrastructure
- Git respository
- Documentation
-
- Indices and tables
-
Shop Documentation Release 001
156 Documentation
The documentation is using reStructuredText as markup language For a local build Sphinx is needed Sphinx isavailable in the Fedora Package Collection and can be installed with yum or any other package management tool
yum -y install python-sphinx python-docutils
The source files of the documentation are located under docs
$ cd docs$ make html
The output is stored under docs_buildhtml
After every push to Github a hook launch a rebuild of the documentation The latest release will be published on Readthe Docs automatically
httpsshoprtfdorg
156 Documentation 39
Shop Documentation Release 001
40 Kapitel 15 Development
KAPITEL 16
Indices and tables
bull genindex
bull modindex
bull search
41
- Basics
-
- Products
- Personas
- Use cases
- Design principles
-
- Web shop Design
-
- General
- Layout
- Sitemap
- Main page
-
- Style and design
-
- Cascading Style Sheets
- Pages
-
- Dynamics
-
- Setup
- Current year
- Navigation Menu
- List of Products
- Company details
-
- External files
-
- Navigation Menu
- Header
- Footer
-
- Input processing
-
- ``Buy Now links
- Select options
-
- Javascript
-
- Simple use case
-
- Cookies and Sessions
-
- Cookies
- Hit counter
- Language selection
- User Accounts
-
- Database
-
- Tables
- PHP
-
- Web service
-
- Map
- Weather
-
- Data export
-
- JSON
-
- Messaging
-
- MQTT
-
- Localisation (L10n)
- Templates
-
- Template
- Content
-
- Development
-
- Web server
- Database server
- Versions
- Setup infrastructure
- Git respository
- Documentation
-
- Indices and tables
-
Shop Documentation Release 001
40 Kapitel 15 Development
KAPITEL 16
Indices and tables
bull genindex
bull modindex
bull search
41
- Basics
-
- Products
- Personas
- Use cases
- Design principles
-
- Web shop Design
-
- General
- Layout
- Sitemap
- Main page
-
- Style and design
-
- Cascading Style Sheets
- Pages
-
- Dynamics
-
- Setup
- Current year
- Navigation Menu
- List of Products
- Company details
-
- External files
-
- Navigation Menu
- Header
- Footer
-
- Input processing
-
- ``Buy Now links
- Select options
-
- Javascript
-
- Simple use case
-
- Cookies and Sessions
-
- Cookies
- Hit counter
- Language selection
- User Accounts
-
- Database
-
- Tables
- PHP
-
- Web service
-
- Map
- Weather
-
- Data export
-
- JSON
-
- Messaging
-
- MQTT
-
- Localisation (L10n)
- Templates
-
- Template
- Content
-
- Development
-
- Web server
- Database server
- Versions
- Setup infrastructure
- Git respository
- Documentation
-
- Indices and tables
-
KAPITEL 16
Indices and tables
bull genindex
bull modindex
bull search
41
- Basics
-
- Products
- Personas
- Use cases
- Design principles
-
- Web shop Design
-
- General
- Layout
- Sitemap
- Main page
-
- Style and design
-
- Cascading Style Sheets
- Pages
-
- Dynamics
-
- Setup
- Current year
- Navigation Menu
- List of Products
- Company details
-
- External files
-
- Navigation Menu
- Header
- Footer
-
- Input processing
-
- ``Buy Now links
- Select options
-
- Javascript
-
- Simple use case
-
- Cookies and Sessions
-
- Cookies
- Hit counter
- Language selection
- User Accounts
-
- Database
-
- Tables
- PHP
-
- Web service
-
- Map
- Weather
-
- Data export
-
- JSON
-
- Messaging
-
- MQTT
-
- Localisation (L10n)
- Templates
-
- Template
- Content
-
- Development
-
- Web server
- Database server
- Versions
- Setup infrastructure
- Git respository
- Documentation
-
- Indices and tables
-