Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Save more on your purchases! discount-offer-chevron-icon
Savings automatically calculated. No voucher code required.
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Events
Videos
Audiobooks
Packt Hub
Free Learning
Arrow right icon
timer SALE ENDS IN
0 Days
:
00 Hours
:
00 Minutes
:
00 Seconds

How-To Tutorials

7019 Articles
article-image-backing-and-restoring-typo3-websites
Packt
22 Oct 2009
4 min read
Save for later

Backing Up and Restoring TYPO3 Websites

Packt
22 Oct 2009
4 min read
What Needs Backing Up in TYPO3? We need to back up: The TYPO3 files A copy of the database These two things make up our TYPO3 installation. We need the database as it contains the website's content and records of the website's users. We need the TYPO3 files as they contain the website's settings in the configuration files, copies of the website's design, and copies of data that has been cached by TYPO3. Backing Up the TYPO3 Files Depending on the operating system we are using, there are a number of different ways in which we can back up the files from TYPO3. In this article, we will look into backing up the files on Windows and on Linux. This is because Windows is the most used operating system, and Linux is the most popular hosting environment for websites. Backing Up Our Files on Windows In Windows, we can easily create a compressed file containing all the TYPO3 files (known as a ZIP file), using the Windows Compressed Folder tool, or a program such as WinZip. Provided we've used the default installation path, TYPO3 will be located in the folder C:Program FilesTypo3_4.0.2Apache and the folder that we want to compress is typo3_src. We could just back up the fileadmin, typo3conf, and uploads folders. This way, should we lose our entire website, we can simply restore the whole thing instead of having to restore TYPO3 and then our extra TYPO3 files. Now that we have a backup, we should copy it to a separate location (preferably on an external disk, or on another computer) for safe keeping. Backing Up Our Files on Linux or Linux Hosting We can create a complete backup of our home directory on a Linux hosting environment. This home directory contains all of our files on the hosting account. Alternatively, we can run a simple command to compress a particular folder. If we have a web hosting account that provides us with access to the cPanel hosting control panel, we can use that to generate a backup of our entire website (except for the database—which is done separately via cPanel). To access the backup utilities, we need to log in to cPanel, which is located at www.ourdomain.com/cpanel, and then enter our hosting account's username and password. In cPanel, we have the backup option on the main screen, as shown in the following screenshot: The Backups section has a number of options, but the one that we want is the Download a home directory Backup. This will generate a backup of all the files of our website and allow us to download it. In the previous screenshot, there is a warning message. This is because my web server does not have the option to back up the entire server, just an individualuser's webspace. The backup tool then takes a moment or two of processing, and then prompts us to download the backup file. Command-Line Backup To create a backup via the command line, we need to have SSH access to the server that is hosting our website. SSH is a protocol that allows us to remotely administer another machine using the command line. We can use a program such as Putty to connect to the server. We can download Putty from http://www.chiark.greenend.org.uk/~sgtatham/putty/. Putty only needs to be downloaded, after which it can be run straight away, and does not require to be installed. When we open the program, we are presented with a screen similar to the one shown in the following screenshot. We enter the server's address (i.e. the web address) into the Host Name box and then click on Open. Putty will then try to connect to the server, and will prompt us to enter our username and password, as shown in the following screenshot: Once we are connected, we can type two commands to back up our site. The first is to navigate to the folder that contains our TYPO3 installation. This depends entirely on the server's setup and your username, but is generally /home/the first 8 characters of your web address/public_html (you should contact your web host for more information or if you need help). Once we are in the correct folder, we can use the tar command to compress our TYPO3 folder to a single file named TYPO3. cd /home/michaelp/public_html/tar cvzf file.tar.gz typo3 Now that we have our backup created, we can download it from www.ourwebaddress.com/file.tar.gz (where we will be prompted to save the file). We should then delete this from our server once we have downloaded it.
Read more
  • 0
  • 0
  • 7616

article-image-consuming-adapter-outside-biztalk-server
Packt
22 Oct 2009
3 min read
Save for later

Consuming the Adapter from outside BizTalk Server

Packt
22 Oct 2009
3 min read
In addition to infrastructure-related updates such as the aforementioned platform modernization, Windows Server 2008 Hyper-V virtualization support, and additional options for fail over clustering, BizTalk Server also includes new core functionality. You will find better EDI and AS2 capabilities for B2B situations and a new platform for mobile development of RFID solutions. One of the benefits of the new WCF SQL Server Adapter that I mentioned earlier was the capability to use this adapter outside of a BizTalk Server solution. Let's take a brief look at three options for using this adapter by itself and without BizTalk as a client or service. Called directly via WCF service reference If your service resides on a machine where the WCF SQL Server Adapter (and thus, the sqlBinding) is installed, then you may actually add a reference directly to the adapter endpoint. I have a command-line application, which serves as my service client. If we right-click this application, and have the WCF LOB Adapter SDK installed, then Add Adapter Service Reference appears as an option. Choosing this option opens our now-beloved wizard for browsing adapter metadata. As before, we add the necessary connection string details and browse the BatchMaster table and opt for the Select operation. Unlike the version of this wizard that opens for BizTalk Server projects, notice the Advanced options button at the bottom. This button opens a property window that lets us select a variety of options such as asynchronous messaging support and suppression of an accompanying configuration file. After the wizard is closed, we end up with a new endpoint and binding in our existing configuration file, and a .NET class containing the data and service contracts necessary to consume the service. We should now call this service as if we were calling any typical WCF service. Because the auto-generated namespace for the data type definition is a bit long, I first added an alias to that namespace. Next, I have a routine, which builds up the query message, executes the service, and prints a subset of the response. using DirectReference = schemas.microsoft.com.Sql._2008._05.Types.Tables.dbo; … private static void CallReferencedSqlAdapterService() { Console.WriteLine("Calling referenced adapter service");TableOp_dbo_BatchMasterClient client = new TableOp_dbo_BatchMasterClient("SqlAdapterBinding_TableOp_dbo_BatchMaster"); try{string columnString = "*";string queryString = "WHERE BatchID = 1";DirectReference.BatchMaster[] batchResult =client.Select(columnString, queryString);Console.WriteLine("Batch results ...");Console.WriteLine("Batch ID: " + batchResult[0].BatchID.ToString());Console.WriteLine("Product: " + batchResult[0].ProductName);Console.WriteLine("Manufacturing Stage: " + batchResult[0].ManufStage);client.Close(); Console.ReadLine(); } catch (System.ServiceModel.CommunicationException){client.Abort(); } catch (System.TimeoutException) { client.Abort(); } catch (System.Exception) { client.Abort(); throw; } } Once this quick block of code is executed, I can confirm that my database is accessed and my expected result set returned.
Read more
  • 0
  • 0
  • 1899

article-image-google-earth-google-maps-and-your-photos-tutorial
Packt
22 Oct 2009
38 min read
Save for later

Google Earth, Google Maps and Your Photos: a Tutorial

