Practical CakePHP Projects. Authors. Kai Chan; John Omokore; Richard K. Miller . Book. 65 Readers · k Downloads · Download book PDF. Chapters Table of. The first € price and the £ and $ price are net prices, subject to local VAT. Prices indicated with * include VAT for books; the €(D) includes 7% for. Germany, the. Practical Cake PHP Projects. PHP Free Books Download PDF / Free Books Online / Free eBook Download PDF / Free eBook Download PDF.
|Language:||English, Spanish, Indonesian|
|ePub File Size:||28.67 MB|
|PDF File Size:||20.38 MB|
|Distribution:||Free* [*Regsitration Required]|
Who Should Read This Book Practical CakePHP is a book mainly for developers . Organizations have found that using an in-house framework for web projects. Short Desciption: This books is Free to download. "Practical CakePHP Projects book" is available in PDF Formate. Learn from this free book and enhance your. Request PDF on ResearchGate | Practical CakePHP Projects | If you've been using PHP for sometime now and would like to start using a web framework, you' ll.
If not, we enter the translation into the pseppan[pn]joh]pekjo table on lines 24 and If not, we render the form again with error messages. Finally, the function formats and returns the current category list, which includes only the currently selected category and its children. Candace English Compositor: In our forum application, we want to include some common features that are found in all forums: Changing Languages Since the HTML language selection drop-down list is displayed on every page within the application layout, we have pushed it out as a Cake element, as shown in Listing
Event-based programming is particularly important in an Ajax environment. NNote Before the use of Ajax, just about every activity on a browser was synchronous.
Users had to wait for feedback whenever they generated an event, such as by clicking a link or submitting a form. Essentially, you could make only one call to the server at any one time. With the use of TIHDpplNamqaop in Ajax, we can now make many calls to the server within a single web page, which makes them all asynchronous. Events can happen independently of each other.
Google Maps defines its own specialized events, which are handled by the API itself. These are separate from the DOM events within a browser, which are more generic. Map events are handled by the CArajp object. Examples include buttons that you can use to move the map around, instead of using the mouse, and a sliding control bar to zoom in and out of the map. In Google Maps terminology, these are known as controls. All the control elements subclass the C? You can define your own control by subclassing this class.
For example, you can create a button that makes an Ajax call to your database server, fetching any journey near that location.
Overlays Objects that move with the map are called overlays. These can be pushpins marking the location of a point or graphical lines that show route directions. The API provides several built-in overlay classes, which are listed in Table Markers are interactive in that they can be dragged across the map and placed in a new location.
Each marker has an icon attached to it. You can define your own icon or use the default one. A large number of markers can slow down the display of the map. CLkhuheja This class is used to lay down lines on the map.
There is also a CLkhuckj class, where the lines form a closed area. CPehaH]uanKranh]u With this class, the map itself is an overlay. You can modify the map itself with your own version of the map.
The pop-up bubble speech window is a special overlay; only one can exist in any one map instance. These routes are then marked in blue on the map. As an example, Listing shows plotting a route from New York to Anchorage.
Figure shows the route map itself. When a query is sent off to the Google servers, it returns a number of useful items of information. One of which is the distance between the locations.
This is very important to us, because it will provide the distance via the roads on the map rather than the straight linear distance between locations. However, if the user were planning to fly, the straight line distance would be more appropriate. OK, now that we have explained how Google Maps work, we can start our application by gathering the requirements.
Application Requirements Our travel application will allow our friends and also the general public to plan their travel journeys and make comments on the places they visit. It will be a web site where they can keep friends and families up-to-date on their travels.
A user interface can then be created based on these conclusions. We run through the ways in which our friends will use the site. We start the process by asking them some broad questions. These are mapped out as follows: Users want to be able to enter destinations and make comments about those destinations. We need to save the destinations so they can make comments while they are on their journey.
We can continue to draw conclusions from this simple need, but that is probably enough for us. There are numerous conclusions we can draw from this statement. For example, we can map out a user journey based on different personas: Or we could map a user journey based on age groups, such as for students. But in this case, we will simply employ the traveling salesman algorithm to find the shortest route between each destination. We will base our interface on what we know from this brief user-centered design exercise.
So far, we have covered the broad issues of the application. Next, we will map out a functional specification that we can use for our Cake application. The functions will include the following: This will be a comma-separated list of strings or tags, which you can associate with a journey. From the specification, we have sketched out the simple layout of the application in Figure Sketch of our home page Application Structure We will set out to create our journeys controller, which will represent the journeys within the application.
It will be responsible for the server-side needs of the application, saving and retrieving user journeys, for example. Along with the journeys controller, there will be three related models. Remember that the model class names follow the name of the controller. Table shows the relationships among the different tables. This will give us an overall picture of how the different data elements are related to each other. Also, each journey can have more than one tag.
The information in Table can also be shown graphically in an entity-relationship diagram, as in Figure Entity-relationship diagram of application tables NTip Data schemas are quite valuable during development. They help you to visualize the relationships among elements, identify problems, and maybe even improve on the relationships.
In our example, we see that a route has one tag line associated with it, but later on, we may also want tags associated with locations. But would this add too much complexity to the application? Always be aware of feature bloat—adding unnecessary features that may be used only by a small percentage of users. From the data schema, we can create our database tables. Listing shows the structure of the fkqnjauo table. The journeys Table Schema? The jkpao field is for comments about the journey itself.
The locations Table Schema? Listing shows the p]co table structure.
Most of the action will initially occur in the browser itself. The server-side code comes into play when the user decides to save or retrieve the journey information. NNote You can create many layouts in the h]ukqpo folder and change between them in the same view. Just set the h]ukqp variable in the controller action. We start by setting the title in line Next, we include our CSS file for our application in line Remember to use your own key that correlates to your domain name.
This simply takes a user back to the home page. Allows a user to retrieve a saved trip from the database. A user can display any journey. This takes the rendered controller action view content and inserts it into that position. Home Page Now that the global layout has been set up, we can create our home page view. In our application, users must be able to plot out a journey quite easily.
On the home page, we will create a form where users can create their journeys the moment they enter the site. All of the other buttons relate entirely to client-side code and will be used in conjunction with the Google Maps functionality. The first button, Enter a Location, on line 12, will save and display the location in Google Maps locally. The Start Again button, on line 29, will clear the slate for a new journey to be entered. When this home page code is processed with the default layout, we get the output shown in Figure with Paris set as the starting location in this example.
The code and functionality behind all these buttons will be explained in the next section. The class will be called Pn]rahI]llnI]j]can, and it will handle all the client-side functionality relating to the application.
Finally, we set the map to show the location and add a pushpin marker, starting from line Figure shows an example of what a user should see after entering a location. As the algorithm is quite large, we have split the code into three parts. We start the algorithm in Listing Next, we work out all the combinations between the locations on line 17 to line Once that is done, we can start calculating the shortest distances between locations.
We continue from the previous listing with Listing The Ajax geocoding call to the Google servers is asynchronous. Once all that is complete, we can start working out the shortest round-trip.
Before we start, there are two important variables to mention: From their names, you can probably guess what they hold: If there is a next location to visit, we carry on with the algorithm. From this, we use a simple bubble sort to work out the shortest distance to the next location.
When we come around the loop the next time, we pick the last city we came from as the next starting point and start over again. These functions are described in Table This function tells us whether there are any more locations to visit. Once there are no more locations to visit, we have found our shortest route.
This function provides us with the next location to visit, which is always the destination location of the last journey. Once a location has been visited, this function marks that location, so that we do not visit the same location. This tells us whether we have visited a location. This gets all the neighbors that we have not visited.
Using the result returned, we can then find the neighbor with the shortest route to the location. Then, on line 12, we trace a route from the end point back to the start so we have a loop. Next, starting from line 19, we need to carry out some housekeeping functions. Google automatically creates pushpin markers when we plot a location. It is worth noting that for a lot of countries, the path and distance use the roads as the mode of travel, which is the route that we would prefer.
However, in countries where Google doesn't have any road information, the straight path between the locations is used. And that is just about it. Start Again and Save Journey. Start Again is pretty straightforward, as it just clears the variables and refreshes the map. Save Journey is a little more interesting.
It is also less verbose than XML. After entering the three locations, our map application will look like the one shown in Figure A journey with three locations Journey Data For our application, we need to save the journey details and also the tags associated with a journey.
We also need to give users the ability to retrieve journeys for viewing and editing. Saving a Journey All our actions are contained in the one and only Fkqnjauo?
This is the target action for the Save Journey button on the client side. It parses the journey name, tags, and comments and also the journey details including the destination comments. The detail of the destinations arrives in the JSON format. We set two variables to be used by the view: The same form is used to add or edit a journey.
The output of the view is shown in Figure Be careful, as the code in the controller and view can get out of hand. Use components in the controller and view helpers or elements in the view where you can spot common code. These are then passed onto the view for display. Each journey needs to have a password so a user can come back and edit a journey. In practice, you would probably create a user account and attach journeys to a particular user.
However, to keep the application simple, we have attached a password to each journey instead. Within the helper, we can use other helpers by including them in the dahlano array. This is the action in the Fkqnjauo?
Note that in a production environment, these three units of code should be within a transaction block. If one fails, the previous save actions should be rolled back.
If not, we render the form again with error messages. The underscore prefix tells Cake that they are protected actions and should not be executed via any URL request. Saving Tags The tag data that goes with a journey is a set of comma-separated strings. These strings are split up and entered into the p]co table separately. The tag-saving protected action is shown in Listing NNote We could have placed the tags within a single database field in the fkqnjauo table and called it p]co.
However, this would not conform to the first normal form in database normalization, where each field must contain single, not multiple, values. We would run into trouble when we wanted to query the tags within a route. When we are editing a journey, the saving or updating of the tags is done slightly differently, in that we first delete all the tags relating to the journey and then we save the updated tags as if they were new.
We find this technique to be simpler to maintain and easier to read and reuse than the alternative method, where we update any tags that have been changed and delete any tags that have been removed.
The action is shown in Listing The main view elements are shown in Listing We have cut some of the HTML markup to simplify the view.
The outline of the code is shown in Listing If no data is supplied, we simply redirect the user back to the retrieve form.
If not, we will render the retrieve form with an error. The view is pretty straightforward and is shown in Listing In this case, we have combined the display form with the view inserted below it.
These are their comments: You have a spare minute and want to let your pals know what you are doing or thinking, Twitter fits that need nicely. Twitter is a social networking and micro-blogging web application. These short messages are referred to as statuses, updates, or tweets.
We can see Twitter being quite an addiction: In fact, we often view the Twitter public timeline, which is a listing of what people around the world are doing at that moment. However, quite a number of messages are in a foreign language. And in true Web 2. Twitter comes with an API that we can call from the server.
These methods are submitted via the principles of representational state transfer REST. Twitter will also return the appropriate HTTP status code. There are a few more items to be aware of when using the API: As such, we must develop our application with this in mind.
This returns the 20 most recent statuses from the server. Calling the public timeline is easy. Listing shows an example. On line 4, note the patp tag, which is the tag that contains the Twitter status. For example, opnhaj may return different length sizes depending on whether the string is single or multibyte. The API allows you to translate or detect language text.
This is shown in line 8 of Listing Additionally, an API key should be sent. You can obtain a key from either of the following signup pages: If you do not know the original language that you want to translate, you can omit the source language in the h]jcl]en parameter. So, for example, we could simply write h]jcl]en9! Now how cool is that! However, we can all be quite certain this will change at some point in the future.
Application Requirements Even though we are essentially developing this application for fun, we still need to establish some requirements and consider usability. The broad requirement is to give users the ability to view the current public timeline in any language by using the Google Translator to translate the status text. This simple statement gives us a starting point for scoping the application. Scoping an application can be a lengthy task, involving many aspects, such as content, function, layout, wireframes, and site maps—just to mention a few.
Since our application is quite small and should be fun, we will concentrate on the following simple functional requirements: Since this happens to every user, we must always cache the results. We will be making requests to Twitter every 60 seconds. As such, we will cache the results every 60 seconds.
In this way, we have separated the viewing of the statuses and the process that requests Twitter statuses. In order to emphasize the raw nuts and bolts of the application, the interface layout will be kept as simple as possible. There will be two web pages: The top part consists of a header and tag line followed by a navigation area.
We also allow the user to change the language at any point via a drop-down list on the right side of the page. Each item in the list will be a link to the first view statuses page. This page will also have the drop-down list to allow the user to change the language. Sketch of the archive listing page Application Structure Each Twitter request we make will need to be stored in a database table. Remember that a single Twitter request to the public timeline returns 20 statuses.
This naturally maps into a one-to-many relationship. Listing shows the? The pseppan[op]pqoao table will mainly hold all the data that has been returned by the Twitter request.
The structure of how the translation will work is slightly trickier. When a Twitter request is made, the statuses returned will contain different languages. Do we also want to automatically translate them into all the other available languages? Pondering this point, we come up with a half yes and half no answer. Yes, we do want to translate them into other languages, but no, not immediately after fetching them from Twitter.
This job should be spread over a period of time instead. When a user does want to view the statuses in another language, whether they are current or past statuses, we will translate them on the fly and then cache the results. Thus, the first user who chooses to view a Twitter request in a specific language will need to endure the time delay that it takes to translate the 20 statuses. When a status does get translated, the results are stored in the pseppan[pn]joh]pekjo table, shown in Listing The h]jc[bnki field is, in a sense, redundant.
Since localization will be involved somewhere, we see it as an advantage to have a language table that will help us bind different language areas together. Listing shows the schema for this table, named h]jcq]cao. The languages Table Schema? The h]jc[j]ia field is for the name of the language, such as Japanese.
Figure shows the relationships between the tables. In the pseppan[namqaopo table, each request gives us many statuses, which are recorded in the pseppan[op]pqoao table, and each status has many different translations, which are recorded in the pseppan[pn]joh]pekjo table. Database schema for all the Twitter Twister tables Cake Models We now have enough information to build our model classes.
As shown in the database schema Figure , one Twitter request generates many Twitter statuses. This relationship is shown in the PseppanNamqaop model using the d]oI]ju variable, as shown in Listing One pseppan[op]pqoao record has many translations in the pseppan[ pn]joh]pekjo table.
The PseppanPn]joh]pekj model, shown in Listing , is quite simple, in that one single translation belongs to one Twitter status. Oddly, the H]jcq]ca model is the most complex out of the lot, as shown in Listing Some of the code will make more sense when we explain caching later on. The H]jcq]ca model includes two methods: There is nothing surprising about the method, but bear in mind that the data it generates will be cached. The ]bpanO]ra method is a Cake model callback.
The code within the method is executed whenever some data is saved into the database. In our case, we want to delete the cache that holds the data for the language drop-down list, so we can have an up-to-date list of languages. NCaution The ]bpanO]ra method is called only if you execute the o]ra model method. Internationalization and Localization Internationalization abbreviated as i18n is the process of developing software so it is portable between different cultures without any change to its internal coding.
Localization abbreviated as l10n is the process of adapting that software to any specific culture by using a predefined set of parameters called locales, normally stored in text files. In our case, a culture is defined by a number of parameters: Adding or changing the locale in Cake is quite easy. Note that in our application, i18n and l10n will be handling only the static text of the site—such as tag lines, error messages, and so on—so they are quite separate from the job of the Google Translator.
To get started, we first add the default language that we will use. For our application, we will have only two languages available: English and Japanese.
We will create the two files as shown here: The H? Other categories exist, like H? The folder name of the language uses the three-letter ISO language code. The same three-letter code is also used in the? There were originally developed as part of the GNU cappatp utilities for language translation. The English. The Japanese. This will echo the iocopn text, which corresponds to the language that we have set in?
They will be able to easily see translated statuses when they are using a handheld device. Adding different output formats for other devices to consume is a piece of cake! Or so we thought. We wrote a few different methods to achieve what we wanted. Starting with our first method, we saw that in the Cake documentation and some forums, the standard way to output RSS or any other format is to attach the format name you want at the end of the action as a file extension, like this: To get this to work, we need to tell the Nkqpan class about our new extension.
Next, we need to have a specific layout for our RSS output. This is the layout that will surround the actual RSS data. Next, we set up some basic channel data. We want to view the same data in different formats, while keeping the coding for the action unchanged.
It will be the view that will change depending on the type of request. Now, having completed the layout part, we need to write the new RSS view. Listing shows this file. As we hinted early on, we ran into some trouble with our RSS feed.
The problem starts when we add parameters to our URL action requests. For example, if want to view an archive Twitter request in another language, this is the URL we could use: We feel these are just too awkward looking.
We want our URLs to look something like this instead: To overcome this problem, we created two alternative methods. The first method is a bit hackish, while the second one works better.
The first method is quite easy. If a match is found, we artificially set the extension variable atp to noo. But, hey, it works, and one alternative solution is better than none. The new rule is shown in bold.
Caching Our seemingly simple application has gotten a lot more complicated with the need to cache results. To start caching, we need to turn on Cake caching. To cache a view, the setting is made in the action that corresponds to the view.
In the controller, there are two different ways you can do this. We can also cache an action within the action function itself, like this: Caching Models Cake goes through a lot of processing to build the object-relational mapping part of the MVC structure.
NCaution If you change or add database fields, you must delete the cached data models. Be careful of cached data during your development. Sometimes you forget about your caching and then wonder why your changes are not showing up. Check your browser session cache and caching in Cake.
The data we get is saved to the database in the three tables we have created. This is unlike some web caching, where data can be occasionally purged or destroyed. In our application, the caching works in two levels. When a user requests the index page, Cake first checks to see whether the view is held in cache.
This data is essentially saved or cached in the database by the background cron process, which fetches the actual status messages from Twitter. Caching and the Application Layout Caching can bring up a lot of unforeseen problems within the application view. There are two main points to be aware of: Changing Languages Since the HTML language selection drop-down list is displayed on every page within the application layout, we have pushed it out as a Cake element, as shown in Listing However, we do want to cache the language data that was generated by the SQL find operation from the h]jcq]cao table list.
Some readers may notice this odd line of code: As a result, some helpers that depend on the view object, such as the form helper, fail. Because of this, we need to manually register the current view object. This highlights the complexity of caching. And in Cake, when an item is cached, no method in the controller is called. Therefore, we need to rely on session data as a conduit for any dynamic data that we need to pass to the view. The capH]jc session variable holds the language data from the h]jcq]cao table, and qoanH]jc holds the current language that the user has selected.
When a user selects a new language, the cached page is presented while noncached content within the cached content is still being executed.
NCaution Adding caching to our application was complex and time-consuming, mainly because we were also using other Cake features such as locales. If you are going to add caching, try to add it early on in your development. This will make your life easier when your application grows. The Twittertwister Controller The Pseppanpseopan? This is a base controller for the application. Starting from line 12, this action takes the language code that the user has selected and changes the status viewing language on line 14 and the locale on line From line 24 onwards, we redirect the users back to the page where they selected the language change, where they would view the same page they have selected in the new language.
As a result, we needed to do some language code translation. Table of contents 13 chapters Table of contents 13 chapters Cake Fundamentals Pages Blogging Pages E-Commerce Pages Google Maps and the Traveling Salesman Pages Mashing Twitter with the Google Translator Pages Unit Testing and Web Testing Pages A Cake Control Panel Pages Translating Stories Pages Adding Automagic Fields Pages Cake Tags Pages Pages A Message Forum Web Service.
Google Maps and the Traveling Salesman. Mashing Twitter with the Google Translator. Unit Testing and Web Testing. A Cake Control Panel. Translating Stories. Adding Automagic Fields.