university of maribor faculty of …praksa.uni-mb.si/porocila/e1031364.pdffaculty of electrical...

38
UNIVERSITY OF MARIBOR FACULTY OF ELECTRICAL ENGINEERING AND COMPUTER SCIENCE Internship Report at InGenius Labs Perth, Western Australia Duration 24 April 2012 to 27 July 2012 Mentor Stuart Kidd Student Bojan Kogoj Enrolment number E1031364 Email address [email protected] Telephone number +386 41 393 561

Upload: nguyendang

Post on 13-Mar-2018

215 views

Category:

Documents


3 download

TRANSCRIPT

UNIVERSITY OF MARIBOR

FACULTY OF ELECTRICAL ENGINEERING AND COMPUTER SCIENCE

Internship Report at

InGenius Labs

Perth, Western Australia

Duration 24 April 2012 to 27 July 2012

Mentor Stuart Kidd

Student Bojan Kogoj

Enrolment number E1031364

Email address [email protected]

Telephone number +386 41 393 561

1-2

4

Contents

1 INTRODUCTION 6

1.1 Perth 6

1.2 InGenius Labs 6

2 INTERNSHIP 7

2.1 Working environment and tasks 7

2.2 Tools 7

2.2.1 NetBeans 7

2.2.2 EasyPHP 8

2.2.3 Kohana PHP framework 8

2.2.4 Dropbox 9

2.2.5 JQUERY 9

2.2.6 JSON 9

2.2.7 Google maps 10

2.2.8 Piwik 10

3 THE PROJECTS 11

3.1 Olsen Environment.com.au 11

3.2 Envoy Settlement Agency 12

3.3 Property Resource 13

3.4 Reportable 14

3.5 InGenius Labs 15

3.5.1 News 15

3.5.2 Application – Emotion detective 15

3.5.3 Application – Property Resource 15

3.6 Backpacker Application 16

3.7 Mobile club guide 19

3.7.1 Search 19

3.7.2 User location 20

3.7.3 Location 21

3.7.4 Venues 23

3.7.5 Event 25

3.7.6 Venue 26

3.7.7 Reports 29

3.7.8 Most popular 29

3.7.9 Editing and creating pages 31

3.7.10 Image upload 33

5

4 CONCLUSION 37

5 SOURCES 38

6

1 INTRODUCTION

For my internship I chose to work at InGenius Labs, a company based in Perth, Australia.

The reason for choosing a company abroad was that I wanted a different, more challenging

experience in an English speaking environment. Western Australia was convenient for two

reasons; firstly I have spent there over a year before and am quite familiar with it and Perth

in particular, and secondly, I have my aunt living in this city therefore my accommodation

issues were easily solved.

This report is written in English so that my mentor is able to read and evaluate it.

1.1 Perth

Perth lies on the western coast of Australia. With its 1.7million inhabitants it is the largest

city of Western Australia and also its capital. The city is located along the Indian Ocean and

spans nearly 50km.

Western Australia is economically very successful, mostly due to its rich natural resources.

The most important industry is mining (iron, gold, nickel and natural gas) and associated

sectors. Wheat is the number one agricultural product, and recently service sector has

developed significantly. The company I worked for represents one of them.

1.2 InGenius Labs

InGenius Labs is a small company based in Perth. The owner is Stuart Kidd, who was also

my mentor. The company has a small team of designers and developers who create

applications for mobile devices, mostly iPhone, iPad and Android. Their clients are

companies and individuals working in different areas, so the products of InGenius Labs

range from applications for supporting working processes in mining to games for children

with autism. Occasionally they also create websites which are mostly used for presenting

and advertising applications.

Some of their products, mostly those I have worked on, are mentioned in the following

chapters of this report.

7

2 INTERNSHIP

2.1 Working environment and tasks

I worked mostly in the company’s office, or occasionally, when my mentor was out of

office, I also worked from home. For my work I used my own laptop. Work instructions

were given to me over email or in person. When I communicated with other developers we

used email or Skype.

Although my orientation is Android applications, the majority of my tasks were web

oriented. I created a bigger website, and a few smaller ones for application advertising

purposes. Two of the projects required work with mobile phone developers, since a website

was used only as a web service. On one occasion I had to make an evaluation of three

websites which were due to be moved. The client who owns them did not have access to