Packt
22 Oct 2009
38 min read
Introduction A scholar who never travels but stays at home is not worthy to be accounted a scholar. From my youth on I had the ambition to travel, but could not afford to wander over the three hundred counties of Korea, much less the whole world. So, carrying out an ancient practise, I drew a geographical atlas. And while gazing at it for long stretches at a time I feel as though I was carrying out my ambition . . . Morning and evening while bending over my small study table, I meditate on it and play with it and there in one vast panorama are the districts, the prefectures and the four seas, and endless stretches of thousands of miles. WON HAK-SAENG Korean Student Preface to his untitled manuscript atlas of China during the Ming Dynasty, dated 1721. To say that maps are important is an understatement almost as big as the world itself. Maps quite literally connect us to the world in which we all live, and by extension, they link us to one another. The oldest preserved maps date back nearly 4500 years. In addition to connecting us to our past, they chart much of human progress and expose the relationships among people through time. Unfortunately, as a work of humankind, maps share many of the same shortcomings of all human endeavors. They are to some degree inaccurate and they reflect the bias of the map maker. Advancements in technology help to address the former issue, and offer us the opportunity to resist the latter. To the extent that it's possible for all of us to participate in the map making, the bias of a select few becomes less meaningful. Google Earth  and Google Maps  are two applications that allow each of us to assert our own place in the world and contribute our own unique perspective. I can think of no better way to accomplish this than by combining maps and photography. Photos reveal much about who we are, the places we have been, the people with whom we have shared those experiences, and the significant events in our lives. Pinning our photos to a map allows us to see them in their proper geographic context, a valuable way to explore and share them with friends and family. Photos can reveal the true character of a place, and afford others the opportunity to experience these destinations, perhaps faraway and unreachable for some of us, from the perspective of someone who has actually been there. In this tutorial I'll show you how to 'pin' your photos using Google Earth and Google Maps. Both applications are free, and available for Windows, Mac OS X, and Linux. In the case of Google Earth there are requirements associated with installing and running what is a local application. Google Maps has its own requirements: primary among them a compatible web browser (the highly regarded FireFox is recommended). In Google Earth, your photos show up on the map within the application complete with titles, descriptions, and other relevant information. You can choose to share your photos with everyone, only people you know, or even reserve them strictly for yourself. Google Maps offers the flexibility to present maps outside of a traditional application. For example you can embed a map on a webpage pinpointing the location of one particular photo, or mapping a collection of photos to present along with a photo gallery, or even collecting all of your digital photos together on one dynamic map. Over the course of a short couple of articles we'll cover everything you need to take advantage of both applications. I've put together two scripts to help us accomplish that goal. The first is a Perl script that works through your photos and generates a file in the proper format with all of the data necessary to include those photos in Google Earth. The second is a short bit of Javascript that works with the first file and builds a dynamic Google Map of those same photos. Both scripts are available for you to download, after which you are free to use them as is, or modify them to suit your own projects. I've purposefully kept the code as simple as possible to make them accessible to the widest audience, even those of you reading this who may be new to programming or unfamiliar with Perl, Javascript or both. I've taken care to comment the code generously so that everything is plainly obvious. I'm hopeful that you will be surprised at just how simple it is. There a couple of preliminary topics to examine briefly before we go any further. In the preceding paragraph I mentioned that the result of the first of our two scripts is a 'file in the proper format...'. This file, or more to the point the file format, is a very important part of the project. KML  (Keyhole Markup Language) is a fairly simple XML-based format that can be considered the native "language" of Google Earth. That description begs the question, 'What is XML?'. To oversimplify, because even a cursory discussion of XML is outside of the scope of this article, XML  (Extensible Markup Language) is an open data format (in contrast to proprietary formats) which allows us to present information in such way that we communicate not only the data itself, but also descriptive information about the data and the relationships among elements of the data. One of the technical terms that applies is 'metalanguage', which approximately translates to mean a language that makes it possible to describe other languages. If you're unfamiliar with the concept, it may be difficult to grasp at first or it may not seem impressive. However, metalanguages, and specifically XML, are an important innovation (I don't mean to suggest that it's a new concept. In fact XML has roots that are quite old, relative to the brief history of computing). These metalanguages make it possible for us to imbue data with meaning such that software can make use of that data. Let's look at an example taken from the Wikipedia entry for KML. <?xml version="1.0" encoding="UTF-8"?> <kml > <Placemark>  <description>New York City</description>  <name>New York City</name>  <Point>  <coordinates>-74.006393,40.714172,0</coordinates>  </Point> </Placemark> </kml>   Ignore all of the pro forma stuff before and after the <Placemark> tags and you might be able to guess what this bit of data represents. More importantly, a computer can be made to understand what it represents in some sense. Without the tags and structure, "New York City" is just a string, i.e. a sequence of characters. Considering the tags we can see that we're dealing with a place, (a Placemark), and that "New York City" is the name of this place (and in this example also its description). With all of this formal structure, programs can be made to roughly understand the concept of a Placemark, which is a useful thing for a mapping application. Let's think about this for a moment. There are a very large number of recognizable places on the planet, and a provably infinite number of strings. Given a block of text, how could a computer be made to identify a place from, for example the scientific name of a particular flower, or a person's name? It would be extremely difficult. We could try to create a database of every recognizable place and have the program check the database every time it encounters a string. That assumes it's possible to agree on a 'complete list of every place', which is almost certainly untrue. Keep in mind that we could be talking about informal places that are significant only to a small number of people or even a single person, e.g. 'the park where, as a child, I first learned to fly a kite'. It would be a very long list if we were going to include these sorts of places, and incredibly time-consuming to search. Relying on the structure of the fragment above, we can easily write a program that can identify 'New York City' as the name of a place, or for that matter 'The park where I first learned to fly a kite'. In fact, I could write a program that pulls all of the place names from a file like this, along with a description, and a pair of coordinate points for each, and includes them on a map. That's exactly what we're going to do. KML makes it possible. If I haven't made it clear, the structural bits of the file must be standardized. KML supports a limited set of elements (e.g. 'Placemark' is a supported element, as are 'Point' and 'coordinates'), and all of the elements used in a file must adhere to the standard for it to be considered valid. The second point we need to address before we begin is, appropriately enough... where to begin? Lewis Carroll famously tells us to "Begin at the beginning and go on till you come to the end: then stop."  Of course, Mr. Carroll  was writing a book at the time. If "Alice's Adventures in Wonderland" were an article, he might have had different advice. From the beginning to the end there is a lot of ground to cover. We're going to start somewhere further along, and make up the difference with the following assumptions. For the purposes of this discussion, I am going to assume that you have: Perl Access to Phil Harvey's excellent ExifTool , a Perl library and command-line application for reading, writing, and editing metadata in images (among other file types). We will be using this library in our first script A publicly accessible web server. Google requires the use of an API key  by which it can monitor the use of its map services. Google must be able to validate your key, and so your site must be publicly available. Note that this a requirement for Google Maps only Photos, preferably in a photo management application. Essentially, all you need is an app capable of generating both thumbnails and reduced size copies of your original photos . An app that can export a nice gallery for use on the web is even better Coordinate data as part of the EXIF metadata  embedded in your photos. If that sounds unfamiliar to you, then most likely you will have to take some additional steps before you can make use of this tutorial. I'm not aware of any digital cameras that automatically include this information at the time the photo is created. There are devices that can be used in combination with digital cameras, and there are a number of ways that you can 'tag' your photos with geographic data much the same way you would add keywords and other annotations. Let's begin!   Part 1: Google Earth Section 1: Introduction to Part 1 Time to begin the project in earnest. As I've already mentioned we'll spend the first half of this tutorial looking at Google Earth and putting together a Perl script whichthat, given a collection of geotagged photos, will build a set of KML files so that we can browse our photos in Google Earth. These same files will serve as the data source for our Google Maps application later on. Section 2: Some Advice Before We Begin Take your time to make sure you understand each topic before you move on to the next. Think of this as the first step in debugging your completed code. If you go slowly enough that you are to be able to identify aspects of the project that you don't quite understand, then you'll have some idea where to start looking for problems should things not go as expected. Furthermore, going slowly will give you the opportunity to identify those parts that you may want to modify to better fit the script to your own needs. If this is new to you, follow along as faithfully as possible with what I do here the first time through. Feel free to make notes for yourself as you go, but making changes on the first pass may make it difficult for you to catch back on to the narrative and piece together a functional script. After you have a working solution, it will be a simple matter to implement changes one at a time until you have something that works for you. Following this approach it will be easy to identify the silly mistakes that tend to creep in once you start making changes. There is also the issue of trust. This is probably the first time we're meeting each other, in which case you should have some doubt that my code works properly to begin with. If you minimize the number of changes you make, you can confirm that this works for you before blaming yourself or your changes for my mistakes. I will tell you up front that I'm building this project myself as we go. You can be certain at least that it functions as described for me as of the date attached to the article. I realize that this is quite different from being certain that the project will work for you, but at least it's something. The entirety of my project is available for you to download. You are free to use all of it for any legal purpose whatsoever,  including my photos in addition to all of the code, icons, etc. This is so you have some samples to use before you involve your own content. I don't promise that they are the most beautiful images you have ever seen, but they are all decent photos and properly annotated with the necessary metadata, including geographic tags. Section 3: Photos, Metadata and ExifTool To begin, we must have a clear understanding of what the Perl script will require from us. Essentially, we need to provide it with a selection of annotated image files, and information about how to reference those files. A simple folder of files is sufficient, and will be convenient for us, both as the programmer and end user. The script will be capable of negotiating nested folders, and if a directory contains both images and other file types, non-image types will be ignored. Typically, after a day of taking photos I'll have 100 to 200 that I want to keep. I delete the rest immediately after offloading them from the camera. For the files that are left, I preserve the original grouping, keeping all of the files together in a single folder. I place this folder of images in an appropriate location according to a scheme that serves to keep my complete collection of photos neatly organized. These are my digital 'negatives'. I handle all subsequent organization, editing, enhancements, and annotations within my photo management application. I use Apple Inc.'s Aperture; but there are many others that do the job equally well. Annotating your photos is well worth the investment of time and effort, but it's important that you have some strategy in mind so that you don't create meaningless tags that are difficult to use to your advantage. For the purposes of this project the tags we'll need are quite limited, which means that going forward we will be able to continue adding photos to our maps with a reasonable amount of work. The annotations we need are: Caption Latitude Longitude Image Date * Location/Sub-Location City Province/State Country Name Event People ImageWidth * ImageHeight * * Values for these Exif tags are generated by your camera. Note that these are labels used in Aperture, and are not necessarily consistent from one application to the next. Some of them are more likely than others to be used reliably. 'City' for example should be dependable, while the labels 'People', 'Events', and 'Location', among others, are more likely to differ. One explanation for these variations is that the meaning of these fields are more open to interpretation. Location, for example, is likely to be used to narrow down the area where the photo was taken within a particular city, but it is left to the person who is annotating the photo to decide that the field should name a specific street address, an informal place (e.g. 'home' or 'school'), or a larger area, for example a district or neighborhood. Fortunately things aren't so arbitrary as they seem. Each of these fields corresponds to a specific tag name that adheres to one of the common metadata formats (Exif1, IPTC2, XMP3, and there are others). These tag names are consistent as required by the standards. The trick is in determining the labels used in your application that correspond to the well-defined tag names. Our script relies on these metadata tags, so it is important that you know which fields to use in your application. This gives us an excuse to get acquainted with ExifTool4. From the project's website, we have this description of the application: ExifTool is a platform-independent Perl library plus a command-line application for reading, writing, and editing meta information in image, audio, and video files... ExifTool can seem a little intimidating at first. Just keep in mind that we will need to understand just a small part of it for this project, and then be happy that such a useful and flexible tool is freely available for you to use. The brief description above states in part that ExifTool is a Perl library and command line application that we can use to extract metadata from image files. With a single short command, we can have the app print all of the metadata contained in one of our image files. First, make sure ExifTool is installed. You can test for this by typing the name of the application at the command line. $ exiftool If it is installed, then running it with no options should prompt the tool to print its documentation. If this works, there will be more than one screen of text. You can page through it by pressing the spacebar. Press the 'q' key at any time to stop. If the tool is not installed, you will need to add it before continuing. See the appendix at the end of this tutorial for more information. Having confirmed that ExifTool is installed, typing the following command will result in a listing of the metadata for the named image: $ exiftool -f -s -g2 /path/image.jpg Where 'path' is an absolute path to image.jpg or a relative path from the current directory, and 'image.jpg' is the name of one of your tagged image files. We'll have more to say about ExifTool later, but because I believe that no tutorial should ask the reader to blindly enter commands as if they were magic incantations, I'll briefly describe each of the options used in the command above: -f, forces printing of tags even if their values are not found. This gives us a better idea about all of the available tag names, whether or not there are currently defined values for those tags. -s, prints tag names instead of descriptions. This is important for our purposes. We need to know the tag names so that we can request them in our Perl code. Descriptions, which are expanded, more human-readable forms of the same names obscure details we need. For example, compare the tag name 'GPSLatitude' to the description 'GPS Latitude'. We can use the tag name, but not the description to extract the latitude value from our files. -g2, organizes output by category. All location specific information is grouped together, as is all information related to the camera, date and time tags, etc.  You may feel, as I do, that this grouping makes it easier to examine the output. Also, this organization is more likely to reflect the grouping of field names used by your photo management application. If you prefer to save the output to a file, you can add ExifTool's -w option with a file extension. $ exiftool -f -s -g2 -w txt path/image.jpg This command will produce the same result but write the output to the file 'image.txt' in the current directory; again, where 'image.jpg' is the name of the image file. The -w option appends the named extension to the image file's basename, creates a new file with that name, and sets the new file as the destination for output. The tag names that correspond to the list of Aperture fields presented above are: metadata tag name Aperture field label Caption-Abstract Caption GPSLatitude Latitude GPSLongitude Longitude DateTimeOriginal Image Date Sub-location Location/Sub-Location City City Province-State Province/State Country-PrimaryLocationName Country Name FixtureIdentifier Event Contact People ImageWidth Pixel Width ImageHeight Pixel Height     Section 4: Making Photos Available to Google Earth We will use some of the metadata tags from our image files to locate our photos on the map (e.g. GPSLatitude, GPSLongitude), and others to describe the photos. For example, we will include the value of the People tag in the information window that accompanies each marker to identify friends and family who appear in the associated photo. Because we want to display and link to photos on the map, not just indicate their position, we need to include references to the location of our image files on a publicly accessible web server. You have some choice about how to do this, but for the implementation described here we will (1) Display a thumbnail in the info window of each map marker and (2) include a link to the details page for the image in a gallery created in our photo management app. When a visitor clicks on a map marker they will see a thumbnail photo along with other brief descriptive information. Clicking a link included as part of the description will open the viewer's web browser to a page displaying a large size image and additional details. Furthermore, because the page is part of a gallery, viewers can jump to an index page and step forward and back through the complete collection. This is a complementary way to browse our photos. Taking this one step further, we could add a comments section to the gallery pages or replace the gallery altogether, instead choosing to display each photo as a weblog post for example. The structure of the gallery created from my photo app is as follows... / (the root of the gallery directory) index.html large-1.html large-2.html large-3.html ... large-n.html assets/ css/ img/ catalog/ pictures/ picture-1.jpg picture-2.jpg picture-3.jpg ... picture-n.jpg thumbnails/ thumb-1.jpg thumb-2.jpg thumb-3.jpg ... thumb-n.jpg The application creates a root directory containing the complete gallery. Assuming we do not want to make any manual changes to the finished site, publishing is as easy as copying the entire directory to a location within the web server's document root. assets/: Is a subfolder containing files related to the theme itself. We don't need to concern ourselves with this sub-directory. catalog/: Contains a single catalog.plist file which is specific to Aperture and not relevant to this discussion. pictures/: Contains the large size images included on the detail gallery pages. thumbnails/: This subfolder contains the thumbnail images corresponding to the large size images in pictures/. Finally, there are a number of files at the root of the gallery. These include index pages and files named 'large-n.html', where n is a number starting at 1 and increasing sequentially e.g. large-1.html, large-2.html, large-3.html, ... The index files are the index pages of our gallery. The number of index pages generated will be dictated by the number of image files in the gallery, as well as the gallery's layout and design. index.html is always the first gallery page. The large-n.html files are the details pages of our gallery. Each page features an individual photo with links to the previous and next photos in sequence and a link back to the index. You can see the gallery I have created for this tutorial here: http://robreed.net/photos/tutorial_gallery/ If you take the time to look through the gallery, maybe you can appreciate the value of viewing these photos on a map. Web-based photo galleries like this one are nice enough, but the photos are more interesting when viewed in some meaningful context. There are a couple of things to notice about this gallery. Firstly, picture-1.jpg, thumb-1.jpg, and large-1.html all refer to the same image. So if we pick one of the three files we can easily predict the names of the other two. This relationship will be useful when it comes to writing our script. There is another important issue I need to call to your attention because it will not be apparent from looking only at the gallery structure. Aperture has renamed all of my photos in the process of exporting them. The name of the original file from which picture-1.jpg was generated (as well as large-1.html and thumb-1.jpg) is 'IMG_0277.JPG', which is the filename produced by my camera. Because I want to link to these gallery files, not my original photos which will stay safely tucked away on a local drive, I must run the script against the photos in the gallery. I cannot run it against the original image files because the filenames referenced in the output are unrelated to the files in the gallery. If my photo management app provided me the option of preserving the original filenames for the corresponding photos in the gallery, then I could run the script against the original image files or the gallery photos because all of the filenames would be consistent, but this is not the case. I don't have a problem as long as I run the script on the exported photos. However, if I'm running the script against the photos in the web gallery, either the pictures or thumbnail images must contain the same metadata as the original image files. Aperture preserves the metadata in both. Your application may not. A simple, dependable way to confirm that the metadata is present in the gallery files is to run ExifTool first against the original file and then the same photo in the pictures/ and thumbnails/ directories in the gallery. If ExifTool reports identical metadata, then you will have no trouble using one of pictures/ or thumbnails/ as your source directory. If the metadata is not present or not complete in the gallery files, you may need to use the script on your original image files. As has already been explained, this isn't a problem unless the gallery produces filenames that are inconsistent with the original filenames, as Aperture does. In this case you have a problem. You won't be able to run the script on the original image files because of the naming issue or on the gallery photos because they don't contain metadata. Make sure that you understand this point. If you find yourself in this situation, then your best bet is to generate files to use with your maps from your original photos in some other way, bypassing your photo management app's web gallery features altogether in favor of a solution that preserves the filenames, the metadata, or both. There is another option which involves setting up a relationship between the names of the original files and the gallery filenames. This tutorial does not include details about how to set up this association. Finally, keep in mind that though we've looked at the structure of a gallery generated by Aperture, virtually all photo management apps produce galleries with a similar structure. Regardless of the application used, you should find: A group of html files including index and details pages A folder of large size image files A folder of thumbnails Once you have identified the structure used by your application, as we have done here, it will be a simple task to translate these instructions. Section 5: Referencing Files Over the Internet Now we can talk about how to reference these files and gallery pages so that we can create a script to generate a KML file that includes these references. When we identify a file over the internet, it is not enough to use the filename, e.g. 'thumb-1.jpg', or even the absolute and relative path to the file on the local computer. In fact these paths are most likely not valid as far as your web server is concerned. Instead we need to know how to reference our files such that they can be accessed over the global internet, and the web more specifically. In other words, we need to be able to generate a URL (Uniform Resource Locator) which unambiguously describes the location of our files. The formal details of exactly what comprises a URL5; are more complicated than may be obvious at first, but most of us are familiar with the typical URL, like this one: http://www.ietf.org/rfc/rfc1630.txt which describes the location of a document titled "Universal Resource Identifiers in WWW" that just so happens to define the formal details of what comprises a URL. http://www.ietf.org This portion of the address is enough to describe the location of a particular web server over the public internet. In fact it does a little more than just specify the location of a machine. The http:// portion is called the scheme and it identifies a particular protocol (i.e. a set of rules governing communication) and a related application, namely the web. What I just said isn't quite correct; at one time, HTTP was used exclusively by the web, but that's no longer true. Many internet-based applications use the protocol because the popularity of the web ensures that data sent via HTTP isn't blocked or otherwise disrupted. You may not be accustomed to thinking of it as such, but the web itself is a highly-distributed, network-based application. /rfc/ This portion of the address specifies a directory on the server. It is equivalent to an absolute path on your local computer. The leading forward slash is the root of the web server's public document directory. Assuming no trickiness on the part of the server, all content lives under the document root. This tells us that rfc/ is a sub-directory contained within the document root. Though this directory happens to be located immediately under the root, this certainly need not be the case. In fact these paths can get quite long. We have now discussed all of the URL except for: rfc1630.txt which is the name of a specific file. The filename is no different than the filenames on your local computer. Let's manually construct a path to one of the large-n.html pages of the gallery we have created. The address of my server is robreed.net, so I know that the beginning of my URL will be: http://robreed.net I keep all of my galleries together within a photos/ directory, which is contained in the document root. http://robreed.net/photos/ Within photos/, each gallery is given its own folder. The name of the folder I have created for this tutorial is 'tutorial_gallery'. Putting this all together, the following URL brings me to the root of my photo gallery: http://robreed.net/photos/tutorial_gallery/ We've already gone over the directory structure of the gallery, so it should make sense you to that when referring to the 'large-1.html' detail page, the complete URL will be: http://robreed.net/photos/tutorial_gallery/large-1.html the URL of the image that corresponds to that detail page is: http://robreed.net/photos/tutorial_gallery/pictures/picture-1.jpg and the thumbnail can be found at: http://robreed.net/photos/tutorial_gallery/thumbnails/thumb-1.jpg Notice that the address of the gallery is shared among all of these resources. Also, notice that resources of each type (e.g. the large images, thumbnails, and html pages) share a more specific address with files of that same type. If we use the term 'base address' to refer to the shared portions of these URLs, then we can talk about several significant base addresses: The gallery base address: http://robreed.net/photos/tutorial_gallery/ The html pages base address: http://robreed.net/photos/tutorial_gallery/ The images base address: http://robreed.net/photos/tutorial_gallery/pictures/ The thumbnails base address: http://robreed.net/photos/tutorial_gallery/thumbnails/ Note that given the structure of this particular gallery, the html pages base address and the gallery base address are identical. This need not be the case, and may not be for the gallery produced by your application. We can hard-code the base addresses into our script. For each photo, we need only append the associated filename to construct valid URLs to any of these resources. As the script runs, it will have access to the name of the file that it is currently evaluating, and so it will be a simple matter to generate the references we need as we go. At this point we have discussed almost everything we need to put together our script. We have: Created a gallery at our server, which includes our photos with metadata in tow Identified all of the metadata tags we need to extract from our photos with the script and the corresponding field names in our photo management application Determined all of the base addresses we need to generate references to our image files Section 6: KML The last thing we need to understand is the format of the KML files we want to produce. We've already looked at a fragment of KML. The full details can be found on Google's KML documentation pages , which include samples, tutorials and a complete reference for the format. A quick look at the reference is enough to see that the language includes many elements and attributes, the majority of which we will not be including in our files. That statement correctly implies it is not necessary for every KML file to include all elements and attributes. The converse however is not true, which is to say that every element and attribute contained in any KML file must be a part of the standard. A small subset of KML will get us most, if not all, of what you will typically see in Google Earth from other applications. Many of the features we will not be using deal with aspects of the language that are either: Not relevant to this project, e.g. ground overlays (GroundOverlay) which "draw an image overlay draped onto the terrain" Minute details for which the default values are sensible There is no need to feel shortchanged because we are covering only a subset of the language. With the basic structure in place and a solid understanding of how to script the generation of KML, you will be able to extend the project to include any of the other components of the language as you see fit. The structure of our KML file is as follows:  1.    <?xml version="1.0" encoding="UTF-8"?> 2.    <kml > 3.        <Document> 4.            <Folder> 5.                <name>$folder_name</name> 6.                <description>$folder_description</description> 7.                <Placemark> 8.                    <name>$placemark_name</name> 9.                    <Snippet maxLines="1"> 10.                        $placemark_snippet 11.                    </Snippet> 12.                    <description><![CDATA[ 13.                        $placemark_description 14.                    ]]></description> 15.                    <Point> 16.                        <coordinates>$longitude,$latitude </coordinates> 17.                    </Point> 18.                </Placemark> 19.            </Folder> 20.        </Document> 21.    </kml> Line 1: XML header Every valid KML file must start with this line and nothing else is allowed to appear before it. As I've already mentioned, KML is an XML-based language and XML requires this header. Line 2: Namespace declaration More specifically this is the KML namespace declaration, and it is another formality. The value of the >Line 3: <Document> is a container element representing the KML file itself. If we do not explicitly name the document by including a name element then Google Earth will use the name of the KML file as the Document element <name>. The Document container will appear on the Google Earth 'Sidebar' within the 'Places' panel. Optionally we can control whether the container is closed or open by default. (This setting can be toggled in Google Earth using a typical disclosure triangle.) There are many other elements and attributes that can be applied to the Document element. Refer to the KML Reference for the full details. Line 4: <Folder> is another container element. The files we produce will include a single <Folder> containing all of our Placemarks, where each Placemark represents a single image. We could create multiple Folder elements to group our Placemarks according to some significant criteria. Think of the Folder element as being similar to your operating system's concept of a folder. At this point, note the structure of the fragment. The majority of it is contained within the Folder element. Folder, in turn, is an element of Document which is itself within the <kml> container. It should make sense that everything in the file that is considered part of the language must be contained within the kml element. From the KML reference: A Folder is used to arrange other Features hierarchically (Folders, Placemarks, NetworkLinks, or Overlays). A Feature is visible only if it and all its ancestors are visible. Line 5: The name element identifies an object, in this case the Folder object. The text that appears between the name tags can be any plain text that will serve as an appropriate label.   Line 6: <description> is any text that seems to adequately describe the object. The description element supports both plain text and a subset of HTML. We'll consider issues related to using HTML in <description> at the discussion of Placemark, lines 12 - 14. Lines 7 - 17 define a <Placemark> element. Note that Placemark contains a number of elements that also appear in Folder, including <name> (line 8), and <description> (lines 12 - 14). These elements serve the same purpose for Placemark as they do for the Folder element, but of course they refer to a different object. I've said that <description> can include a subset of HTML in addition to plain text. Under XML, some characters have special meaning. You may need to use these characters as part of the HTML included in your descriptions. Angle brackets (<, >) for example surround tag names in HTML, but serve a similar purpose in XML. When they are used strictly as part of the content, we want the XML parser to ignore these characters. We can accomplish this a few different ways: We can use entity references, either numeric character references or character entity references, to indicate that the symbol appears as part of the data and should not be treated as part of the syntax of the language. The character '<', which is required to include an image as part of the description (something we will be doing), (e.g. <img src=... />) can safely be included as the character entity reference '&lt;' or the numeric character reference '&#60'. The character entity references may be easier to remember and recognize on sight but are limited to the small subset of characters for which they have been defined. The numeric references on the other hand can specify any ASCII character. Of the two types, numeric character references should be preferred. There are also Unicode entity references which can specify any character at all. In the simple case of embedding short bits of HTML in KML descriptions, we can avoid the complication of these references altogether by enclosing the entire description in a CDATA6 element, which instructs the XML parser to ignore any special characters that appear until the end of the block set off by the CDATA tags. Notice the string '<![CDATA[' immediately after the opening <description> tag within <Placemark>, and the string ]]> immediately before the closing </description> tag. If we simply place all of our HTML and plain text between those two strings, it will all be ignored by the parser and we are not required to deal with special characters individually. This is how we'll handle the issue. Lines 9 - 11: <Snippet> The KML reference does a good job of clearly describing this element. From the KML reference: In Google Earth, this description is displayed in the Places panel under the name of the feature. If a Snippet is not supplied, the first two lines of the <description> are used. In Google Earth, if a Placemark contains both a description and a Snippet, the <Snippet> appears beneath the Placemark in the Places panel, and the <description> appears in the Placemark's description balloon. This tag does not support HTML markup. <Snippet> has a maxLines attribute, an integer that specifies the maximum number of lines to display. Default for maxLines is 2. Notice that in the block above at line 9, I have included a 'maxLines' attribute with a value of 1. Of course, you are free to substitute your own value for maxLines, or you can omit the attribute entirely to use the default value. The only element we have yet to review is <Point>, and again we need only look to the official reference for a nice description. From the KML reference: A geographic location defined by longitude, latitude, and (optional) altitude. When a Point is contained by a Placemark, the point itself determines the position of the Placemark's name and icon. <Point> in turn contains the element <coordinates> which is required. From the KML reference: A single tuple consisting of floating point values for longitude, latitude, and altitude (in that order). The reference also informs us that altitude is optional, and in fact we will not be generating altitude values. Finally the reference warns: Do not include spaces between the three values that describe a coordinate. This seems like an easy mistake to make. We'll need to be careful to avoid it. There will be a number of <Placemark> elements, one for each of our images. The question is how to handle these elements. The answer is that we'll treat KML as a 'fill in the blanks' style template. All of the structural and syntactic bits will be hard-coded, e.g. the XML header, namespace declaration, all of the element and attribute labels, and even the whitespace, which is not strictly required but will make it much easier for us to inspect the resulting files in a text editor. These components will form our template. The blanks are all of the text and html values of the various elements and attributes. We will use variables as place-holders everywhere we need dynamic data, i.e. values that change from one file to the next or one execution of the script to the next. Take a look at the strings I've used in the block above. $folder_name, $folder_description, $placemark_name, etc. For those of you unfamiliar with Perl, these are all valid variable names chosen to indicate where the variables slot into the structure. These are the same names used in the source file distributed with the tutorial. Section 7: Introduction to the Code At this point, having discussed every aspect of the project, we can succinctly describe how to write the code. We'll do this in 3 stages of increasing granularity. Firstly, we'll finish this tutorial with a natural language walk-through of the execution of the script. Secondly, if you look at the source file included with the project, you will notice immediately that comments dominate the code. Because instruction is as important an objective as the actual operation of the script, I use comments in the source to provide a running narration. For those of you who find this superabundant level of commenting a distraction, I'm distributing a second copy of the source file with much of the comments removed. Finally, there is the code itself. After all, source code is nothing more than a rigorously formal set of instructions that describe how to complete a task. Most programs, including this one, are a matter of transforming input in one form to output in another. In this very ge
Read more
  • 0
  • 0
  • 8682