their source code and needed estimated costs for the eventual move.

I also attended a three-day conference organised by Media 140 in topics related with mobile

and social issues of contemporary businesses with my mentor as one of the presenters.

Mr. Kidd monitored and evaluated my work and made necessary comments which I used for

improvement. I also received feedback from clients who ordered the product.

After I had completed my internship and returned from Australia, I kept contacts with my

mentor and some of the clients to continue and finalise some work.

In the next chapter tools and technologies I have used will be described.

2.2 Tools

I have used most of the tools I employed for the work with InGenius Labs before I started

my internship. However, there is always room for improvement. During my internship I

enhanced my programming skills. I got some insight into running a small business, from

establishing contacts with potential clients and communicating with them, to team work with

other developers. On top of that, I improved my English language skills.

Here is a brief description of the tools and the way I used them.

2.2.1 NetBeans

Figure 1: NetBeans logo

8

NetBeans is a multi-language IDE (Integrated development environment). With its PHP

support it helps you develop with a nice interface and warns you about syntax errors. I have

used it for website development. I have occasionally worked on more than one project at the

same time, and that is where project groups helped a lot, since I could easily switch between

projects.

2.2.2 EasyPHP

Figure 2: EasyPHP logo

EasyPHP is a software package for PHP developers on Windows. It contains Apache server,

PHP, MySQL, phpMyAdmin and many more features. It is preconfigured, so you can use all

of its functions immediately after installation.

2.2.3 Kohana PHP framework

Figure 3: Kohana logo

Kohana is a HMVC PHP framework. That means that it is based on Model-View-Controller

design, but is less strict, so Model and View can be accessed without controller. The purpose

of the framework is to create easily readable and more consistent code. It helps you develop

a code, since you do not have to write everything because of its predefined features. It also

has built in security, such as escaping MySQL queries.

For my main project I have used Kohana 3.1.

9

2.2.4 Dropbox

Figure 4: Dropbox logo

Even though it is not a development tool, Dropbox has been an incredible help in sharing

projects, since there were over 12000 files shared.

2.2.5 JQUERY

jQuery is the most popular javascript library. It is very fast and helps programmers create

complex scripts with a minimum effort. It can animate, handle events and use AJAX. There

are many plugins available, making development mostly the matter of copy pasting.

Sample:

$('#mydiv').text('This is text').show("slow");

The code above will set the text of element “mydiv” to “This is text” and slowly display it

(expand it).

2.2.6 JSON

JSON (JavaScript Object Notation) is a lightweight data-interchange format. It is a simple

text based notation, which is easily readable by humans and machines. It is natively

supported by some programming languages (such as PHP) and some have written libraries

for it. In comparison to XML it is much smaller, since it contains a minimum amount of data

and is better supported by most programming languages. You can easily save Objects as

well as Arrays and both of them can be nested.

Sample: { "employees": [ { "firstName":"John" , "lastName":"Doe" }, { "firstName":"Anna" , "lastName":"Smith" }, { "firstName":"Peter" , "lastName":"Jones" } ] }

10

This is an Object, containing Array called “employees” which contains Objects with values

of “firstName” and “lastName”.

Because it is so easy to use and is widely spread I have used it in my AJAX requests and for

web services for mobile devices.

2.2.7 Google maps

Two projects required location information. Google maps have a very good support and web

services, so it was a perfect tool for required tasks. I used geocoding API for obtaining an

address from the location and vice versa. I also used Maps for displaying locations.

2.2.8 Piwik

Piwik is an open source traffic analytics. It basically does the same as Google Analytics, but

you host it on your server and have complete access to it. Because of that, I have used it to

create the “most popular” events list for which I required specific data which you cannot get

in any other way. It is very easy to install and use and it made a perfect tool for my task.

Figure 5: Piwik dashboard (piwik.org)

11

3 THE PROJECTS

In the following chapters I will describe some of the products I worked on. Due to relatively

numerous and diverse projects I decided to present some most significant ones. My main

project was Mobile Club Guide, a Website for displaying events all around the world. In the

future mobile application will also be designed therefore a web service has been created.

Only parts of products will be described here and the relevant code.

3.1 Olsen Environment.com.au

Olsen Environment is a company that provides services to mining industry. InGenius Labs

created an iPhone application for them called 'Bionic Balancer', and as part of the contract

also created instructions for use on their website. I have been given all required information

from which I have created an instruction page for the application.

Figure 6: Olsen Environment Instructions

12

I have also been asked to make a vertically scrolling news feed. For the given task I have

used a code found on JSFiddle (http://jsfiddle.net/HxKAJ/21/), which is a javascript/jQuery

code.

Figure 7: Olsen Environment news page

3.2 Envoy Settlement Agency

Envoy Settlement Agency asked for a few corrections on their website which is a static html.

Some employees have changed and the list needed to be updated. Their main request was to

change a quote form, which was a Flash with a PHP backend for email. I have done

minimum changes to backend, but I have replaced Flash form with Html. All design has

been carefully put in CSS, therefore HTML code used is minimal. Here is an example of one

of input boxes:

<div> <label class="l"> Phone number<font color="red">*</font>: </label><p> <input id="phNumber" class="required" type="text" name="phNumber" value="" size="30"> </p> </div>

This code is a part of a form for purchase quote, a very similar form has been created for

sellers quote.

13

Figure 8: Envoy Settlement Agency contact form

3.3 Property Resource

Property Resource is an iPad application for a client. It requires a website as a backend,

which has been created by InGenius Labs. A client has requested a few changes to the

website, mostly smaller text changes which were assigned to me. On one occasion I also had

to change the design, since text change destroyed graphical display of the website. The

changes were mostly in CSS.

14

Figure 9: Property Resource

3.4 Reportable

Reportable is an iPhone and iPad app created to help people make reports with the

government guidelines. My task was to create a simple website for a description of the

application.

Figure 10: The Reportable website

15

3.5 InGenius Labs

A few smaller changes had to be made on the website, mostly adding application

descriptions but also some changes in JavaScript were done.

3.5.1 News

On my company’s website I have been asked to add another section for news. The current

menu did not support another link, so it had to be changed.

Figure 11: InGenius labs menu

3.5.2 Application – Emotion detective

Figure 12: Emotion Detective page

3.5.3 Application – Property Resource

16

Figure 13: Property Resource page

3.6 Backpacker Application

Backpacker Application is an iPhone applicatin for tourists in Australia. Its function is to

help people find different places (later referred to as items). It has 6 categories: Sleep, Food,

Drinks, Cafes, Attractions and Tours. Under each category you can find places with basic

information about them, such as address, phone number, opening times and description.

My job was to make a backend for the application, a web service which would provide

information for mobile device. For this task I used Kohana 3.1, and JSON for

communicating with mobile devices. This is only a backend for a mobile device, therefore

all requests and forms have been created to the liking of an iOS developer.

For the task I have created the following requests

Get comments

Example: getcomments?timestamp=1341389657

Return is an array of all comments, whose timestamp is greater than the one

provided. If timestamp is not provided it is considered to be 0.

Add comment

Example: addcomment

No URL parameters are required, all data is sent via POST.

Get Items

Example: getbackpackeritem?timestamp=1341389657

Return is an array of all items, whose timestamp is greater than the one provided. If

no timestamp is provided it is considered to be 0. Items also contain an array of all

images, which provides URL to image and its thumbnail.

17

Add rating

Example: addrating?item_id=2&rating=4

It accepts two arguments (item ID and rating) vie GET, and returns status success or

error, depending whether rating was successful or whether an error occurred.

For administration, a simple website with the most basic forms has been created. It contains

a list of all items, a form to add and edit items and a form to upload and edit images.

Figure 14: List of items

The form to edit and add items uses Google maps for obtaining location. An address can be

inserted manually, or with the help of Google Maps (address is being fetched from the

location).

18

Figure 15: Input form

19

3.7 Mobile club guide

Mobile club guide is a website and iPhone application for events around the world. My task

was to create a website, as well as web services for mobile devices.

It contains information of artists, events and venues, where events can be separated into

Concerts, Festivals (which includes multiple events), Clubs and Gigs, and even further by its

genre. Here it is described in greater detail, since it was my major project.

3.7.1 Search

There is one search engine for all three main items: events, venues and artists.

Search is being sent via GET parameters, with one parameter called s. (search?s=test).

I wanted the results to be ordered by relevance but I could not use the simple MySQL

expression using LIKE so I had to use MATCH, which also returns a matching value. The

following is a SQL example for events. Kohana database helper only supports functions

which are used by all SQL databases, therefore MATCH is not implemented because it is

MySQL only. This means I had to use hardcoded SQL statements.

$events = DB::query(Database::SELECT, "SELECT name, description, id, 'event' AS type, match(name, description) against ('" . $keyword . "') as rel FROM events WHERE match(name, description) against ('" . $keyword . "') ")->execute()->as_array();

I used a similar SQL expression for artists and venues. Field 'type' has been created to

distinguish between the tables, so we can later on make appropriate URL's. The search

results will be shown as one, so I had to join all three results with the following code.

$result = array_merge($events, $venues, $artists);

Item 'rel' is relevance, which means the higher that number is, the more important it is. To

sort the array by relevance, I used the following code:

function compare_rel($a, $b) { return -strcmp($a['rel'], $b['rel']); } usort($result, 'compare_rel');

The usort function uses quick sort, with the comparing function provided. In this case, I

compare relevance, so it is ordered from the biggest to smallest.

20

Figure 16: Search result

3.7.2 User location

In Venues and Location I show venues and events close to the user’s current location. The

only way to get the user's location is to use GeoIP. There are a few free scripts available,

which you can install on your web server, yet none of them were up to the task because

sometimes they could not locate a town properly. The only other option was to use a web

service, which would provide me with the required data. I have chosen ipinfodb.com for its

precision and speed. The only thing that needs to be done is to make an account because you

have to use an API key to access their service.

Usage is very simple, all you need to provide is a key, ip and define in what format you want

result to be. An example of such url:

http://api.ipinfodb.com/v3/ip-city/?key=<API key>&ip120.145.10.95&format=json

In return I get a JSON containing my location data. This request takes more 100ms, so it

cannot be simply embedded within a PHP code because the website would wait until you

load this data before displaying the website. To solve this problem I created a simple jQuery

call, which would get the required data in the background.

$(function() { $.get('<?php echo Url::base(); ?>geoip'); });

This simple AJAX call triggers PHP script that calls the web service. The following is a web

service response.

21

{ "statusCode": "OK", "statusMessage": "", "ipAddress": "120.145.10.95", "countryCode": "AU", "countryName": "AUSTRALIA", "regionName": "WESTERN AUSTRALIA", "cityName": "PERTH", "zipCode": "-", "latitude": "-31.9333", "longitude": "115.833", "timeZone": "+08:00" }

Most of the information received is up to no use to me, so I extract only countryName,

cityName, latitude and logitude and safely save them as JSON in a cookie.

cookie::set('gloc', json_encode($myloc));

The reason I decided to use a cookie is simple, it is easily usable, and very effective.

The final values in a cookie look like this:

{"city":"PERTH","country":"AUSTRALIA","lat":"-31.9333","lng":"115.833"}

3.7.3 Location

Location by default displays your own city, getting it from the cookie (as described in User

location) unless it is provided in URL (example: location/slovenia/velenje). If a city or a

country cannot be found in the database, it is being requested from Google and asks the user

for confirmation that the town is correct. Google has its own web service and scripts already

created; all you need is to provide the required data as follows:

var geocoder = new google.maps.Geocoder(); //init var address = 'celje, slovenia' geocoder.geocode({ 'address': address }, function (results, status) { //calling web service var lat = results[0].geometry.location.lat(); //getting latitude var lng = results[0].geometry.location.lng(); //getting longitude var city = results[0].address_components[0].long_name; //getting city name

Even Google can make mistakes, so the user has to confirm the location, which is shown on

the map. To do that, we simply create URL using the newly acquired information and

display the map: var mapurl = "http://www.google.com/uds/modules/elements/mapselement/iframe.html?maptype=roadmap&latlng="+lat+","+lng+"&mlatlng="+lat+","+lng+"&zoom=13&mtitle=name&element=true"; $('#gmap').attr('src',mapurl); //setting google map url to the new one

The result can be seen in the following image:

22

Figure 17: Location, adding new city

If the city already exists in the database, it is shown with all its venues . The list below

contains upcoming events in those venues, and if clicked on the ‘pin’, it will open a small

window on the map containing address information and a link to the venue. Each venue has

its own letter, and if all letters have been taken, only dot is used.

23

Figure 18: Location, showing venues and events

3.7.4 Venues

Venues are very similar to Location, except it does not show events. It also works a slightly

differently. When a city cannot be found it does not give you a choice to enter it, but it tells

you to go to location and create it there.

24

Figure 19: Venues when city is unknown

If city is known, it displays a map with all venues and a list.

25

Figure 20: Venues

3.7.5 Event

Events are listed in four groups; concerts, festivals, clubs and gigs. A Festival is basically an

event that holds multiple events. Each event contains the basic information about the

performer, the time, location, ticket cost and a short description. There are also images and

YouTube video. The location address is being fetched from the venue, and so is location for

Google map. By default the map is hidden, and can be easily shown or hidden by clicking on

the link under the address.

26

Figure 21: Event

3.7.6 Venue

Venue is considered to be a place where an event is being held. It can be a club, a concert

hall, a stadium or even a park. It contains all important information such as location

27

(including on a Google map) and description. You can also add images and YouTube video

to it, and all events held there can be easily visible.

Displaying a Google map is actually very simple. Google does most of the work, since in

HTML you only need to put a simple div to show where it should be.

<div class="frame_right" id="map_canvas" style="width:400px;height:300px;margin-left:0px;">

The only thing you need to do is set up settings, define what the zoom should be, center the

coordinates and define type of the map.

var latlng = new google.maps.LatLng(<?php echo $venue['lat']; ?>, <?php echo $venue['lng']; ?>); var options = { zoom: 15, center: latlng, mapTypeId: google.maps.MapTypeId.ROADMAP }; var map = new google.maps.Map($('#map_canvas')[0], options); var latLng = new google.maps.LatLng(<?php echo $venue['lat']; ?>,<?php echo $venue['lng']; ?>); var marker = new google.maps.Marker({ position: latLng, title: '<?php echo $venue['name'] ?>', map: map });

I also inserted a marker in the map so that it shows exactly where the location is. I set ‘Title’

of my marker to venue name. When you click on it, a small window containing the venue

address displays. This has been created with the following code:

var content ='<?php echo Html::chars($venue['name']) ?>'; var address1 = '<?php echo Html::chars($venue['address1']); ?>'; var address2 = '<?php echo Html::chars($venue['address2']); ?>'; content+= '<br />' + address1; content+= ', ' + address2; var infowindow = new google.maps.InfoWindow( { content: content, size: new google.maps.Size(50,50) }); google.maps.event.addListener(marker, 'click', function() { infowindow.open(map,marker);

28

Figure 22: Venue

29

3.7.7 Reports

Website content is being created by its users; therefore some of it might be inappropriate or

incorrect. Administration cannot review every single update, so we rely on users to report

those that break the rules.

A report system has been set up with a “Report” link on every site. When clicking on it a

simple window appears, asking you to provide more details about the problem. Once the

“Report” button is pressed, an AJAX request is being sent to report, and it gives a simple

response.

Figure 23: Report window

Reports can then be viewed in administration and dealt with. Administrator has a choice of

ignoring it, approving or marking it as “in progress”.

Figure 24: List of reports and report view

3.7.8 Most popular

This was one of the very demanding tasks. Getting most popular events on its own is not

very difficult if you save number of visits to each event. The challenge was created by the

30

requirement that it had to be most popular of the last 6 days. In this way we avoid one event

staying on the very top because it was popular at some point. To do this, I had to use

analytics (Piwik) which saves every visit and every view. Unfortunately Piwik does not

provide web services with the information required for this, so I had to go directly to

MySQL and extract data from there. Piwik saves every record to the table

analytics_log_action which contains titles and URL's. Titles have type set to 4, URL's to 1,

so we only need the ones with type 1. Every visit is saved to analytics_log_link_visit_action,

so we link the two tables by id. By using LIKE statements, we only get those url's that

contain /event/<number>, to make sure URL like page/event/edit do not come through. We

only select those that are less than a week old by substracting 6 days from the current date.

Then we order them by number of appearances, so they are in a required order, although

they get mixed up later on. The result is the following SQL statement:

SELECT COUNT( DISTINCT ( llva.idvisitor ) ) AS num, la.name FROM analytics_log_link_visit_action AS llva, analytics_log_action AS la WHERE la.idaction = llva.idaction_url AND la.type = '1' AND (la.name LIKE '%/event/0%' OR la.name LIKE '%/event/1%' OR la.name LIKE '%/event/2%' OR la.name LIKE '%/event/3%' OR la.name LIKE '%/event/4%' OR la.name LIKE '%/event/5%' OR la.name LIKE '%/event/6%' OR la.name LIKE '%/event/7%' OR la.name LIKE '%/event/8%' OR la.name LIKE '%/event/9%') AND llva.server_time >= curdate( ) - INTERVAL DAYOFWEEK( curdate( ) ) +6 DAY GROUP BY la.idaction ORDER BY num DESC LIMIT 5

The results are URL's and are not sufficient. The data required are URL, city, country and

title, so I extract ID using a very simple php code:

foreach ($res as $i => $r) { $tmp = explode('/', $r['name']); $ids[$i] = $tmp[4]; }

To get my missing data I connect the required MySQL tables together and fetch information

using a previously acquired ID's:

DB::select('e.name', 'e.id', array('v.city', 'city'), array('c.name', 'country')) ->from(array('events', 'e')) ->join(array('venues', 'v')) ->on('v.id', '=', 'e.venue_id') ->join(array('countries', 'c')) ->on('c.id', '=', 'v.country_id') ->where('e.id', 'IN', $ids)

31

->execute()->as_array();

I also retreive images for each event but at this point I will not go into details on how I got

them. Unfortunately, when I selected this new data, the order has changed. That having in

mind, I reordered them using the previous array of id's which is correctly ordered:

$out = array(); foreach ($result as $i => $r) { $id = array_search($r['id'], $ids); $out[$id] = $r; }

3.7.9 Editing and creating pages

Every person with a login privilege is allowed to create an event, a venue or an artist. For

that purpose the forms have been created. They are called pages.

Figure 25: Form for creating an event

32

Some fields in forms are connected to other information, already stored in the database, such

as a country in venues, or a venue name in events. To help the user with this, an

autocomplete script has been added.

To do this, I had to use a jQuery autocomplete library, which, after inserting a few

characters, requests similar results from the database using AJAX.

$("#country").autocomplete({ url: '<?php echo Url::base(); ?>search/country?output=json', showResult: function(value, data) { return '<span>' + value + '</span>'; } remoteDataType: 'json' });

The code above calls a PHP script that very simply searches for supplied information and

then encodes it in JSON and prints it out.

$countries = DB::select('name', 'id')->from('countries')->where('name', 'like', $search . '%')->execute(); $result = array(); foreach ($countries as $country) { $result[$country['name']] = $country['id']; } echo json_encode($results);

JSON is picked up by the jQuery and displayed in a list as seen on the image below.

Figure 26: Example of autocomplete

Each event has a starting and finishing date and time, and to help user choose those another

jQuery plugin has been used. The plugin used is called »jQuery Timepicker«, and is an

extension of the official Datepicker script. The usage is very simple, and because data and

time field are separate you also call them separately:

$('#startTime').timepicker({}); $( "#startDate").datepicker({ defaultDate: "+1w", dateFormat: "yy-mm-dd", changeMonth: true, numberOfMonths: 1 });

33

Another thing needed was saving YouTube URL. Inserting a player in the website is very

easy, the code is provided by YouTube:

<iframe width="560" height="315" src="http://www.youtube.com/embed/a-ahy218_FM" frameborder="0" allowfullscreen></iframe>

Unfortunately, there are three different types of URL available (provided by YouTube

website) as seen below:

http://www.youtube.com/embed/a-ahy218_FM http://www.youtube.com/watch?v=a-ahy218_FM http://youtu.be/a-ahy218_FM

Only the first URL can be used in the script, so I had to parse the user's input URL and if it

is not in the correct form, transform it.

$query_string = array(); $result = ""; parse_str(parse_url($fullurl, PHP_URL_QUERY), $query_string); if (isset($query_string["v"])) //#1 { $id = $query_string["v"]; if (strlen($id) > 5) $result = "http://www.youtube.com/embed/" . $id; } else if (preg_match('/http:\/\/[w.]*youtube\.com\/embed\/[^.]+$/', $fullurl)) //#2 $result = $fullurl; else if(preg_match("#(?<=v=)[a-zA-Z0-9-]+(?=&)|(?<=v\/)[^&\n]+|(?<=v=)[^&\n]+|(?<=youtu.be/)[^&\n]+#", $fullurl, $matches)) //#3 { $result = "http://www.youtube.com/embed/" . $matches[0]; }

In number one only this is being searched for: v=a-ahy218_FM. If that exists, it extracts the

hash (a-ahy218_FM) from it, and creates a valid URL.

Number two checks the whole URL ignoring the hash. If URL is correct it will return true,

and use it as it is in a correct form.

The third one does the URL match similar to the second one, but uses the hash from it to

create valid URL. The final URL which can be used in the script is saved in $result.

3.7.10 Image upload

The website will later be used mostly as a backend for mobile applications. Mobile devices

have a smaller screen and much stricter designs, so images uploaded on the website had to

be limited to a certain ration and size. We have decided for one of the most common of

ratios, that is 4:3. To keep a certain quality we decided to use a »minimum size« condition,

and set it to 1024x768.

Images can belong to an event, a venue or an artist. To keep some kind of an order the

images have been saved under a folder of each page, and in another folder, matching pages

ID.

34

Figure 27: Image folders

To keep the order there were two more folders created, one for thumbnails and another one

for images about to be resized.

When you want to upload an image you just click the »Upload image« link on the image

page. With the help of the »Once click upload« jQuery plugin the image is being

immediately uploaded after you select it.

Figure 28: Uploading image

The image has been automatically saved to images/<page>/<id>/tmp folder and renamed for

search engine optimization and to have a unique name. The first page name is changed to

lower case and then stripped of all spaces and replaced with an underscore. To make sure the

image names are unique PHP provides a simple function called uniqid that gives a unique

hash.

$newfilename = str_replace(" ", "_", strtolower($item['name'])) . '-' . uniqid() . '.' . $ext;

Then it is being shown to the user to resize it. To do the job a jQuery plugin called Jcrop is

used. With a few simple settings the plugin automatically ensures that the resized image is a

4:3 ratio and at least 1024x746 in size.

jQuery('#cropbox').Jcrop({

35

onChange: showPreview, onSelect: updateCoords, aspectRatio: 1.33333, minSize:[ 1024, 80 ], boxWidth: 512 });

The result is a very easy to use interface.

Figure 29: Image cropping

Once your desired image has been selected and you press »Crop image« a simple AJAX

request sends your newly chosen image size.

$.post( "<?php echo Url::base() . 'admin/images/resize' . $di . '/' . $item_id ?>", {w:w,h:h,x:x,y:y,image:img} , function(data) {

36

loadingmessage('', 'hide'); if(data=='success') { location.reload(); } } );

Then the server uses a Kohana created class for manipulating the image. First it crops the

image to selected values and then resizes it for image and thumbnail and saves them in

appropriate folders. The last thing left is to remove the original image because it is no longer

required.

$image = Image::factory($targetPath . '/tmp/' . $imgname); $image->crop($w, $h, $x, $y); $image->resize(1024, 768)->save($targetPath . $imgname); $image->resize(200, 150)->save($targetPath . '/thumbnails/' . $imgname); unlink($targetPath . 'tmp/' . $imgname);

37

4 CONCLUSION

I enjoyed my work in spite of the fact that it was occasionally demanding. Creating and

fixing websites for application promotion has been quite an easy but still interesting job.

Creating web services has been interesting because I worked with mobile platform

developers.

Unlike most of the school work where we worked with computer applications and Android

applications, I have worked with PHP websites. I have learned the technologies prior to the

internship and have now improved my skills.

This internship has been a great experience for me, I not only worked for a company with

experienced developers in a foreign country, but I also had an opportunity to meet client’s

requests and cooperate with other programmers.

I would like to thank Mr. Stuart Kidd for giving me a chance to do my internship in his

company and learn from them, and my aunt Marjana for providing a hospitable

accommodation and company in Perth.

38

5 SOURCES

http://kohanaframework.org/

http://jquery.com/

http://netbeans.org/

http://www.json.org/

http://www.dropbox.com/

http://www.easyphp.org/

https://developers.google.com/maps/

http://docs.jquery.com/UI/Autocomplete

http://piwik.org/

http://deepliquid.com/content/Jcrop.html

http://code.google.com/p/ocupload/