Packt
22 Oct 2009
7 min read
Save for later

Data Types in Microsoft® Dynamics™ NAV

Packt
22 Oct 2009
7 min read
As you know, design of an application starts with the data. The data design depends on the types of data that your development tool set allows you to use. Since NAV is designed specifically to develop financially oriented business applications, the NAV data types are financially and business oriented, and also have some special features that make it easier to design and develop typical business applications. Furthermore, these same special features can make your applications run faster. In this article, we will cover the data types that you are most likely to use. We will also take an overview of the others. In addition, we will also cover field classes, which are where the special features are enabled. Fields A field is the basic element of data definition in NAV—the "atom" in the structure of a system. The mechanical definition of a field consists of its number, its description (name), and its data type (and, of course, any parameters required for its particular data type). From a logical point of view, a field is also defined by its Properties and the C/AL code contained in its Triggers. Field Properties The specific properties that can be defined for a field partially depend on the data type. First we will review the universal field properties. Then we will review the properties that are data-type dependent plus some other field properties. You can check out the remaining properties by using Help within the Table Designer.Fields You can access the properties of a field while viewing the table in Design mode, by highlighting the field line whose properties you wish to examine and clicking on the Properties icon or pressing Shift + F4. All the property screenshots in this section are obtained in this way for fields within the standard Customer table. As we review various field properties, you will learn more if, using the Object Designer, you follow along in your NAV system. Poke around and explore different properties and the values they can have. Use the Field Help function liberally and read the help for various properties. The property value enclosed in < > (less than sign, greater than sign), is the default value for that property. When you set a property to any other value, < and > should not be present unless they are supposed to be the part of the property value (e.g. part of a Text string value).All data types have the following properties: Property Property Description Field No. Identifier for the field within the table object Name Label by which code references the field. The name can be changed at any time and NAV will automatically ripple that change throughout the code Caption and Caption ML Work similarly as named table properties Description Used for internal documentation only Data Type Identifies what kind of data format applies to this field (e.g. Integer, Date, Code, Text, etc.) Enabled Determines if the field is activated for data handling or not. This property defaults to yes and is rarely changed   The following screenshot shows the BLOB properties for the Picture Field in the Customer table: This set of properties, for fields of the BLOB data type, is the simplest set of field properties. After the properties that are shared by all data types, appear the BLOB-specific properties—SubType and Owner:    SubType: This defines the type of data stored in the BLOB. The three  sub-type choices are Bitmap (for bitmap graphics), Memo (for text data), and  User-Defined (for anything else). User-Defined is the default value.    Owner: The usage is not defined.   The available properties of Code and Text fields are quite similar to one another. The following are some common properties between the two as shown in the screenshot overleaf:   DataLength: This specifies how many characters long the data field is. InitValue: This is the value that the system should supply as a default when  the system actively initializes the field. AltSearchField: This allows definition of an alternative field in the same  table to be searched for a match if no match is found on a lookup on this datastyle="width: 761px; height: 446px;"  item. For example, you might want to allow customers to be looked up eitherstyle="width: 761px; height: 446px;"  by their Customer No. or by their Phone No. In that case, in the No. field  properties you would supply the Phone No. field name in the AltSearchField  field. Then, when a user searches in the No. field, NAV will first look for  a match in the No. field and, if it is not found there, it will then search  the Phone No. field for a match. Use of this property can save you a lot of  coding, but make sure both fields have high placement in a key so the lookup  will be speedy. Editable: This is set to No when you don't want to allow a field to ever be  edited for example, if this is a computed or assigned value field that the user  should not change. NotBlank, Numeric, CharAllowed, DateFormula, and ValuesAllowed: All  these support placing constraints on the specific data that can be entered into  this field. TableRelation and ValidateTableRelation: These are used to  control referencing and validation of entries against another table.  (TestTableRelation is an infrequently used property, which controls whether  or not this relationship should be tested during a database validation test.) Let us take a look at the properties of couple more Data types, Integer and Decimal. You may find it useful to explore them on your own as well. Specific properties related to the basic numeric content of these data types are as follows and are also shown in the following screenshot: DecimalPlaces: This sets the number of decimal places in a Decimal  data item. BlankNumbers, BlankZero, and SignDisplacement: All these can be used to  influence the formatting and display of the data in the field. MinValue and MaxValue: These can constrain the range of data values allowed. AutoIncrement: This allows setting up of one field in a table to automatically  increment for each record entered. This is almost always used to support  automatic updating of a field used as the last field in a primary key, enabling  creation of a unique key. The field properties for an Integer field with a FieldClass property of FlowField are similar to those of a field with a FieldClass property of Normal. The differencesstyle="width: 761px; height: 446px;"relate to the fact that the field does not actually contain data but holds the formula by which the displayed value is calculated, as shown in the following screenshot overleaf. Note the presence of the CalcFormula property and the absence of the AltSearchField, AutoIncrement, and TestTableRelation properties. Similar differences exist for FlowFields of other data types. The properties for an Option data type, whose properties are shown in the following screenshot, are essentially like those of the other numeric data types, but with a datatype-specific set of properties as described below: OptionString: This spells out the text interpretations for the stored integer  values contained in Option data type fields. OptionCaption and OptionCaptionML: These serve the same captioning  and multi-language purposes as other caption properties. The properties defined for FlowFilter fields, such as Date Filter in the following screenshot overleaf, are similar to those of Normal data fields. Take a look at the Date Filter field (a Date FlowFilter field) and the Global Dimension 1 Filter field (a Code FlowFilter field) in the Customer table. The Date Filter field property looks similar to a Normal FieldClass field.
Read more
  • 0
  • 0
  • 4613

article-image-pop-image-widget-using-javascript-php-and-css
Packt
22 Oct 2009
7 min read
Save for later

Pop-up Image Widget using JavaScript, PHP and CSS

Packt
22 Oct 2009
7 min read
If you’re a regular blog reader then it’s likely that you’ve encountered the Recent Visitors widget form (http://mybloglog.com). This widget displays the profile like name, picture and sites authored by members of Mybloglog who have recently visited your blog. In the Mybloglog widget, when you move the mouse cursor to the member’s picture, you’ll see a popup displaying a brief description of that member. A glance at MyBlogLog widget The above image is of a MyBlogLog widget. As you can see in the right part of the widget, there is a list of the recent visitors to the blog from members of MyBlogLog. You may also have noticed that in the left part of the widget is a popup showing the details and an image of the visitor. This popup is displayed when the mouse is moved over the image on the widget. Now, let’s look at the code which we got from MyBlogLog to display the above widget. <script src="http://pub.mybloglog.com/comm3.php?mblID=2007121300465126&r= widget&is=small&o=l&ro=5&cs=black&ww=220&wc=multiple"></script> In the above script element, the language and type attributes are not specified. Although they are optional attributes in HTML - you must specify a value in the type attribute to make the above syntax valid in an XHTML web page. If you closely looked at the src attribute of the script element, you can see that the source page of the script is a .php file. You can use the JavaScript code with any file extension like .php , .asp, and so on , but whenever you use such a file in src attribute please note that the final output code of the file (after being parsed by server) should be a valid JavaScript code. Creating pop-up image widget This pop-up image widget is somewhat similar to MyBlogLog widget but it is a simplified version of that widget. This is a very simple widget with uses JavaScript, PHP and CSS. Here you’ll see four images in the widget and a pop-up image (corresponding to the chosen image) will be displayed when you move the mouse over it. After getting the core concept, you can extend the functionality to make this look fancier. Writing Code for Pop-up Image Widget As I’ve already discussed, this widget is going to contain PHP code, JavaScript and a little bit of CSS as well. For this, you need to write the code in a PHP file with the .php extension. First of all, declare the variables for storing the current mouse position and string variables for storing the string of the widget. var widget_posx=0;var widget_posy=0;var widget_html_css=''; The widget_posx variable is to hold the x co-ordinate values of the mouse position on the screen, whereas, the widget_posy variable will store the y co-ordinate. The widget_html_css variable stores the HTML and CSS elements which will be used later in the code. The (0,0) co-ordinate of the output devices like monitor is located at the top left position. So the mouse position 10,10 will be somewhere near the top left corner of monitor. After declaring the variables, let’s define an event handler to track the mouse position on the web page. document.onmousemove=captureMouse; As you can see above, we’ve called a function captureMouse() When the mouse is moved anywhere on the document (web page), the event handler which is the function captureMouse() is called on the onmousemove event. The Document object represents the entire HTML document and can be used to access and capture the events of all elements on a page. Each time a user moves the mouse one pixel, a mousemove event occurs. It engages system resources to process all mousemove events, hence, use this event carefully! Now, let’s look at the code of the captureMouse() function. function captureMouse(event){ if (!event){var event = window.event;}if (event.pageX || event.pageY) { widget_posx = event.pageX; widget_posy = event.pageY; } else if (event.clientX || event.clientY) { widget_posx = event.clientX; widget_posy = event.clientY; } } As you can see in the above function, the event variable is passed as a function parameter. This event variable is the JavaScript’s Event object. The Event object keeps track of various events that occur on the page, such as the user moving the mouse or clicking on the link, and allows you to react to them by writing code which is relevant to the event. if (!event){var event = window.event;} In the above code, the first line of the event handler ensures that if the browser doesn’t pass the event information to the above function, then we would obtain it from any explicit event registration of the window object. We can track different activity in the document by the event object with the help of its various defined properties. For example, if eventObj is the event object and we’ve to track whether the ctrl key is pressed (or not) - we can use the following code in JavaScript: eventObj.ctrlKey If we’ve assigned the x, y-position of mouse in the page using the pageX and pageY properties, we can also get the same mouse position of the mouse cursor using clientX and clientY property. Most browsers provide both pageX/pageY and clientX/clientY. Internet Explorer is the only current browser that provides clientX/clientY, but not pageX/pageY. To provide cross-browser support, we’ve used both pageX/pageY and clientX/clientY to get the mouse co-ordinates in the document, and assigned them to the widget_posx and widget_posy variables accordingly. Now, let’s look at widget_html_css variable, where we’re going to store the string which is going to be displayed in the widget. widget_html_css+='<style type="text/css">';widget_html_css+='.widgetImageCss';widget_html_css+='{ margin:2px;border:1px solid #CCCCCC;cursor:pointer}';widget_html_css+='</style>'; As you can see in the string of the above variable, we’ve added the style for the HTML element with the class name widgetImageCss within the style element. When applied, this class in the HTML adds a 2 pixel margins ‘brown color border’ to the element. Furthermore, the mouse cursor will be converted into pointer (a hand) which is defined with the cursor attribute in CSS. widget_html_css+='<div id="widget_popup"style="position:absolute;z-index:10; display:none">&nbsp;</div>'; Using the above code, we’re adding a division element with id widget_popup to the DOM. We’ve also added style to this element using inline styling. The position attribute of this element is set to absolute so that this element can move freely without disturbing the layout of the document. The z-index property is used for stacking the order of the element and in the above element it is set 10 so that this element will be displayed above all the other elements of the document. Finally, the display property is set to none for hiding the element at first. Afterwards, this element will be displayed with the pop-up image using JavaScript in the document. Elements can have negative stack orders i.e. you can set the z-index to -1 for an element. This will display it underneath the other elements on the page. Z-index only works on elements that have been positioned using CSS (such as position:absolute). Now, the PHP part of the codes comes in. We’ve used PHP to add the images to the widget_html_css string variables of JavaScript. We’ve used PHP in this part rather than using JavaScript for making this application flexible. JavaScript is a client side scripting language and can’t access the database or do any kind of server activity. Using PHP, you can extract and display the images from the database which might be the integral part of your desired widget.
Read more
  • 0
  • 0
  • 8547

Packt
22 Oct 2009
8 min read
Save for later

Working with Rails – ActiveRecord, Migrations, Models, Scaffolding, and Database Completion

Packt
22 Oct 2009
8 min read
ActiveRecord, Migrations, and Models ActiveRecord is the ORM layer (see the section Connecting Rails to a Database in the previous article) used in Rails. It is used by controllers as a proxy to the database tables. What's really great about this is that it protects you against having to code SQL. Writing SQL is one of the least desirable aspects of developing with other web-centric languages (like PHP): having to manually build SQL statements, remembering to correctly escape quotes, and creating labyrinthine join statements to pull data from multiple tables. ActiveRecord does away with all of that (most of the time), instead presenting database tables through classes (a class which wraps around a database table is called a model) and instances of those classes (model instances). The best way to illustrate the beauty of ActiveRecord is to start using it. Model == Table The base concept in ActiveRecord is the model. Each model class is stored in the app/models directory inside your application, in its own file. So, if you have a model called Person, the file holding that model is in app/models/person.rb, and the class for that model, defined in that file, is called Person. Each model will usually correspond to a table in the database. The name of the database table is, by convention, the pluralized (in the English language), lower-case form of the model's class name. In the case of our Intranet application, the models are organized as follows: Table Model class File containing class definition (in app/models) people Person person.rb companies Company company.rb addresses Address address.rb We haven't built any of these yet, but we will shortly. Which Comes First: The Model or The Table? To get going with our application, we need to generate the tables to store data into, as shown in the previous section. It used to be at this point where we would reach for a MySQL client, and create the database tables using a SQL script. (This is typically how you would code a database for a PHP application.) However, things have moved on in the Rails world. The Rails developers came up with a pretty good (not perfect, but pretty good) mechanism for generating databases without the need for SQL: it's called migrations, and is a part of ActiveRecord. Migrations enable a developer to generate a database structure using a series of Ruby script files (each of which is an individual migration) to define database operations. The "operations" part of that last sentence is important: migrations are not just for creating tables, but also for dropping tables, altering them, and even adding data to them. It is this multi-faceted aspect of migrations which makes them useful, as they can effectively be used to version a database (in much the same way as Subversion can be used to version code). A team of developers can use migrations to keep their databases in sync: when a change to the database is made by one of the team and coded into a migration, the other developers can apply the same migration to their database, so they are all working with a consistent structure. When you run a migration, the Ruby script is converted into the SQL code appropriate to your database server and executed over the database connection. However, migrations don't work with every database adapter in Rails: check the Database Support section of the ActiveRecord::Migration documentation to find out whether your adapter is supported. At the time of writing, MySQL, PostgreSQL, SQLite, SQL Server, Sybase, and Oracle were all supported by migrations. Another way to check whether your database supports migrations is to run the following command in the console (the output shown below is the result of running this using the MySQL adapter): >> ActiveRecord::Base.connection.supports_migrations? => true We're going to use migrations to develop our database, so we'll be building the model first. The actual database table will be generated from a migration attached to the model. Building a Model with Migrations In this section, we're going to develop a series of migrations to recreate the database structure outlined in Chapter 2 of the book Ruby on Rails Enterprise Application Development: Plan, Program, Extend. First, we'll work on a model and migration for the people table. Rails has a generate script for generating a model and its migration. (This script is in the script directory, along with the other Rails built-in scripts.) The script builds the model, a base migration for the table, plus scripts for testing the model. Run it like this: $ ruby script/generate model Person exists app/models/  exists test/unit/    exists test/fixtures/    create app/models/person.rb    create test/unit/person_test.rb    create test/fixtures/people.yml    exists db/migrate    create db/migrate/001_create_people.rb Note that we passed the singular, uppercase version of the table name ("people" becomes "Person") to the generate script. This generates a Person model in the file app/models/person.rb; and a corresponding migration for a people table (db/ migrate/001_create_people.rb). As you can see, the script enforces the naming conventions, which connects the table to the model. The migration name is important, as it contains sequencing information: the "001" part of the name indicates that running this migration will bring the database schema up to version 1; subsequent migrations will be numbered "002...", "003..." etc., each specifying the actions required to bring the database schema up to that version from the previous one. The next step is to edit the migration so that it will create the people table structure. At this point, we can return to Eclipse to do our editing. (Remember that you need to refresh the file list in Eclipse to see the files you just generated). Once, you have started Eclipse, open the file db/migrate/001_create_people.rb. It should look like this:     class CreatePeople < ActiveRecord::Migration        def self.up            create_table :people do |t|                # t.column :name, :string            end        end        def self.down            drop_table :people        end    end This is a migration class with two class methods, self.up and self.down. The self.up method is applied when migrating up one database version number: in this case, from version 0 to version 1. The self.down method is applied when moving down a version number (from version 1 to 0). You can leave self.down as it is, as it simply drops the database table. This migration's self.up method is going to add our new table using the create_table method, so this is the method we're going to edit in the next section. Ruby syntaxExplaining the full Ruby syntax is outside the scope of this book. For our purposes, it suffices to understand the most unusual parts. For example, in the create_table method call shown above:,     create_table :people do |t|        t.column :title, :string        ...    end The first unusual part of this is the block construct, a powerful technique for creating nameless functions. In the example code above, the block is initialized by the do keyword; this is followed by a list of parameters to the block (in this case, just t); and closed by the end keyword. The statements in-between the do and end keywords are run within the context of the block. Blocks are similar to lambda functions in Lisp or Python, providing a mechanism for passing a function as an argument to another function. In the case of the example, the method call create_table:people is passed to a block, which accepts a single argument, t; t has methods called on it within the body of the block. When create_table is called, the resulting table object is "yielded" to the block; effectively, the object is passed into the block as the argument t, and has its column method called multiple times. One other oddity is the symbol: that's what the words prefixed with a colon are. A symbol is the name of a variable. However, in much of Rails, it is used in contexts where it is functionally equivalent to a string, to make the code look more elegant. In fact, in migrations, strings can be used interchangeably with symbols.  
Read more
  • 0
  • 0
  • 5395
Unlock access to the largest independent learning library in Tech for FREE!
Get unlimited access to 7500+ expert-authored eBooks and video courses covering every tech area you can think of.
Renews at ₹800/month. Cancel anytime
article-image-php-data-objects-error-handling
Packt
22 Oct 2009
11 min read
Save for later

PHP Data Objects: Error Handling

Packt
22 Oct 2009
11 min read
In this article, we will extend our application so that we can edit existing records as well as add new records. As we will deal with user input supplied via web forms, we have to take care of its validation. Also, we may add error handling so that we can react to non-standard situations and present the user with a friendly message. Before we proceed, let's briefly examine the sources of errors mentioned above and see what error handling strategy should be applied in each case. Our error handling strategy will use exceptions, so you should be familiar with them. If you are not, you can refer to Appendix A, which will introduce you to the new object-oriented features of PHP5. We have consciously chosen to use exceptions, even though PDO can be instructed not to use them, because there is one situation where they cannot be avoided. The PDO constructors always throw an exception when the database object cannot be created, so we may as well use exceptions as our main error‑trapping method throughout the code. Sources of Errors To create an error handling strategy, we should first analyze where errors can happen. Errors can happen on every call to the database, and although this is rather unlikely, we will look at this scenario. But before doing so, let's check each of the possible error sources and define a strategy for dealing with them. This can happen on a really busy server, which cannot handle any more incoming connections. For example, there may be a lengthy update running in the background. The outcome is that we are unable to get any data from the database, so we should do the following. If the PDO constructor fails, we present a page displaying a message, which says that the user's request could not be fulfilled at this time and that they should try again later. Of course, we should also log this error because it may require immediate attention. (A good idea would be emailing the database administrator about the error.) The problem with this error is that, while it usually manifests itself before a connection is established with the database (in a call to PDO constructor), there is a small risk that it can happen after the connection has been established (on a call to a method of the PDO or PDO Statement object when the database server is being shutdown). In this case, our reaction will be the same—present the user with an error message asking them to try again later. Improper Configuration of the Application This error can only occur when we move the application across servers where database access details differ; this may be when we are uploading from a development server to production server, where database setups differ. This is not an error that can happen during normal execution of the application, but care should be taken while uploading as this may interrupt the site's operation. If this error occurs, we can display another error message like: "This site is under maintenance". In this scenario, the site maintainer should react immediately, as without correcting, the connection string the application cannot normally operate. Improper Validation of User Input This is an error which is closely related to SQL injection vulnerability. Every developer of database-driven applications must undertake proper measures to validate and filter all user inputs. This error may lead to two major consequences: Either the query will fail due to malformed SQL (so that nothing particularly bad happens), or an SQL injection may occur and application security may be compromised. While their consequences differ, both these problems can be prevented in the same way. Let's consider the following scenario. We accept some numeric value from a form and insert it into the database. To keep our example simple, assume that we want to update a book's year of publication. To achieve this, we can create a form that has two fields: A hidden field containing the book's ID, and a text field to enter the year. We will skip implementation details here, and see how using a poorly designed script to process this form could lead to errors and put the whole system at risk. The form processing script will examine two request variables:$_REQUEST['book'], which holds the book's ID and $_REQUEST['year'], which holds the year of publication. If there is no validation of these values, the final code will look similar to this: $book = $_REQUEST['book'];$year = $_REQUEST['year'];$sql = "UPDATE books SET year=$year WHERE id=$book";$conn->query($sql); Let's see what happens if the user leaves the book field empty. The final SQL would then look like: UPDATE books SET year= WHERE id=1; This SQL is malformed and will lead to a syntax error. Therefore, we should ensure that both variables are holding numeric values. If they don't, we should redisplay the form with an error message. Now, let's see how an attacker might exploit this to delete the contents of the entire table. To achieve this, they could just enter the following into the year field: 2007; DELETE FROM books; This turns a single query into three queries: UPDATE books SET year=2007; DELETE FROM books; WHERE book=1; Of course, the third query is malformed, but the first and second will execute, and the database server will report an error. To counter this problem, we could use simple validation to ensure that the year field contains four digits. However, if we have text fields, which can contain arbitrary characters, the field's values must be escaped prior to creating the SQL. Inserting a Record with a Duplicate Primary Key or Unique Index Value This problem may happen when the application is inserting a record with duplicate values for the primary key or a unique index. For example, in our database of authors and books, we might want to prevent the user from entering the same book twice by mistake. To do this, we can create a unique index of the ISBN column of the books table. As every book has a unique ISBN, any attempt to insert the same ISBN will generate an error. We can trap this error and react accordingly, by displaying an error message asking the user to correct the ISBN or cancel its addition. Syntax Errors in SQL Statements This error may occur if we haven't properly tested the application. A good application must not contain these errors, and it is the responsibility of the development team to test every possible situation and check that every SQL statement performs without syntax errors. If this type of an error occurs, then we trap it with exceptions and display a fatal error message. The developers must correct the situation at once. Now that we have learned a bit about possible sources of errors, let's examine how PDO handles errors. Types of Error Handling in PDO By default, PDO uses the silent error handling mode. This means that any error that arises when calling methods of the PDO or PDOStatement classes go unreported. With this mode, one would have to call PDO::errorInfo(), PDO::errorCode(), PDOStatement::errorInfo(), or PDOStatement::errorCode(), every time an error occurred to see if it really did occur. Note that this mode is similar to traditional database access—usually, the code calls mysql_errno(),and mysql_error() (or equivalent functions for other database systems) after calling functions that could cause an error, after connecting to a database and after issuing a query. Another mode is the warning mode. Here, PDO will act identical to the traditional database access. Any error that happens during communication with the database would raise an E_WARNING error. Depending on the configuration, an error message could be displayed or logged into a file. Finally, PDO introduces a modern way of handling database connection errors—by using exceptions. Every failed call to any of the PDO or PDOStatement methods will throw an exception. As we have previously noted, PDO uses the silent mode, by default. To switch to a desired error handling mode, we have to specify it by calling PDO::setAttribute() method. Each of the error handling modes is specified by the following constants, which are defined in the PDO class: PDO::ERRMODE_SILENT – the silent strategy. PDO::ERRMODE_WARNING – the warning strategy. PDO::ERRMODE_EXCEPTION – use exceptions. To set the desired error handling mode, we have to set the PDO::ATTR_ERRMODE attribute in the following way: $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); To see how PDO throws an exception, edit the common.inc.php file by adding the above statement after the line #46. If you want to test what will happen when PDO throws an exception, change the connection string to specify a nonexistent database. Now point your browser to the books listing page. You should see an output similar to: This is PHP's default reaction to uncaught exceptions—they are regarded as fatal errors and program execution stops. The error message reveals the class of the exception, PDOException, the error description, and some debug information, including name and line number of the statement that threw the exception. Note that if you want to test SQLite, specifying a non-existent database may not work as the database will get created if it does not exist already. To see that it does work for SQLite, change the $connStr variable on line 10 so that there is an illegal character in the database name: $connStr = 'sqlite:/path/to/pdo*.db'; Refresh your browser and you should see something like this: As you can see, a message similar to the previous example is displayed, specifying the cause and the location of the error in the source code. Defining an Error Handling Function If we know that a certain statement or block of code can throw an exception, we should wrap that code within the try…catch block to prevent the default error message being displayed and present a user-friendly error page. But before we proceed, let's create a function that will render an error message and exit the application. As we will be calling it from different script files, the best place for this function is, of course, the common.inc.php file. Our function, called showError(), will do the following: Render a heading saying "Error". Render the error message. We will escape the text with the htmlspecialchars() function and process it with the nl2br() function so that we can display multi-line messages. (This function will convert all line break characters to tags.) Call the showFooter() function to close the opening and tags. The function will assume that the application has already called the showHeader() function. (Otherwise, we will end up with broken HTML.) We will also have to modify the block that creates the connection object in common.inc.php to catch the possible exception. With all these changes, the new version of common.inc.php will look like this: <?php/*** This is a common include file* PDO Library Management example application* @author Dennis Popel*/// DB connection string and username/password$connStr = 'mysql:host=localhost;dbname=pdo';$user = 'root';$pass = 'root';/*** This function will render the header on every page,* including the opening html tag,* the head section and the opening body tag.* It should be called before any output of the/*** This function will 'close' the body and html* tags opened by the showHeader() function*/function showFooter(){?></body></html><?php}/*** This function will display an error message, call the* showFooter() function and terminate the application* @param string $message the error message*/function showError($message){echo "<h2>Error</h2>";echo nl2br(htmlspecialchars($message));showFooter();exit();}// Create the connection objecttry{$conn = new PDO($connStr, $user, $pass);$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);}catch(PDOException $e){showHeader('Error');showError("Sorry, an error has occurred. Please try your requestlatern" . $e->getMessage());} As you can see, the newly created function is pretty straightforward. The more interesting part is the try…catch block that we use to trap the exception. Now with these modifications we can test how a real exception will get processed. To do that, make sure your connection string is wrong (so that it specifies wrong databasename for MySQL or contains invalid file name for SQLite). Point your browser to books.php and you should see the following window:
Read more
  • 0
  • 0
  • 6809

article-image-visual-sourcesafecreating-service-oriented-application
Packt
22 Oct 2009
17 min read
Save for later

Visual SourceSafe:Creating a Service-Oriented Application

Packt
22 Oct 2009
17 min read
I will build a prototype for a hotel reservation system outlining the way Software Configuration Management makes the job easier. Don't worry if you are not fully familiar with the technologies used. The purpose of this application is purely for reference, so you can sit back and relax. At this point I will use my time machine and get a screenshot for the final application so you can see how it will look like. Or, I can insert the screenshot after it finished. I think the first way seems more reasonable. This is what the public reservation site looks like: If you like it, you can download the application from the book's website: http://orbitalhotel.alexandruserban.com. Now let's get back to our time and start the development lifecycle on the Orbital Hotel product. The first phase is the specifications phase. Specifications—Project Architecture In order to build a software system, we need a list of requirements. What is the purpose of the system? What are the actions performed by the system and against the system? Who will use the system and how? The answers to these questions will let us identify the main parts of the system and the way these parts work together. System Requirements Let's take a look at the Orbital Hotel's reservation system's requirements. The purpose of the reservation system is to allow guests to make room reservations. There are several room types each having a number, occupancy, price, availability, description, and image. The reservations can be made by using the hotel's internet website, through the websites of travel agencies (third parties), or by making phone calls to the hotel's client service. Reservations can be also made by internal client service staff who receive phone calls from guests. When guests use the hotel's website, they will create a user with a username and password and input their personal details such as first name, last name, address, city, zip code, state, country, phone, email address, and card number. Then they will choose a room and complete the reservation details such as arrival date, the number of nights they will be staying and the number of adults, teenagers, children, and pets. They will also be able to cancel their reservation. When making a reservation over the phone, a guest will provide the same personal information and reservation details to the hotel's client-service staff. The staff will create a reservation for the guest using an internal application. The staff members will also authenticate using a username and password. Travel agencies and other third parties must also be able to make hotel reservations. Taking a big picture about the type of system we are going to build, what we need is an application design that will be as flexible as possible. It should provide us with a variety of options like reservations through phone calls, personal or third-party websites, smart devices like PDAs or cell phones, and so on. This is where we gather the specifications and plan the system architecture. In this phase we have to consider as many aspects as we can, based on our requirements and specifications. So, let's see what the main existing application architectures are, and see what application architecture fits our requirements. Application Architectures The computer and computer programming history is a very short one in comparison with that of other industries. Although it is short, it has evolved and continues to evolve very rapidly, changing the way we live. Taking into account the architectures used at the beginning of computer programming, we can see an evolution from the single, powerful, fault-tolerant, expensive super mainframe computer applications, towards multiple, distributed, less expensive smaller machine applications, the personal computers. During this evolution, three main application architectures can be identified: Compact application architecture Component application architecture Service-Oriented Architecture (SOA) We are going to take a brief look at these application architectures and outline their characteristics. Compact Application Architecture During application development for the single mainframe, there was no clear separation between application layers and no reusable components were used. All the data access, business logic, and user interface-specific code were contained in a single executable program. This traditional compact architecture was used because the mainframe computers had specific proprietary programming languages and formats for accessing and manipulating the data. All the data access-specific procedures as well as the business logic and business rules code are written in this programming language. At the surface, a user interface is presented to the user for data visualisation and manipulation. This application architecture works for applications that do not need data input from multiple sources and can be easily developed by a single programmer. However, this approach has several major disadvantages when it comes to building large-scale systems: Application components cannot be reused in other applications because they are tightly coupled and dependent on one another. Tight coupling means that in order for a piece of code to use another piece of code, it must have intimate knowledge about its implementation details. Being tightly coupled, a change to one component can affect the functionality of another, making debugging and maintenance a difficult task. The application is actually a black box; no one, except the main developer, knows what it is in there. Applying security is another problem because the user interface cannot be separated from the business logic components using security-specific mechanisms like authentication and authorization. Application integration is affected because the code is platform dependent. Integration between two such applications requires special and specific coding and can be difficult to maintain. Scalability issues are considered when the system grows and need to be scaled across several machines. Using this application architecture, scalability is not possible as you can't separate different application parts across different physical boundaries because of the tight coupling. To address the issues with the compact application architecture, the component-based application architecture was developed. Component Application Architecture In the component application architecture, the application's functionality is defined using components. A component is like a black box, a software unit that encapsulates data and code and provides at the surface a set of well-defined interfaces used by other components. Since a component only needs to support a well-defined set of interfaces, it can change the inner implementation details without affecting other components that use its external interfaces. Components that export the same interfaces can be interchanged, allowing them to be reused and tight coupling to be eliminated. This makes them loosely coupled because they don't need to know internal implementation details of one another. This separation of application functionality using components allows the distribution of development tasks across several developers and makes the overall application more maintainable and scaleable. In the Windows environment, the most used component application architecture is the Component Object Model (COM). Typically, components are grouped into logical layers. For example, an application uses the data access layer to access the different data sources, the business logic layer to process the data according to the business rules, and the presentation layer also known as the user interface layer to present the data to end users. Using well-defined application layers allows for a modular design, component decoupling, and therefore the possibility for component reuse. Data Access Layer This architecture forms a chain of layers that communicate with one another. The base is the data access layer, which is responsible for querying, retrieving, and updating the data from and to different data sources while providing a uniform data view to the layers above. Business Layer Above the data access layer is the business logic layer. The business logic layer uses the uniform data provided by the data access layer and processes it according to the business rules it contains. The business logic layer doesn't need to know from what source and how the data was obtained. Its purpose is only data manipulation and processing. Presentation Layer At the top of the chain is the presentation layer or the user interface layer. Its purpose is to present the data processed by the business logic layer to end users and to receive input and commands from these end users. The presentation layer will propagate these commands down the chain to the business layer for processing. Characteristics The component application architecture solves many software problems and it has been used extensively in the past. But because software evolves continuously, new requirements introduce new challenges. Let's suppose we have several applications on different platforms, each incorporating its presentation layer, business logic layer, and data access layer. We want to integrate them into a bigger distributed system, a system that spans across several heterogeneous environments. At some point, one application will need to access the data existing in another application. While components can work well in a homogenous environment on the same platform, for example COM in the Windows environment, problems appear in components working across several platforms. For example, it is very difficult for a COM component to be used from a Java application or vice-versa, mainly because they don't speak the same language. Integration between two or more applications running on different platforms would require a middle component-dependent intercommunication layer that is expensive, difficult to build, and reintroduces tight coupling between systems, which is what we tried to avoid in the first place. Avoiding building this intercommunication layer would require that the data exchange between these applications be done by a person who will read the necessary data from the source application and write it into the target application. We need to integrate these systems, and maintain the loose coupling between them. What we need to do, is make these components understand each other, making them to speak the same language. This is where the concept of services and Service-Oriented Architecture (SOA) comes into play. Service-Oriented Architecture SOA describes an information technology architecture that enables distributed computing environments with many different types of computing platforms and applications. To enable distributed computing environments, SOA defines the concept of services. A service is a well-defined, self-contained unit of functionality, independent of the state of other services. Let's see how services can be used to create distributed applications, integrate component-based applications, and make them communicate with each other. We keep our data access layer and business logic layer as they are, but we completely decouple the presentation layer so we can change it later without affecting the other layers. In order to expose the functionality of the business logic layer, we wrap it in a service interface. The service interface wraps the business logic layer components offering a point of access for any process that needs to access the business logic, whose functionality has now become a service. Service-oriented architecture is basically a collection of services that communicate with each other. The communication can involve either simple data passing or it can involve two or more services coordinating some activity. Whatever the required functionality may be, we have now separated the functionality of applications into specific units, the services that we use to construct flexible, distributed applications. Typically services reside on different machines. They are exposed to the outside world by service interfaces. A service provider provides its functionality using the service interfaces that are used or consumed by the service consumers. A service consumer sends a service request to a service interface and receives a service response. The following figure represents a typical service consumer-service provider request. A service can be a service provider and a service consumer at the same time as it can consume other services. They communicate using a communication medium like a local area network for internal services or the Internet for external services. This communication medium is called a service bus. We saw that services don't have a presentation layer as we've decoupled the presentation layer from the rest. This presents an advantage because we can now use any platform able to understand and consume the service to build a presentation layer. The service interface has to provide a standard and open way of communication, a common language that both service providers and service consumers can understand, regardless of the machine type they are deployed on, their physical location, and the language in which they are written. XML Web Services In today's world, the communication standard used to connect services is achieved using web services. Web services are small, reusable applications that help computers with many different operating system platforms work together by exchanging messages. Web services are based on industry protocols that include XML (Extensible Markup Language), SOAP (Simple Object Access Protocol), and WSDL (Web Services Description Language). These protocols help computers work together across platforms and programming languages enabling data exchange between otherwise unconnected sources: Client-to-Client: Devices, also called smart clients, can host and consume XML web services, allowing data sharing anywhere, anytime. Client-to-Server: A server application can share data with desktop or mobile devices using XML web services over the Internet. Server-to-Server: Independent server applications can use XML web services as a common interface to share and exchange data. Service-to-Service: Systems that work together to deliver complex data processing can be created using XML web services. The following figure shows an example of services exposed using web services, which deliver their functionality to a wide variety of platforms and applications. Service-oriented architecture provides us with the maximum flexibility in building applications. Individual services define specific application functions and interact with one another to provide the entire business process functionality. Encapsulation: Just as an object encapsulates its internal implementation details inside while providing public methods to external objects, services encapsulate their internal complexity and implementation from the service consumers who don't have to know the internal details. Mobility: As services are independent and encapsulated, they can be deployed in any location. Since they are using the same standard communication language, they are accessed in the same way irrespective of their physical location or implementation details. Parallel development: A service-oriented application is built using several service layers and clients. These application components can be built in parallel by developers specialized in specific layer functionality, speeding up the development process. Platform independence: Service providers and service consumers can be written in any language and deployed on any platform, as long as they can speak the standard communication language. Security: More security can be added to a service-oriented application at the service interface layer. Different application components require different security levels. The security can be enforced by using firewalls configured to allow access only to the required service providers only by the required service consumers. In addition, by using Web Service Enhancements (WSE), authentication, authorization, and encryption can be easily added. Reusability: Once a service is constructed and deployed, it can be used by any other service consumer without problems related to platform integration and interoperability. Choosing an Application Architecture Now that we have seen the existing application architectures, we must choose one that meets our project requirements. As you may have guessed by this point, the best application architecture we can use for our project is a Service-Oriented Architecture (SOA). The SOA allows us to build a distributed system, a system that has great flexibility and interoperability with other systems on other platforms. This will allow us to build the business logic functions and expose them as services that will be used by higher functionality layers. Choosing an Application Platform After choosing our application architecture, we must choose a platform capable of building and supporting it. For the purpose of our system we will choose the Microsoft .NET Framework platform and build the system using Microsoft Visual Studio.NET 2005 and Microsoft SQL Server as the back-end database for storing the data. Microsoft .NET Framework From a Service-Oriented Architecture point of view, the .NET Framework is the Microsoft strategy for connecting systems, information, and devices through software such as web services. .NET technology provides the capability to quickly build, deploy, manage, and use connected, security-enhanced solutions through the use of web services. Intrinsically, the .NET Framework is an environment for development and execution that allows different programming languages and libraries to work together to create Windows-based applications that are easier to build, manage, deploy, and integrate with other networked systems. The .NET core components are: The Common Language Runtime (CLR): A language-neutral development and execution environment that provides a consistent model and services to manage application execution that includes: Support for different programming languages: A variety of over 20 programming languages that target the CLR, such as C#, VB.NET, and J#, can be used to develop applications. Support for libraries developed in different languages: Libraries developed in different languages integrate seamlessly, making application development faster and easier. Support for different platforms: .NET applications are not tied to a single platform and can be executed on any platform that supports the CLR. Enhanced security: The .NET Code Access Security model provides a managed environment for application execution and security. Automatic resource management: The CLR automatically handles process, memory, and thread management, enabling developers to focus on the core business logic code.   The Framework Class Libraries (FCL): An object-oriented library of classes that extends a wide range of functionality including: Support for basic operations: Input/output and string management, standard network protocols, and network standards such as TCP/IP, XML, SOAP, and HTTP are supported natively to allow basic operations and system connections. Support for data access and data manipulation: The FCL includes a range of data access and data manipulation classes forming the ADO.NET technology that natively supports XML and data environments such as SQL Server and Oracle. Support for desktop applications: Rich desktop and mobile client applications can be easily created using the Windows Forms technology. Support for web applications: Thin web clients, websites, and web services can be created using web forms and XML web services technologies that form ASP.NET.   In the planning phase we've gathered the project requirements and specifications and we've also chosen an application architecture. The next phase is the design phase. Designing the System In the design phase, we will create an application design based on the application architecture, project requirements, and specifications. Gathering all the information needed to design the system is a difficult task, but the most important step is to start writing down the first idea. System Structure The system will be composed from the following main component categories: Core components (Data Access Layer, Business Logic Layer) forming the middle-tier component layers. Web service components (XML Web service) forming the Service Interface layer. Website components (ASP.NET website) forming the front-end WebReservation application, a web presentation layer. Windows Application components (Windows Forms Application) forming the WinReservation application, a Windows presentation layer. The following figure illustrates the overall system structure, outlining each system component: As we saw earlier, one major advantage of a service-oriented application is the decoupling of the presentation layer from the business logic layer. This allows for the business logic layer being exposed as a web service to be used by other third parties to integrate its functionality into their business process. Database Structure The back-end database is hosted by a Microsoft SQL Server system. According to the project specifications the internal database structure will be composed of the following database tables: User (Contains the user accounts) Guest (Contains the personal details of the guests) Room (Contains the details of each of the hotel's rooms) Reservation (Contains the details of the reservation made by each user) The following figure illustrates these tables and the relations between them. The bold fields are mandatory (not NULL). The User table contains the following rows:    
Read more
  • 0
  • 0
  • 4652

article-image-coldfusion-8-enhancements-you-may-have-missed
Packt
22 Oct 2009
5 min read
Save for later

ColdFusion 8-Enhancements You May Have Missed

Packt
22 Oct 2009
5 min read
<cfscript> Enhancements Poor <cfscript>! It can't be easy being the younger sibling to CFML tags. Natively, you can just do more with tags. Tags are arguably easier to learn and read, especially for beginners. Yet, since its introduction in ColdFusion 4.0, <cfscript> has dutifully done its job while getting none, or little, of the love. Given that ColdFusion was marketed as an easy-to-learn tag-based language that could be adopted by non-programmers who were only familiar with HTML, why did Allaire make the effort to introduce <cfscript>? Perhaps it was an effort to add a sense of legitimacy for those who didn't view a tag-based language as a true language. Perhaps it was a matter of trying to appeal to more seasoned developers as well as beginners. In either case, <cfscript> <cfscript> wasn't without some serious limitations that prevented it from gaining widespread acceptance.<cfscript> For example, while it boasted an ECMAScript-like syntax, which perhaps would have made it attractive to JavaScript developers, it was tied tightly enough to CFML that it used CFML operators. If you were used to writing the following to loop over an array in JavaScript: for (var i=0; i<myArray.length; i++) { … it wasn't quite a natural progression to write the same loop in cfscript<cfscript>: <cfscript>for (i=1; i lt arrayLen(myArray); i=i+1) {<cfscript> On the surface, it may look similar enough. But there are a few significant differences. First, the use of "lt" to represent the traditional "<" ('less than' operator). Second, the lack of a built-in increment operator. While ColdFusion does have a built-in incrementValue() function, that doesn't really do much to bridge the gap between <cfscript> and ECMAScript. When you're used to using traditional comparison operators in a scripting language (<, =, >, etc), as well as using increment operators (++), you would likely end up losing more time than you'd save in <cfscript>. Why? Because chances are that you'd type out the loop using the traditional comparison operators, run your code, see the error, smack your forehead, modify the code, and repeat. Well, your forehead is going to love this. As of ColdFusion 8, cfscript supports all of the traditional comparison operators (<, <=, ==, !=, =>, >). In addition, both <cfscript> and CFML support the following operators as of ColdFusion 8: Operator Name ColdFusion Pre CF 8 ColdFusion 8 ++ Increment i=i+1 i++ -- Decrement i=i-1 i-- % Modulus x = a mod b x = a%b += Compound Addition x = x + y x += y -= Compound Subtraction x = x - y x -= y *= Compound Multiplication x = x * y x *= y /= Compound Division x = x / y x /= y %= Compound Modulus x = x mod y x %= y &= Compound Concatenation (Strings) str = "abc"; str = str & "def"; str = "abc"; str &= "def"; && Logical And if (x eq 1) and (y eq 2) if (x == 1) && (y == 2) || Logical Or if (x eq 1) or (y eq 2) if (x == 1) || (y == 2) ! Logical Complement if (x neq y) if (! x == y)   For people who bounce back and forth between ColdFusion and languages like JavaScript or ActionScript, this should make the transitions significantly less jarring. Array and Structure Enhancements Arrays and structures are powerful constructs within the world of programming. While the naming conventions may be different, they exist in virtually every language. Creating even a moderately complex application without them would be an unpleasant experience to say the least. Hopefully you're already putting them to use. If you are, your life just got a little bit easier. Creating Arrays One of the perceived drawbacks to a tag-based language like CFML is that it can be a bit verbose. Consider the relatively straightforward task of creating an array and populating it with a small amount of data: <cfset myArray  = arrayNew(1) /><cfset myArray[1] = "Moe" /><cfset myArray[2] = "Larry" /><cfset myArray[3] = "Curly" /> In <cfscript> it gets a little bit better by cutting out some of the redundancy of the <cfset> <cfset> tags: <cfset&gt<cfscript> myArray  = arrayNew(1); myArray[1] = "Moe"; myArray[2] = "Larry"; myArray[3] = "Curly";</cfscript></cfset&gt A little bit better. But if you're familiar with languages like JavaScript, ActionScript, Java, or others, you know that this can still be improved upon. That's exactly what Adobe's done with ColdFusion 8. ColdFusion 8 introduces shorthand notation for the creation of arrays. <cfset myArray = [] /> The code above will create an empty array. In and of itself, this doesn't seem like a tremendous time saver. But, what if you could create the array and populate it at the same time? <cfset myArray = ["Larry", "Moe", "Curly"] /> The square brackets tell ColdFusion that you're creating an array. Inside the square brackets, a comma-delimited list populates the array. One caveat to be aware of is that ColdFusion has never taken much of a liking to empty list elements. The following will throw an error: <cfset myArray = ["Larry", , "Curly"] /> <!-- don't do this --> If you're populating your array dynamically, take steps to ensure that there are no empty elements in the list.      
Read more
  • 0
  • 0
  • 2419

article-image-using-object-oriented-approach-implementing-php-classes-interact-oracle
Packt
22 Oct 2009
8 min read
Save for later

Using An Object Oriented Approach for Implementing PHP Classes to Interact with Oracle

Packt
22 Oct 2009
8 min read
Before you start developing object-oriented solutions with PHP 5, it is important to understand that its object model provides more features than PHP 4's object model. Like most object-oriented languages, PHP 5 allows the developer to take advantage of interfaces, abstract classes, private/public/protected access modifiers, static members and methods, exception handling, and other features that were not available in PHP 4. But perhaps the most important thing to note about the object-oriented improvements of PHP 5 is that objects are now referenced byhandle, and not by value. Building Blocks of Applications As you no doubt know, the fundamental building block in any object-oriented language is a structure called a class. A class is a template for an object. It describes the data and behavior of its instances (objects). During run time, an application can create as many instances of a single class as necessary. The following diagram conceptually depicts the structure of a class. You might find it handy to think of an object-oriented application as a building made of blocks, where classes are those blocks. However, it is important to note that all blocks in this case are exchangeable. What this means is that if you are not satisfied with the implementation of a certain class, you can use a relevant class that has the same Application Programming Interface (API) but a different implementation instead. This allows you to increase the reusability and maintainability of your application, without increasing the complexity. The intent of the example discussed in this section is to illustrate how you can rewrite the implementation of a class so that this doesn't require a change in the existing code that employs this class. In particular, you'll see how a custom PHP 4 class designed to interact with Oracle can be rewritten to use the new object-oriented features available in PHP 5. Creating a Custom PHP Class from Scratch To proceed with the example, you first need to create a PHP 4 class interacting with Oracle. Consider the following dbConn4 class: <?php //File: dbConn4.php class dbConn4 { var $user; var $pswd; var $db; var $conn; var $query; var $row; var $exec_mode; function dbConn4($user, $pswd, $db, $exec_mode= OCI_COMMIT_ON_SUCCESS) { $this->user = $user; $this->pswd = $pswd; $this->db = $db; $this->exec_mode = $exec_mode; $this->GetConn (); } function GetConn() { if(!$this->conn = OCILogon($this->user, $this->pswd, $this->db)) { $err = OCIError(); trigger_error('Failed to establish a connection: ' . $err['message']); } } function query($sql) { if(!$this->query = OCIParse($this->conn, $sql)) { $err = OCIError($this->conn); trigger_error('Failed to parse SQL query: ' . $err['message']); return false; } else if(!OCIExecute($this->query, $this->exec_mode)) { $err = OCIError($this->query); trigger_error('Failed to execute SQL query: ' . $err['message']); return false; } return true; } function fetch() { if(!OCIFetchInto($this->query, $this->row, OCI_ASSOC)) { return false; } return $this->row; } } ?> In the above script, to define a class, you use the class keyword followed by the class name. Then, within curly braces, you define class properties and methods. Since this class is designed to work under both PHP 4 and PHP 5, all the class properties are defined with the var keyword. Declaring a property with var makes it publicly readable and writable. In PHP 5, you would use the public keyword instead. In PHP 4, you define the class constructor as a function with the same name as the class itself. This still works in PHP 5 for backward compatibility. However, in PHP 5, it's recommended that you use __construct as the constructor name. In the above example, the class constructor is used to set the member variables of a class instance to the values passed to the constructor as parameters. Note the use of the self-referencing variable $this that is used here to access the member variables of the current class instance. Within class methods, you can use $this, the special variable that points to the current instance of a class. This variable is created automatically during the execution of any object's method and can be used to access both member variables of the current instance and its methods. Then, you call the GetConn method from within the constructor to obtain a connection to the database. You reference the method using the $this variable. In this example, the GetConn method is supposed to be called from within the constructor only. In PHP 5, you would declare this method as private. To obtain a connection to the database in this example, you use the OCILogon function. In PHP 5, you would use the oci_connect function instead. The query method defined here takes an SQL string as the parameter and then parses and executes the query. It returns true on success or false on failure. This method is supposed to be called from outside an object. So, in PHP 5, you would declare it as public. Finally, you define the fetch method. You will call this method to fetch the results retrieved by a SELECT statement that has been executed with the query method. Testing the Newly Created Class Once written, the dbConn4 class discussed in the preceding section can be used in applications in order to establish a connection to an Oracle database and then issue queries against it as needed. To see this class in action, you might use the following PHP script. Assuming that you have saved the dbConn4 class as the dbConn4.php file, save the following script as select.php: <?php //File: select.php require_once 'dbConn4.php'; require_once 'hrCred.php'; $db = new dbConn4($user, $pswd, $conn); $sql="SELECT FIRST_NAME, LAST_NAME FROM employees"; if($db->query($sql)){ print 'Employee Names: ' . '<br />'; while ($row = $db->fetch()) { print $row['FIRST_NAME'] . '&nbsp;'; print $row['LAST_NAME'] . '<br />'; } } ?> The above select.php script employs the employees table from the hr/hr demonstration schema. So, before you can execute this script, you must create the hrCred.php file that contains all the information required to establish a connection to your Oracle database using the HR account. The hrCred.php file should look as shown below (note that the connection string may vary depending on your configuration): <?php //File: hrCred.php $user="hr"; $pswd="hr"; $conn="(DESCRIPTION= (ADDRESS_LIST= (ADDRESS=(PROTOCOL=TCP)(HOST=localhost)(PORT=1521)) ) (CONNECT_DATA=(SID=orcl)(SERVER=DEDICATED)) )"; ?> Once you have created the hrCred.php script, you can execute the select.php script. As a result, it should output the names of employees from the employees table in the hr/hr demonstration schema. Taking Advantage of PHP 5's Object-Oriented Features Turning back to the dbConn4 class, you may have noticed that it was written for PHP 4. Of course, it still can be used in new applications written for PHP 5. However, to take advantage of the new object-oriented features available in PHP 5, you might want to rewrite this class as follows: <?php //File: dbConn5.php class dbConn5 { private $user; private $pswd; private $db; private $conn; private $query; private $row; private $exec_mode; public function __construct($user, $pswd, $db, $exec_mode= OCI_COMMIT_ON_SUCCESS) { $this->user = $user; $this->pswd = $pswd; $this->db = $db; $this->exec_mode = $exec_mode; $this->GetConn(); } private function GetConn() { if(!$this->conn = oci_connect($this->user, $this->pswd, $this->db)) { $err = oci_error(); trigger_error('Failed to establish a connection: ' . $err['message']); } } public function query($sql) { if(!$this->query = oci_parse($this->conn, $sql)) { $err = oci_error($this->conn); trigger_error('Failed to execute SQL query: ' . $err['message']); return false; } else if(!oci_execute($this->query, $this->exec_mode)) { $err = oci_error($this->query); trigger_error('Failed to execute SQL query: ' . $err['message']); return false; } return true; } public function fetch() { if($this->row=oci_fetch_assoc($this->query)){ return $this->row; } else { return false; } } } ?> As you can see, the implementation of the class has been improved to conform to the new standards of PHP 5. For instance, the above class takes advantage of encapsulation that is accomplished in PHP 5—like most other object-oriented languages—by means of access modifiers, namely public, protected, and private. The idea behind encapsulation is to enable the developer to design the classes that reveal only the important members and methods and hide the internals. For instance, the GetConn method in the dbConn5 class is declared with the private modifier because this method is supposed to be called only from inside the constructor when a new instance of the class is initialized; therefore, there is no need to allow client code to access this method directly. Since the implementation of the newly created dbConn5 class is different from the one used in dbConn4, you may be asking yourself: "Does that mean we need to rewrite the client code that uses the dbConn4 class as well?" The answer is obvious: you don't need to rewrite client code that uses the dbConn4 class since you have neither changed the Application Programming Interface (API) of the class nor,more importantly, its functionality. Thus, all you need to do in order to make the select.php script work with dbConn5 is simply replace all the references to dbConn4 with references to dbConn5 throughout the script.
Read more
  • 0
  • 0
  • 7001
article-image-adding-newsletters-web-site-using-drupal-6
Packt
22 Oct 2009
4 min read
Save for later

Adding Newsletters to a Web Site Using Drupal 6

Packt
22 Oct 2009
4 min read
Creating newsletters A newsletter is a great way of keeping customers up-to-date without them needing to visit your web site. Customers appreciate well-designed newsletters because they allow the customer to keep tabs on their favorite places without needing to check every web site on a regular basis. Creating a newsletter Good Eatin' Goal: Create a new newsletter on the Good Eatin' site, which will contain relevant news about the restaurant, and will be delivered quarterly to subscribers. Additional modules needed: Simplenews (http://drupal.org/project/simplenews). Basic steps Newsletters are containers for individual issues. For example, you could have a newsletter called Seasonal Dining Guide, which would have four issues per year (Summer, Fall, Winter, and Spring). A customer subscribes to the newsletter and each issue is sent to them as it becomes available. Begin by installing and activating the Simplenews module, as shown below: At this point, we only need to enable the Simplenews module, and the Simplenews action module can be left disabled. Next, select Content management and then Newsletters, from the Administer menu. Drupal will display an administration area divided into the following sections: a) Sent issuesb) Draftsc) Newslettersd) Subscriptions Click on the Newsletters tab and Drupal will display a page similar to the following: As you can see, a default newsletter with the name of our site has been automatically created for us. We can either edit this default newsletter or click on the Add newsletter link to create a new newsletter. Let's click the Add newsletter option to create our seasonal newsletter. Drupal will display a standard form where we can enter the name, description, and relative importance (relative importance weight) of the newsletter. Click Save to save the newsletter. It will now appear in the list of available newsletters. If you want to modify the Sender information for the newsletter to use an alternate name or email address to your site's default ones, you can either expand the Sender information section when adding the newsletter, or you click Edit newsletter and modify the Sender information, as shown in the following screenshot: Allowing users to sign-up for the newsletter Good Eatin' Goal: Demonstrate how registered and unregistered users can sign-up for a newsletter, and configure the registration process. Additional modules needed: Simplenews (http://drupal.org/project/simplenews). Basic steps To allow customers to sign-up for the newsletter, we will begin by adding a block to the page. Open the Block Manager by selecting Site building and then Blocks, from the Administer menu. Add the block for the newsletter that you want to allow customers to subscribe to, as shown in the following screenshot: We will now need to give users permission to subscribe to newsletters by selecting User management and then Permissions, from the Administer menu. We will give all users permissions to subscribe to newsletters and to view newsletter links, as shown below: If the customer does not have permission to subscribe to newsletters then the block will appear as shown in the following screenshot: However, if the customer has permissions to subscribe to newsletters, and is logged in to the site, the block will appear as shown in the following screenshot: If the customer has permission to subscribe, but is not logged in, the block will appear as follows: To subscribe to the newsletter, the customer will simply click on the Subscribe button. Once they he subscribed, the Subscribe button will change to Unsubscribe so that the user can easily opt out of the newsletter. If the user does not have an active account with the site, they will need to confirm that they want to subscribe to the site.
Read more
  • 0
  • 0
  • 2721

article-image-content-modeling
Packt
22 Oct 2009
12 min read
Save for later

Content Modeling

Packt
22 Oct 2009
12 min read
Organizing content in a meaningful way is nothing new. We have been doing it for centuries in our libraries—the Dewey decimal system being a perfect example. So, why can't we take known approaches and apply them to the Web? The main reason is that a web page has more than two dimensions. A page on a book might have footnotes or refer to other pages, but the content only appears in one place. On a web page, content can directly link to other content and even show a summary of it. It goes way beyond just the content that appears on the page—links, related content, reviews, ratings, etc. All of this brings extra dimensions to the core content of the page and how it is displayed. This is why it's so important to ensure your content model is sound. However, there is no such thing as the "right" content model. Each content model can only be judged on how well it achieves the goals of the website now and in the future. The Purpose of a Content Model The idea of a content model is new, but it has similarities to both a database design and an object model. The purpose of both of these is to provide a foundation for the logic of the operation. With a database design, we want to structure the data in a meaningful way to make storage and retrieval effective. With an object model, we define the objects and how they relate to each other so that accessing and managing objects is efficient and effective. The same applies to a content model. It's about structuring the content and the relationships between the classes to allow the content to be accessed and displayed easily. The following diagram is a simple content model that shows the key content classes and how they relate to each other. In this diagram, we see that resources belong to a collection which in turn belongs to a context. Also, a particular resource can belong to more than one collection. As stated before, there is no such thing as the "right" model. What we are trying to achieve is the most "effective" model for the project at hand. This means coming up with a model that will provide the most effective way of organizing content so that it can be easily displayed in the manner defined in the functional specification. The way a content model is defined will have an impact on how easy it is to code templates, how quickly the code will run, how easy it is for the editors to input content, and also how easy it is to change down the track. From experience, rarely is a project completed and then never touched again. Usually, there are changes, modifications, updates, etc. down the track. If the model is well structured, these changes will be easy, if not, they can require a significant amount of work to implement. In some cases, the project has to be rebuilt entirely and content re-entered to achieve the goals of the client. This is why the model is so important. If done well, it means the client pays less and has a better-running solution. A poor model will take longer to implement and changes will be more difficult to implement. What Makes a Good Model? It's not easy to define exactly what makes a good model. Like any form of design, simplicity is the key. The more the elements, the more complex it gets. Ideally, a model should be technology independent, but there are certain ways in which eZ publish operates that can influence how we structure the content model. Do we always need a content model? No, it depends on the scale of the project. Smaller projects don't really need a formal model. It's only when there are specific relationships between content classes that we need to go to the effort of creating a model. For example, a basic website that has a number of sections, e.g., About Us, Services, Articles, Contact, etc., doesn't need a model. There's no need for an underlying structure. It's just content added to sections. The in-built content classes in eZ publish will be enough to cater for that type of site. It's when the content itself has specific relationships e.g., a book belongs to a category or a product belongs to a product group, which belongs to a division of the business—this is when you need to create a model to capture the objects and the relationships between them. T o start with, we need to understand the content we are dealing with. The broad categories are existing/known content and new content. If we know the structure of the content we are dealing with and it already exists, this can help to shape the model. If we are dealing with content that doesn't exist yet (i.e. is to be written or created for this project) it's harder to know if we are on the right track. For example, when dealing with products, generally the product data will already exist in a database or ERP system. This gives us a basis from which to work. We can establish the structure of the content and the relationships from the existing data. That doesn't mean that we simply copy what's there, but it can guide us in the right direction. Sometimes the structure of the data isn't effective for the way it's to be displayed on the Web or it's missing elements. (As a typical example, in a recent project, the product data was stored in three places—the core details were in the Point of Sale system, product details and categorization were in a spreadsheet, and the images were stored on a file system.) So, the first step is to get an understanding of all the content we are dealing with. If the content doesn't exist as yet, at least get some examples of what it is likely to be. Without knowing what you are dealing with, you can't be sure your model will accommodate everything. T his means you'll need to allow for modifications down the track. Of course we want to minimize this but it's not always possible. Clients change their minds so the best we can do is hope that our model will accommodate what we think are the likely changes. This really can only be done through experience. There are patterns in content as well as how it's displayed. Through these patterns e.g., a related-content box on each page, we can try to foresee the way things might alter and build room for this into the model. A good example was that on a recent project, for each object, there was the main content but there were also a number of related objects (widgets) that were to be displayed in the right-hand column of the page. Initially, the content class defined the specific widgets to be associated with the object. The table below contains the details of a particular resource (as shown in the previous content model). It captures the details of the "research report" resource content class. Attribute Type Notes Title Text line Short Title Text Line If present, will be used in menus and URLs Flash Flash Navigator object Hero Image Image (displays if no flash) Caption Rich text   Body* Rich Text   Free Form Widgets Related Objects Select one or more Multimedia Widget Related Object Select one This would mean that when the editor added content, they would pick the free-form widgets and then the multimedia widget to be associated with the research report. Displaying the content would be straightforward as from the parent object we would have the object IDs for each widget. The idea is sound but lacks flexibility. It would mean that the order in which the object was added would dictate the order in which it was displayed. It also means that if the editor wants to choose to add a different type of widget, they couldn't unless the model was changed, i.e., another attribute was added to the content class. We updated the content class as follows: Attribute Type Notes Title* Text line Short Title Text Line If present, will be used in menus and URLs Flash Flash Navigator object Hero Image Image (displays if no flash) Caption Rich text   Body* Rich Text   Widgets Related Objects Select one or more This approach is less strict and provides more flexibility. The editor can choose any widget and also select the order. In terms of programming the template, there's the same amount of work. But, if we decide to add another widget type down the track, there's no need to update the content class to accommodate it. Does this mean that anytime we have a related object we should use the latter approach? No, the reason we did it in this situation is that the content was still being written as we were creating the model, and there was a good chance that once the content was entered and we saw the end result, the client was going to say something like "can we add widget x" to the right-hand column of a context object? In a different project, in which a particular widget should only be related to a particular content class, it's better to enforce the rule by only allowing that widget to be associated with that content class. Defining a Content Model The process of creating a content model requires a number of steps. It's not just a matter of analyzing the content; the modeler also needs to take into consideration the domain, users, groups, and the relationships between different classes within the model. To do this, we start with a walkthrough of the domain. Step 1: Domain Walkthrough The client and domain experts walk us through the entire project. This is a vital part of the process. We need to get an understanding of the entire system, not just the part that is captured in the final solution. The model that we end up creating may need to interact with other systems and knowing what they are and how they work will inform the shape of the model. A good example is with e-commerce systems, any information captured on a sale will eventually need to be entered into the existing financial system (whether is it automated or manual). Without an understanding of the bigger picture, we lack the understanding of how the solution we are creating will fit in with what the business does. That's when there is an existing business process. Sometimes there is no business process and the client is making things up as they go along, e.g. they have decided to do online shopping but they have never dealt with overseas orders so don't know how that will work and have no idea how they would deal with shipping costs. One of the typical problems that will surface during the domain walkthrough is that the client will try to tell you how they want the solution to work. By doing this, they are actually defining the model and interactions. This is something to be wary of. It is unlikely that they would be aware of how best to structure a solution; what you want to be asking is what they currently do, what's their current business process. You want to deal with facts that are in existence so that you can decide how best to model the solution. To get the client back on track ask questions like: How do you currently do "it" (i.e. the business process)? What information to you currently capture? How do you capture that information? What format is that information in? How often is the information updated? Who updates it? This gives you a picture of what is currently happening. Then you can start to shape the model to ensure that you are dealing with the real world, not what the client thinks they want. Sometimes they won't be able to answer the question and you'll have to get the right person from the business involved to get the answers you want. Sometimes you discover that what the client thought was happening is not really what happens. Another benefit of this process is gaining a common understanding. If both you and the client are in the room when the process for calculating shipping costs is being explained by the Shipping Manager, you'll both appreciate how complex the process is. If the client thinks it's easy, they won't expect it to cost much. If they are in the room when the shipping manager explains there are five different shipping methods and each has its own way of calculating the costs for a shipment based on their own set of international zones, you know modeling that part of the system is not going to be straightforward unlike what the client initially thought. What this means is that the domain walkthrough gives you a sense of what's real, not what people think the situation is. It's the most important part of the process. Assumptions that "shipping costs" are straightforward, so you don't need to worry about that, can be a disaster later down the track when you find out it's not the case. Also, don't necessarily rely on requirements documents (unless you have written them yourself). A statement in a requirements document may not reflect what really happens; that's why you want to make sure you go through everything to confirm that you have all the facts. Sometimes, a particular requirement can be stated in the document but when you go through it in more detail, ask a few questions, pose a few scenarios, the client changes their mind on what it is that they really want as they realize what they thought they wanted is going to be difficult or expensive to implement. Or, you put an alternative approach to them and they are happy to achieve the same result in a different manner that is easier to implement. This is a valuable way to work out what's real and what really matters.
Read more
  • 0
  • 0
  • 2522

article-image-obtaining-alfresco-web-content-management-wcm
Packt
22 Oct 2009
11 min read
Save for later

Obtaining Alfresco Web Content Management (WCM)

Packt
22 Oct 2009
11 min read
You must obtain and install an additional download to enable Alfresco WCM functionality. The download includes a new Spring bean configuration file, a standalone Tomcat instance pre-configured with JARs, and server settings that allow a separate Tomcat instance (which is called the virtualization server) to run web applications stored in Alfresco WCM web folders. This capability is used when content managers "preview" an asset or a website. Just as in the core Alfresco server, you can either build the WCM distribution from source or obtain a binary distribution. Step-by-Step: Installing Alfresco WCM If you are building from source, the source code for Alfresco WCM is included with the source code for the rest of the product. Once the source code is checked out, all you have to do is run the distribute Ant task as follows: ant -f continuous.xml distribute After several minutes, the WCM distribution will be placed in the build|dist directory of your source code's root directory. Alternatively, if you are using binaries, download the binary distribution of the Alfresco WCM extension. Where you get it depends on whether you are running Labs or Enterprise. The Labs version is available for download from http://www.alfresco.com. The Enterprise version can be downloaded from the customer or partner site using the credentials provided by your Alfresco representative. Regardless of whether you chose source or binary, you should now have an Alfresco WCM archive. For example, the Labs edition for Linux is named alfresco-labs-wcm-3b.tar.gz. To complete the installation, follow these steps: Expand the archive into any directory that makes sense to you. For example, on my machine I use |usr|local|bin|alfresco-labs-3.0-wcm. Copy the wcm-bootstrap-context.xml file to the Alfresco server's extension directory ($TOMCAT_HOME|shared|classes|alfresco|extension). Edit the startup script (virtual_alf.sh) to ensure that the APPSERVER variable is pointing to the virtual-tomcat directory in the location to which you expanded the archive. Using the example from the previous step, the APPSERVER variable would be: APPSERVER=|usr|local|bin|alfresco-labs-3.0-wcm|virtual-tomcat Start the virtual server by running: |virtual_alf.sh start</i> Start the Alfresco server (or restart it if it was already running). You now have Alfresco with Alfresco WCM up and running. You'll test it out in the next section, but you can do a smoke test by logging in to the web client and confirming that you see the Web Projects folder under Company Home. Creating Web Projects A web project is a collection of assets, settings, and deployment targets that make up a website or a part of a website. Web projects are stored in web project folders, which are regular folders with a bunch of web project metadata. The number of web project folders you use to represent a site, or whether multiple sites are contained within a single web project folder is completely up to you. There is no "right way" that works for everybody. Permissions are one factor. The ability to set permissions stops at the website. Therefore, if you have multiple groups that maintain a site that are concerned with the ability of one to change the other's files, your only remedy is to split the site across web project folders. Web form and workflow sharing is another thing to think about. As you'll soon learn, workflows and web forms are defined globally, and then selectively chosen and configured by each site. Once made available to a web project, they are available to the entire web project. For example, you can't restrict the use of a web form to only a subset of the users of a particular site. SomeCo has chosen the approach of using one web project folder to manage the entire SomeCo.com website. Step-by-Step: Creating the SomeCo Web Project The first thing you need to do is create a new web project folder for the SomeCo website. Initially, you don't need to worry about web forms, deployment targets, or workflows. The goal is simply to create the web project and import the contents of the website. To create the initial SomeCo web project, follow these steps: Log in as admin. Go to Web Projects under Company Home. Click Create, and then Create Web Project. Specify the name of the web project as SomeCo Corporate Site. Specify the DNS name as someco-site. Click Next for the remaining steps, taking all defaults. You'll come back later and configure some of these settings. On the summary page, click Finish. You now have a web project folder for the SomeCo corporate site. Click SomeCo Corporate Site. You should see one Staging Sandbox and one User Sandbox. Click the Browse Website button for the User Sandbox. Now you can import SomeCo's existing website into the web project folder. Click Create, and then Bulk Import. Navigate to the "web-site" project in your Eclipse workspace. Assuming you've already run Ant for this project, there should be a ZIP file in the build folder called someco-web-site.zip. Select the file. Alfresco will import the ZIP into your User Sandbox. What Just Happened You just created a new web project folder for SomeCo's corporate website. But upon creation of a web project folder, there is no website to manage. This is a big disappointment for some people. The most crestfallen are those who didn't realize that Alfresco is a "decoupled" content management system—it has no frontend framework and no "default" website like "coupled" content management systems such as Drupal. This will change in the 3.0 releases as Alfresco introduces its new set of clients. But for now, it's up to you to give Alfresco a website to manage. You just happened to have a start on the SomeCo website sitting in your Eclipse workspace. Alfresco knows how to import WAR and ZIP files, which is a convenient way to migrate the website into Alfresco for the first time. Because web project sandboxes are mountable via CIFS, simply copying the website into the sandbox via CIFS is another way to go. The difference between the two approaches is that the WAR/ZIP import can only happen once. The import action complains if an archive contains nodes that already exist in the repository. If you haven't already done so, take a look at the contents of your sandbox. You should see index.html in the root of your User Sandbox and a someco folder that contains additional folders for CSS, images, JavaScript, and so on. The HTML file in the root is the same index.html file you deployed to the Alfresco web application in order to implement the AJAX ratings widget. Click the preview icon. (Am I the only one who thinks it looks eerily similar to the Turkish nazar talisman used to ward off the "evil eye"?) You should see the index page in a new tab or window. The list of Whitepapers won't be displayed. That's because the page is running in the context of the virtualization server, which is a different domain than your Alfresco server. Therefore, it is subject to the cross-domain restriction, which will be addressed later. Playing Nicely in the Sandbox Go back to the root of your web project folder. The link in the breadcrumb trail is likely to be the fastest way to navigate back. Click the Browse Website link in the Staging Sandbox. It's empty. If you were to invite another user to this website, his/her sandbox would be empty as well. Sandboxes are used to isolate changes each content owner makes, while still providing him/her the full context of the website. The Staging Sandbox represents your live website. Or in source code control terms, it is the HEAD of your site. It is assumed that whatever is in the Staging Sandbox can be safely deployed to the live website at any time. It is currently empty because you have not yet submitted any content to staging. Let's go ahead and do that now. If you click the Modified Items link in the User Sandbox, you'll see the index.html file and the someco folder. You could submit these individually. But you want everything to go to staging, so click Submit All: Provide a label and a description such as initial population and click OK. It is safe to ignore the warning that a suitable workflow was not found. That's expected because you haven't configured a workflow for this web project yet. Now the files have been submitted to staging. Here are some things to notice: If you click the Preview Website link in the Staging Sandbox, you'll see the website just as you did in the User Sandbox earlier. If you browse the website in the Staging Sandbox, you'll see the same files currently shown when you browse the website in your User Sandbox. A snapshot of the site was automatically taken when the files were committed and is listed under Recent Snapshots: Inviting Users To get a feel for how sandboxes work, invite one or more users to the web project (Actions, Invite Web Project Users). The following table describes the out of the box web project roles:   WCM User Role Can do these things Content Contributor Create and submit new content; but cannot edit or delete existing content Content Reviewer Create, edit, and submit new content; but cannot delete existing content Content Collaborator See all sandboxes, but only have full control over their own Create, edit, and submit new content; but cannot delete existing content Edit web project settings Content Manager See and modify content in all sandboxes; exert full control over all content See and deploy snapshots and manage deployment reports Edit web project settings Invite new users to the web project Delete the web project and individual sandboxes You'll notice that each new user gets his/her own sandbox, and that the sandbox automatically contains everything that is currently in staging. If a user makes a change to his/her sandbox, it is only visible within their sandbox until they commit the change to staging. If this is done, everyone else sees the change immediately. Unlike some content management and source code control systems, there is no need for other users to do an "update" or a "get latest" to copy the latest changes from staging into their sandbox. It is important to note that Alfresco will not merge conflicts. When a user makes a change to a file in his/her sandbox, it will be locked in all other sandboxes to prevent conflicts. If you were to customize Alfresco to disable locking, the last change would win. Alfresco would not warn you of the conflict. The Alfresco admin user and any user with Content Manager Access can see (and work within) all User Sandboxes. Everyone else sees only their own sandboxes. Mounting Sandboxes via CIFS All sandboxes are individually mountable via CIFS. In fact, in staging, each snapshot is individually mountable. This gives content owners the flexibility to continue managing content in their sandbox using the tools they are familiar with. The procedure for mounting a sandbox is identical to that of mounting the regular repository via CIFS, except that you use "AVM" as the mount point instead of "Alfresco". One difference between mounting the AVM repository through CIFS and mounting the DM repository is that the AVM repository directory structure is more complicated. For example, the path to the root of admin's sandbox in the SomeCo site is: |someco-site--admin|HEAD|DATA|www|avm_webapps|ROOT The first part of the path, someco-site, is the DNS name you assigned when you set up the web project. The admin string indicates which User Sandbox we are looking at. If you wanted to mount to the Staging Sandbox, the first part of the path would be someco-site without --admin. The next part of the path, HEAD, specifies the latest-and-greatest version of the website. Alternatively, you could mount a specific snapshot like this: |someco-site--admin|VERSION|v2|DATA|www|avm_webapps|ROOT As you might expect, the normal permissions apply. Users who aren't able to see another user's sandbox in the web client won't be able to do so through CIFS.
Read more
  • 0
  • 0
  • 2307
article-image-blackberry-bes-architecture-and-implementation-planning
Packt
22 Oct 2009
4 min read
Save for later

BlackBerry: BES Architecture and Implementation Planning

Packt
22 Oct 2009
4 min read
BlackBerry Enterprise Server Components BlackBerry Enterprise Server is not a single service. Like many complex application servers, BES is comprised of a number of services and components that are integrated to deliver the full feature set. Below is a list of the components and a description of their function. Component Name Component Function BlackBerry Attachment Service The BlackBerry Attachment Service converts email attachments into a format that can be viewed on BlackBerry devices. BlackBerry Collaboration Service The BlackBerry Collaboration Service encrypts the communications between instant messaging servers and the instant messenger client on client on BlackBerry devices. BlackBerry Configuration Database The BlackBerry Configuration Database is a relational database that stores the configuration information for the BES components, using either Microsoft SQL Developer Edition (MSDE) or Microsoft SQL Server. BlackBerry Controller The BlackBerry Controller monitors BES components and restarts any stopped services. BlackBerry Dispatcher The BlackBerry Dispatcher handles compression and encryption for BlackBerry data. BlackBerry Manager The BlackBerry Manager is used for administration of the BES. BlackBerry MDS Connection Service The BlackBerry MDS Connection Service is used to connect BlackBerry devices to online content and applications. BlackBerry MDS Services The BlackBerry MDS Services provide connectivity between BlackBerry MDS Studio Applications on BlackBerry devices and enterprise applications. BlackBerry MDS Studio Application Repository The BlackBerry MDS Studio Application Repository stores and manages BlackBerry MDS Studio Applications. BlackBerry Messaging Agent The BlackBerry Messaging Agent serves as the connection between the email server and the other BES components. BlackBerry Policy Service The BlackBerry Policy Service manages the IT policies for the BlackBerry devices. BlackBerry Router The BlackBerry Router connects to the BlackBerry Infrastructure and communicates with the BlackBerry devices. BlackBerry Synchronization Service The BlackBerry Synchronization Service syncs organizer data (tasks, calendar, etc.) between the email server and the BlackBerry devices. The component-based design of BES provides flexibility and scalability as you plan your implementation. This is due to the fact that the components can be installed on a single server or distributed among several servers based on your needs. The BlackBerry Enterprise Server components are integrated to deliver the desired services to your handheld clients. BlackBerry Enterprise Server Requirements and Prerequisites The BlackBerry Enterprise Server system requirements vary based on the number of users supported. Below are the recommended minimum requirements for a BlackBerry Enterprise Server v4.1 for Microsoft Exchange that supports 500 users. Refer to the BlackBerry Enterprise Server Version 4.1 for Microsoft Exchange Server Capacity Calculator at the BlackBerry Technical Solution Center (http://www.blackberry.com/btsc/) to calculate the system requirements for your environment. Intel® Pentium® IV, 2 GHz or better. 1.5GB RAM. BES supports specific Microsoft Windows and Exchange environments. Following are the basic software requirements. Microsoft Windows 2000 Server or Windows Server 2003. Microsoft Exchange 5.5 (SP4 or better), Microsoft Exchange 2000 (SP2 or better), Microsoft Exchange 2003, Microsoft Exchange 2007. Microsoft Internet Explorer 6.0 or better. In addition to the basic hardware and software requirements, there are a number of prerequisites for BES. Some of the prerequisites are installed as a part of the BES setup program, but others must be installed prior to starting the BES installation. Below is the list of prerequisites. Prerequisite Required/ Optional Notes Microsoft Messaging Queue (MSMQ) Version 3.0 Optional This is required for installations that will use Microsoft Windows Messenger. Microsoft .NET Framework Version 1.1 Required This may be installed during BES installation. SP1 is required to use Microsoft Windows Messenger. Microsoft Data Access Components (MDAC) Version 2.8 Required This requires either Security Patch MS04-003 (Version 2000.85.1025.00) or SP2 (Version 2000.86.1830.00) for Microsoft Windows Server 2003 SP1. Java® 2 Platform, Standard Edition (J2SETM) Runtime Environment Version 5.0 update 9 Required This may be installed during BES installation. Internet Service Manager for Internet Information Services Optional This is required for Microsoft Exchange 2007 support. Microsoft Exchange administration tools Required The appropriate tools for your Exchange version should be installed. Microsoft Exchange Version 5.5 Administrator Microsoft Exchange 2000 System Manager Microsoft Exchange  003 System Manager Microsoft Exchange Server MAPI Client and Collaboration Data Objects 1.2.1 For Exchange 2007, Microsoft Exchange Server MAPI Client and Collaboration Data Objects 1.2.1, or Microsoft Exchange Server 2003 System Manager with SP2 Refer to the BlackBerry Enterprise Server for Microsoft Exchange Installation Guide for your version of BES for an up-to-date list of system requirements, especially if you are planning to implement additional services above and beyond the basic messaging and collaboration.  
Read more
  • 0
  • 0
  • 3002

article-image-fedora-8-more-linux-distribution
Packt
22 Oct 2009
4 min read
Save for later

Fedora 8 — More than a Linux Distribution

Packt
22 Oct 2009
4 min read
Fedora project leader, Max Spevack, has himself acknowledged this fact in his Fedora 8 pre-release announcement. "If you think back to the Fedora Core 6 release cycle, you will remember that a significant portion of the engineering goals for that release were driven by the knowledge that Fedora Core 6 would be the upstream for RedHat Enterprise Linux 5. Everyone knew going in that Fedora Core 6 would be more "corporate" than "community"," writes Spevack. Of course in a larger context this has worked for Fedora. The distro has gained much from its "closeness" to RHEL including its impressive security arsenal. As Spevack notes the community was "ok" with these diversions since "we also knew that once Red Hat Enterprise Linux 5 was released, the Fedora Project would be able to spend its next several releases focused on its community-related priorities." And what releases they have been! Fedora 7 marked a new direction for the distro. It merged both its in-house "core" and community "extra" repositories. This gave Fedora's community developers commit access to all Fedora packages, and along with a new build system, called Koji, completed Fedora's leap towards being a true community distro. Furthermore that release also introduced a new composing tool Pungi that produced installable distributions of Fedora once fed with a list of packages. Similarly the LiveCD Creator tool created Live CD and USB releases. Up to this point Fedora had been one of the few distros that didn't have a Live CD to show off itself. The graphical Revisor tool that lets users create installable and Live Fedora "spins" from a multitude of repositories is the cherry on the cake. Creating custom Fedora "spins" started with Fedora 7 and is also what Fedora 8 is all about. Well almost. In addition to an installable DVD, Fedora 8 has several installable Live spins including one each for GNOME and KDE desktops, a developer spin, a games spin, and an electronic lab spin. Since all the tools, from Pungi to Revisor, are free software and available in Fedora repositories, Fedora 8 is a perfect platform for creating your own installable Live CD. Creative Commons uses it for its Live CD to show off some of the quality content released under its license. What I haven't mentioned till now is that Fedora 8 itself is a fantastic release. Desktop users will enjoy its desktop wallpaper that changes color depending on the time of the day, the easy to use Firewall configuration tool and enhanced printer and network management in addition to the Compiz 3D desktop. I love the improved package management which makes adding software from the DVD and other online repositories, not only possible but a walk in the park. Fedora 8 also finds a solution for its inability to support patented media formats in the form of CodecBuddy. But like any other Linux distro Fedora 8 has its comfort zone, where everything works as it should. KDE under Fedora 8 doesn't fall in this category. I think openSUSE 10.3 sets the benchmark for maintaining consistency between GNOME and KDE desktop environments. In fact a few days before its release, Fedora's KDE Special Interest Group sent out a call for help, requesting participation citing a lack of active contributors. I am sure the community will respond and KDE's upcoming release, KDE 4 will be much stable under Fedora 9. Talking of Fedora 9, Spevack hints in Fedora 8's pre-release announcement that "Fedora 9 will probably start to see the pendulum swing back in the other direction [as opposed to Fedora 7 and 8's focus on the community], as Red Hat Enterprise Linux 6 starts to materialize on the horizon." I am not yet sure whether or not this is how things will turn out. But honestly though I think its time we stopped looking at Fedora as a distribution. While it's still early days, one look at Fedora 9's proposed feature list and you know what I'm talking about. Not only will the next release come out with more spins but if everything goes as planned it will expand the ability to create spins from other operating systems and even the web! For sure, Fedora has transitioned from just being a Linux distro to a platform for launching your own, and it's got the perfect recipe of tools to do so. You might also be interested in reading: GoboLinux: An Interview with Lucas Villa Real 2007 Open Source Content Management System Award
Read more
  • 0
  • 0
  • 5172
Modal Close icon
Modal Close icon