Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
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-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-modeling-furniture-blender
Packt
22 Oct 2009
10 min read
Save for later

Modeling Furniture in Blender

Packt
22 Oct 2009
10 min read
Create Models or Use a Library? There are two possibilities when working with furniture. We can create new furniture, or use pre-made models from a library. The question is: when must we use each type? Some people say that using a pre-made model is not very professional thing but what they forget to say is that most projects have a tight deadline, and we need a quick modeling process to be ready on time. So, what's most important for professionals? Getting things done, or telling the client that all the models were created just for his project? Of course, the deadline is the most important, and your clients normally won't mind if you use pre-made models. Probably they won't even notice. So don't be ashamed to use pre-made models they won't make your projects any less professional. It's even recommended to use these models to speed-up the process, and allow you to spend more time on lighting or texturing. Is there any situation that demands the creation of a furniture model from scratch? Well, there are some. First, if you can't find the model in any library that you know, then it's going to be necessary to create it from scratch. If you are working with an architect who designs the spaces and furniture as well, you will probably have to model the furniture too, since it won't be available at any public library. Any project that deals with customized furniture will require that we work on the modeling for the furniture. Create your own libraryA good practice for anyone doing architectural visualization is to collect a lot of 3D models from public libraries for use in future projects. Keep these models for later, but don't forget to check if the author has released the models with no restrictions for commercial use. Otherwise, you must get their permission to use them. If you want to create your library, with no restrictions, why not create your own models? This could be a good exercise: take a few examples, and start creating some furniture. With time, you will have a good number of models. How to Get Started? In most cases, we have to get used to all that furniture modeling. We will have to start from scratch, with no blueprints available. The only references that we will have would be the photos, either provided by our clients, or provided from some web resources. If you have the time, visit a real store, and take some pictures and measures on your own. Sometimes, these stores will give you fliers and brochures, especially if you work with architecture. With time, you will get a lot of good reference material, and some of them come with measurements. But, if you don't know where to get started, let me point out some great web resources: http://www.e-interiors.net http://resources.blogoscopia.com http://blender-archi.tuxfamily.org/Models http://www.katorlegaz.com/ http://sketchup.google.com/3dwarehouse The first link has a lot of reference images classified by furniture type and designer. And sometimes, they even provide free 3D models. Most models there are saved in DXF, or 3DS file formats. Appending Models Before we start to model, let's see how we can import a model form an external library into Blender. The process is very simple, and what we have to do is to use the File menu, and access the Append or Link option. There is a shortcut for that too - just press SHIFT+F1 to call the same function. With this option, we have to select file that is already in the Blender file format. This option won't import files in other formats. When we select a file, a list of elements available in that particular file will be displayed, for us to select what we want to import. In most cases, the models will be stored under Object. When we click the Object option, all of the objects available in the file will be listed. If you know the name of the object that you want to import, just select the name, and click Load Library. The object will be loaded into our scene. Here, we have two options to handle this object: Append or Link: Append: If we choose this option, the object will be merged into ourcurrent scene. Link: With this option, an external link to the object file will be created. Any modifications to the original file will be reflected in our current scene. What is the best method to use? It will depend on whether we are willing to track all modifications applied to our furniture models. Using the Link method is a great way of keeping the furniture updated, because every modification at the original file is reflected immediately in the scene in which this model is placed. However, we will have to take the original file with the scene file every time we need to put our scene on another computer. They always have to go together. But if you choose to use the Append option, things will be a bit simpler, because the object will be incorporated into the scene file. We won't have to be worried about moving the furniture file along with the scene. Always use the Append option when you want to use furniture, or any other model, saved in another Blender file. To use a furniture model saved in another file, with a type other than “.blend”, we have to use the Import option. Importing Models To import a model, the process is very simple. We must use the File menu and select, Import. Then we have to select the proper file type from the list. The best file type, and the most common for furniture blocks, is the 3Ds file format, which belongs to the old 3D Studio application. There are some other good formats that work well with Blender, such as OBJ and LWO. The 3Ds file format can store lights, and it works well with Blender. The only thing we have to take extra care about is that most models imported come with triangular faces, which are a bit harder to edit. But, if you don't need to make any modifications to the model, this won't be a problem. Append or Import?Just to make things clearer, if you download a furniture model from a web site, and it's saved in the Blender native file format (.blend), you should append the model. If you download or get a furniture model on any file format other than “.blend”, you will have to import it. Since most models aren't saved in the Blender native file format, we can safely say that almost all furniture models that you find will require an import action to be placed in your scenes. Modeling a Chair Let's start with something simple, such as a chair. Even for a simple model, it will help us deal with smaller dimensions and details. Here is an image of the model: What's the main objective of this modeling? We have to create this chair, with the minimum use of faces and vertices. A good amount of detail can be left for textures, and it's always a good choice to use a lower number of vertices and faces in a model. If you consider one model, it won't matter much. But with a large number of chairs, such as in a theater room, it can make a difference in render time. Let's get started with a simple cube. Select this cube, and change the work mode to Edit. Select all vertices and press the W key. This will open the Specials menu. Choose subdivide, just once, from this menu. This will create new vertices and edges. Once these new vertices have been created, as shown in the image to the left, below, press the A key to remove all of the objects from the selection. Now, select the vertices to the right, using the B key. Remember to change the view mode to Wireframe before using the B key, otherwise, we won't be able to select the vertices behind the visible faces. When these vertices are selected, press the X key and choose Vertices to erase only the selected vertices. Using the CTRL+R key, add a new edge loop to the model, as shown in the following image: The next step is to change the scale of our model. Rotate the view to see the model in perspective view. Select all objects and press the S key, immediately after pressing the Z key. This will make the scale work only in the Z axis. Now, select the vertices identified in the following image and erase them using the X key. Change the selection mode to Edges, and select the edges identified in the following image. With the edges selected, press the E key to extrude them. With the new faces created, we can now add some detail to the model. Select only the top edge of the previously created faces. Move this edge down just a bit. This will add a small declivity to the seat. Now, we can move on to the next extrude, which must be from the selected edges identified in the following image. I'm not using any kind of measure for this example, but if you like to work only with real measurements, remember to hold the CTRL key every time a new extrude or edge is moved. This way, all transformations will use the grid lines. For this model, I'm not using vertex snap. With the new faces created, select just the two edges identified in the following image. Extrude these edges until they reach the other side of the base model. Hold the CTRL key, while you extrude them, to help with the precision. If you already want to remove duplicated vertices, select all objects, and press the W key. Choose Remove doubles to erase any duplicated vertices. Select the edges identified in the image to keep adding more parts to the chair. Extrude the edges three times until you have the same structure showed here. Now, we have to close the top with a face. To do that, we must select all four vertices on the top. When the vertices are selected, press the F key to create a new face. The next step is to select the small side edges to create some detail. Select just one edge, beginning from bottom to top, and move it just a bit. Repeat this operation with the other edges until we get the edges positioned as in the following image. The basic shape of our chair has now been created. Now, we can make some adjustments for improving the overall proportions. Select all edges or vertices on the left side, and move them a bit to the left. This will make the model wider. Did you notice that we have modeled only half a chair? Now we can make the other half, using the Mirror modifier. Add the modifier, and choose the right axis to make a perfect copy. If the center point for the model has been moved, you might need to edit the model to create a perfect mirrored match. Don't worry if you have moved the model by accident - this can happen sometimes. Along with the Mirror modifier, add a Subsurf modifier, too. With the Subsurf modifier, we realize that this model needs a new edge loop on the left side. Just press CTRL+R, and add a new loop, as in the following image.
Read more
  • 0
  • 0
  • 9612

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-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

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-developing-simple-workflow-within-sugarcrm
Packt
22 Oct 2009
4 min read
Save for later

Developing a Simple Workflow within SugarCRM

Packt
22 Oct 2009
4 min read
A Very Simple Workflow In our simple workflow we'll assume that each task is carried out by one person at a time, and that all tasks are done sequentially (i.e. none are done in parallel). So, we'll look at the PPI Preliminary Investigation which, as you remember, maps to the standard SugarCRM Opportunity. Also, in this example, we're going to have a different person carrying out each one of the Investigation stages. Setting up the Process Stages If you look at SugarCRM then you'll see that by default none of the stages are related to investigations—they're all named using standard CRM terms: Obviously the first thing to do is to decide what the preliminary investigation stages actually are, and then map these to the SugarCRM stages. You'll realize that you'll need to edit the custom/include/langauge/en_us.lang.php file: $app_list_strings['sales_stage_dom']=array ( 'Prospecting' => 'Fact Gathering', 'Qualification' => 'Witness and Subject Location', 'Needs Analysis' => 'Witness and Subject Interviews', 'Value Proposition' => 'Scene Investigation', 'Id. Decision Makers' => 'Financial and background Investigation', 'Perception Analysis' => 'Document and evidence retrieval', 'Proposal/Price Quote' => 'Covert Camera surveillance', 'Negotiation/Review' => 'Wiretapping', 'Closed Won' => 'Full Investigation required', 'Closed Lost' => 'Insufficient Evidence',); Don't forget that you can also do this via Studio. However, once you've added your mapping into custom/include/langauge/en_us.lang.php file, and refresh your browser, then you'll see the new stages: Now that our stages are set up we need to know who'll be carrying out each one. Deciding Who Does What In our simple workflow there may not be the need to do anything further. Each person just needs to know who does what next: For example, once Kurt finishes the 'Covert Camera surveillance' stage then he just needs to update the Preliminary Investigation so that the stage is set to 'Wiretapping' and the assigned user as 'dobbsm'. However, things are rarely as simple as that. It's much more likely that: Investigations may be based on geographical locations, so that the above table may only apply to investigations based in London. Investigations based in New York follow the same process but with a different set of staff. On Mondays Fran does 'Witness and Subject Location' and William does 'Fact Gathering'. This means, of course, that we need to be using some businesses rules. Introducing Business Rules There are six 'triggers' that will cause the logic hooks to fire: after_retrieve before_save before_delete after_delete before_undelete after_undelete And the logic hooks are stored in custom/modules/<module name>/logic_hook.php, so for 'Preliminary Inquiries' this will be custom/modules/Opportunities/logic_hook.php. You'll also remember, of course, that the logic hook file needs to contain: The priority of the business rule The name of the businesses rule The file containing the business rule The business rule class The business rule function So, custom/modules/Opportunities/logic_hook.php needs to contain something like: <?php#As always ensure that the file can only be accessed through SugarCRMif(!defined('sugarEntry') || !sugarEntry) die( 'Not A Valid Entry Point');$hook_array = Array(); #Create an array$hook_array['before_save'] = Array();$hook_array['before_save'][] = Array(1, 'ppi_workflow', 'custom/include/ppi_workflow.php', 'ppi_workflow', 'ppi_workflow');?> Next we'll need the file that logic hook will be calling, but to start with this can be very basic—so, custom/include/ppi_workflow.php just needs to contain something like: <?php#Define the entry pointif(!defined('sugarEntry') || !sugarEntry) die( 'Not A Valid Entry Point');#Load any required filesrequire_once('data/SugarBean.php');require_once('modules/Opportunities/Opportunity.php');#Define the classclass ppi_workflow{ function ppi_workflow (&$bean, $event, $arguments) { }}?> With those two files set up as above nothing obvious will change in the operation of SugarCRM—the logic hook will fire, but we haven't told it to do anything, and so that what we'll do now. When the logic hook does run (i.e. when any Primary Investigation is saved) we would want it to: Check to see what stage we're now at Define the assigned user accordingly  
Read more
  • 0
  • 0
  • 4067
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 €18.99/month. Cancel anytime
article-image-textures-blender
Packt
22 Oct 2009
10 min read
Save for later

Textures in Blender

Packt
22 Oct 2009
10 min read
Procedural Textures vs. Bitmap Textures Blender has basically two types of textures, which are procedural textures and bitmap textures. Each one has both positive and negative points. Which one is the best will depend on your project needs. Procedural: This kind of texture is generated by the software at rendering time, just like vector lines. This means that it won't depend on any type of image file. The best thing about this type of texture is that it is resolution independent, so we can set the texture to be rendered with high resolutions with minimum loss of quality. The negative point about this kind of texture is that it's harder to get realistic textures with it. Bitmap: To use this kind of texture, we will need an image file, such as a JPEG, PNG, or TGA file. The good thing about these textures is that we can achieve very realistic materials with it quickly. On the other hand, we must find the texture file before using it. And there is more. If you are creating a high resolution render, the texture file must be big. Texture Library Do you remember the way we organized materials? We can do exactly the same thing about textures. Besides setting names and storing the Blender files to import and use again later, collecting bitmap textures is another important point. Even if you don't start right away, it's important to know where to look for textures. So here is a small list of websites that provides free texture download. http://www.blender-textures.org http://www.cgtextures.com http://blender-archi.tuxfamily.org/textures Applying Textures To use a texture, we must apply a material to an object, and then use the texture with this material. We always use the texture inside a material. For instance, to make a plane that simulates a marble floor, we have to use a texture and set up how the surface will react to light and texture, which can give the surface a proper look of marble using any texture. To do that, we must use the texture panel, which is located right next to the materials button. We can use a keyboard shortcut to open this panel: just hit F6. There is a way to add a texture in the material panel as well, with a menu called Texture. The best way to get all the options is to add the texture on the texture panel. On this panel, we will be able to see a lot of buttons, which represent the texture channels. Each one of these channels can hold a texture. The final texture will be a mix of all the channels. If we have a texture at channel 1 and another texture at channel 2, these textures will be blended and represented in the material. Before adding a new texture, we must select a channel by clicking over one of them. Usually the first channel is selected, but if you want to use another one, just click on the channel. When the channel is selected, just click the Add New button to add a new texture. The texture controls are very similar to the material controls. We can set a name for the texture at the top, or erase it if we don't want it anymore. With the selector, we can choose a previously created texture too—just click and select. Now comes the fun part. Having added a texture, we have to choose a texture type. To do that, we click on the texture type combo box. There are a lot of textures, but most of them are procedural textures and we won't use them much. The only texture type that isn't procedural is the image type. We can use textures like Clouds and Wood to create some effects and give surfaces a more complex look, or even create a grass texture with some dirt on it. But most times, the texture type that we will be using will be the Image type. Each texture has its own set of parameters to determine how it will look in the object. If we add a Wood texture, it will show the configuration parameters at the right. If we choose as texture type Clouds, the parameters showed at the right will be completely different. With the image texture type it's not different, this kind of texture has its own type of setup. This is the control panel: To show how to set up a texture, let's use an image file that represents a wood floor and a plane. We can apply the texture to this plane and set up how it's going to look, testing all the parameters. The first thing to do is assign a material to the plane, and add a texture to this material. We choose as texture type the Image option. It will show the configuration options for this kind of texture. To apply the image as a texture to the plane, just click on the Load button, situated on the Image menu. When we hit this button, we will be able to select the image file. Locate the image file and the texture will be applied. If we want to have more control over how this texture is organized and placed on the plane, we need to learn how the controls work. Every time you make any changes to the setup of a texture, these changes will be shown in the preview window; use it a lot to make good changes. Here is a list of what some of the buttons can do for the texture: UseAlpha: If the texture has an alpha channel, we have to press this button for Blender calculate the channel. An image has an alpha channel when some kind of transparency is stored in the image. For instance, a .png file with transparent background has an alpha channel. We can use this to create a texture with a logo, for a bottle, or to add an image of a tree or person to a plane. Rot90: With this option we can rotate the texture by 90 degrees. Repeat: Every texture must be distributed on the object surface, and repeating the texture in lines and columns is the default way to do that. Extended: If this button is pressed, the texture will be adjusted to fit all the object surface area. Clip: With this option, the texture will be cropped and we will be able to show only a part of it. To adjust which parts of the texture will be displayed, use the Min/Max X/Y options. Xrepeat / Yrepeat: This option determines how many times a texture is repeated, with the repeat option turned on. Normal Map: If the texture will be used to create Normal Maps, press this button. These are textures used to change the face normals of an object. Still: With this button selected, we can determine that the image used as texture is a still image. This option is marked by default. Movie: If you have to use a movie file as texture, press this button. This is very useful if we need to make something like a theatre projection screen or a tv screen. Sequence: We can use a sequence of images as texture too; just press this button. It works the same ways as with a movie file. There are a few more parameters, like the Reload button. If your texture file suffers any kind of change, we must press this button for the changes get accepted by Blender. The X button can erase this texture; use it if you need to select another image file. When we add a texture to any material, an external link is created with this file. This link can be absolute or relative. When we add a texture called "wood.png", which is located at the root of your main hard disk, like C:, a link to this texture will be created like this: "c:wood.png", so every time you open this file, the software will look for that file at that exact place. This is an absolute link, but we can use a relative link as well. For instance, when we add a texture located in the same folder as our scene, a relative link will be created. Every time we use an absolute link and we have to move the ".blend" file to another computer, the texture file must go with it. To imbue the image file with the .blend, just press the icon of gift package. To save all the textures used in a scene, just access the file menu and use the Pack Data option. It will make all the texture files embedded with the source blend file. Mapping Every time we add a texture to any object, we must choose a mapping type to set up how the texture will be applied to the object. For instance, if we have a wall and apply a wood texture, it must be placed like wallpaper. But for cylindrical or spherical objects, or even walls, we have to set up in a way that makes the texture adaptable to the topology of the surface, to avoid effects such as a stretched texture. To set this up, we use the mapping options, which are located on the Map Input menu. On this menu, we can choose between four basic mapping types which are Cube, Sphere, Flat, and Tube. If you have a wall, choose the option that matches the topology type with the model. In this case, the best choice is the Cube. Another important option here is the UV button, which allows us to use another very powerful type of texturing, based on UV Mapping. Normal Map This is a special and useful type of texture, that can change the normals of surfaces. If we have a floor and a texture of ceramic tiles, the surface can be represented with smaller details of that tiling, using this kind of a map. It's almost like modeling the tiles. But everything is created using just a normal map. To use this kind of texture, we must turn on the Nor button on the Map To menu. When this button is turned on, we can set up the Nor slider to determine the intensity of the normal displacement. It works based on the pixel color of the texture. With white pixels, the normals are not affected, and with black pixels, the normals are fully translated. If you want to optimize the normal mapping, using a special texture is much recommended. Some texture libraries even have this type of normal maps ready for use. They can be called bump maps too. Here is an example of how we can use them. We take a stone texture and a tiled texture with a white background and black lines. The stone texture is applied to the floor, and the tiled texture is used to create a tiling for the floor. The setup for that is really simple. Just apply the texture at a lower channel, and turn off the Col button for this channel. Turn on the Nor button, and this texture will affect only the normals and not the material color. Any image can be used as a normal map, but we will always get better results with a greyscale image prepared to be used as a normal map. Now, just set up the Nor intensity with the slider, and see the render. Turn on positive and turn on negativeSome of the buttons on the Map To menu can be turned on with positive and negative values. For instance, the Nor option can be turned on with one click. If we click on it again, the Nor text will turn yellow. This means that the Nor is inverted with negative values. Some other buttons may present the same option.
Read more
  • 0
  • 0
  • 26810

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-soap-and-php-5
Packt
22 Oct 2009
16 min read
Save for later

SOAP and PHP 5

Packt
22 Oct 2009
16 min read
SOAP SOAP, formerly known as Simple Object Access Protocol (until the acronym was dropped in version 1.2), came around shortly after XML-RPC was released. It was created by a group of developers with backing from Microsoft. Interestingly, the creator of XML-RPC, David Winer, was also one of the primary contributors to SOAP. Winer released XML-RPC before SOAP, when it became apparent to him that though SOAP was still a way away from being completed, there was an immediate need for some sort of web service protocol. Like XML-RPC, SOAP is an XML-based web service protocol. SOAP, however, satisfies a lot of the shortcomings of XML-RPC: namely the lack of user-defined data types, better character set support, and rudimentary security. It is quite simply, a more powerful and flexible protocol than REST or XML-RPC. Unfortunately, sacrifices come with that power. SOAP is a much more complex and rigid protocol. For example, even though SOAP can stand alone, it is much more useful when you use another XML-based standard, called Web Services Descriptor Language (WSDL), in conjunction with it. Therefore, in order to be proficient with SOAP, you should also be proficient with WSDL. The most-levied criticism of SOAP is that it is overly complex. Indeed, SOAP is not simple. It is long and verbose. You need to know how namespaces work in XML. SOAP can rely heavily on other standards. This is true for most implementations of SOAP, including Microsoft Live Search, which we will be looking at. The most common external specifications used by a SOAP-based service is WSDL to describe its available services, and that, in turn, usually relies on XML Schema Data (XSD) to describe its data types. In order to "know" SOAP, it would be extremely useful to have some knowledge of WSDL and XSD. This will allow one to figure out how to use the majority of SOAP services. We are going to take a "need to know" approach when looking at SOAP. Microsoft Live Search's SOAP API uses WSDL and XSD, so we will take a look at SOAP with the other two in mind. We will limit our discussion on how to gather information about the web service that you, as a web service consumer, would need and how to write SOAP requests using PHP 5 against it. Even though this article will just introduce you to the core necessities of SOAP, there is a lot of information and detail. SOAP is very meticulous and you have to keep track of a fair amount of things. Do not be discouraged, take notes if you have to, and be patient. All three, SOAP, WSD, and XSD are maintained by the W3C. All three specifications are available for your perusal. The official SOAP specification is located at http://www.w3.org/TR/soap/. WSDL specification is located at http://www.w3.org/TR/wsdl. Finally, the recommended XSD specification can be found at http://www.w3.org/XML/Schema. Web Services Descriptor Language (WSDL) With XML Schema Data (XSD) Out of all the drawbacks of XML-RPC and REST, there is one that is prominent. Both of these protocols rely heavily on good documentation by the service provider in order to use them. Lacking this, you really do not know what operations are available to you, what parameters you need to pass in order to use them, and what you should expect to get back. Even worse, an XML-RPC or REST service may be poorly or inaccurately documented and give you inaccurate or unexpected results. SOAP addresses this by relying on another XML standard called WSDL to set the rules on which web service methods are available, how parameters should be passed, and what data type might be returned. A service's WSDL document, basically, is an XML version of the documentation. If a SOAP-based service is bound to a WSDL document, and most of them are, requests and responses must adhere to the rules set in the WSDL document, otherwise a fault will occur. WSDL is an acronym for a technical language. When referring to a specific web service's WSDL document, people commonly refer to the document as "the WSDL" even though that is grammatically incorrect. Being XML-based, this allows clients to automatically discover everything about the functionality of the web service. Human-readable documentation is technically not required for a SOAP service that uses a WSDL document, though it is still highly recommended. Let's take a look at the structure of a WSDL document and how we can use it to figure out what is available to us in a SOAP-based web service. Out of all three specifications that we're going to look at in relationship to SOAP, WSDL is the most ethereal. Both supporters and detractors often call writing WSDL documents a black art. As we go through this, I will stress the main points and just briefly note other uses or exceptions. Basic WSDL Structure Beginning with a root definitions element, WSDL documents follow this basic structure:     <definitions>        <types>        …        </types>        <message>        …        </message>        <portType>        …        </portType>        <binding>        …        </binding>    </definitions> As you can see, in addition to the definitions element, there are four main sections to a WSDL document: types, message, portType, and binding. Let's take a look at these in further detail. Google used to provide a SOAP service for their web search engine. However, this service is now deprecated, and no new developer API keys are given out. This is unfortunate because the service was simple enough to learn SOAP quickly, but complex enough to get a thorough exposure to SOAP. Luckily, the service itself is still working and the WSDL is still available. As we go through WSDL elements, we will look at the Google SOAP Search WSDL and Microsoft Live Search API WSDL documents for examples. These are available at http://api.google.com/GoogleSearch.wsdl and http://soap.search.msn.com/webservices.asmx?wsdl respectively. definitions Element This is the root element of a WSDL document. If the WSDL relies on other specifications, their namespace declarations would be made here. Let's take a look at Google's WSDL's definition tag:     <definitions name="GoogleSearch"        targetNamespace="urn:GoogleSearch"                                                > The more common ones you'll run across are xsd for schema namespace, wsdl for the WSDL framework itself, and soap and soapenc for SOAP bindings. As these namespaces refer to W3C standards, you will run across them regardless of the web service implementation. Note that some searches use an equally common prefix, xs, for XML Schema. tns is another common namespace. It means "this namespace" and is a convention used to refer to the WSDL itself. types Element In a WSDL document, data types used by requests and responses need to be explicitly declared and defined. The textbook answer that you'll find is that the types element is where this is done. In theory, this is true. In practice, this is mostly true. The types element is used only for special data types. To achieve platform neutrality, WSDL defaults to, and most implementations use, XSD to describe its data types. In XSD, many basic data types are already included and do not need to be declared. Common Built-in XSD Data Types Time Date Boolean String Base64Binary Float Double Integer Byte For a complete list, see the recommendation on XSD data types at http://www.w3.org/TR/xmlschema-2/. If the web service utilizes nothing more than these built-in data types, there is no need to have special data types, and thus, types will be empty. So, the data types will just be referred to later, when we define the parameters. There are three occasions where data types would be defined here: If you want a special data type that is based on a built-in data type. Most commonly this is a built-in, whose value is restricted in some way. These are known as simple types. If the data type is an object, it is known as a complex type in XSD, and must be declared. An array, which can be described as a hybrid of the former two. Let's take a look at some examples of what we will encounter in the types element. Simple Type Sometimes, you need to restrict or refine a value of a built-in data type. For example, in a hospital's patient database, it would be ludicrous to have the length of a field called Age to be more than three digits. To add such a restriction in the SOAP world, you would have to define Age here in the types section as a new type. Simple types must be based on an existing built-in type. They cannot have children or properties like complex types. Generally, a simple type is defined with the simpleType element, the name as an attribute, followed by the restriction or definition. If the simple type is a restriction, the built-in data type that it is based on, is defined in the base attribute of the restriction element. For example, a restriction for an age can look like this:     <xsd:simpleType name="Age">        <xsd:restriction base="xsd:integer">            <xsd:totalDigits value="3" />        </xsd:restriction>    </xsd:simpleType> Children elements of restriction define what is acceptable for the value. totalDigits is used to restrict a value based on the character length. A table of common restrictions follows: Restriction Use Applicable In enumeration Specifies a list of acceptable values. All except boolean fractionDigits Defines the number of decimal places allowed. Integers length Defines the exact number of characters allowed. Strings and all binaries maxExclusive/ maxInclusive Defines the maximum value allowed. If Exclusive is used, value cannot be equal to the definition. If Inclusive, can be equal to, but not greater than, this definition. All numeric and dates minLength/ maxLength Defines the minimum and maximum number of characters or list items allowed. Strings and all binaries minExclusive/ minInclusive Defines the minimum value allowed. If Exclusive is used, value cannot be equal to the definition. If Inclusive, can be equal to, but not less than, this definition. All numeric and dates pattern A regular expression defining the allowed values. All totalDigits Defines the maximum number of digits allowed. Integers whiteSpace Defines how tabs, spaces, and line breaks are handled. Can be preserve (no changes), replace (tabs and line breaks are converted to spaces) or collapse (multiple spaces, tabs, and line breaks are converted to one space. Strings and all binaries A practical example of a restriction can be found in the MSN Search Web Service WSDL. Look at the section that defines SafeSearchOptions.     <xsd:simpleType name="SafeSearchOptions">        <xsd:restriction base="xsd:string">            <xsd:enumeration value="Moderate" />            <xsd:enumeration value="Strict" />            <xsd:enumeration value="Off" />    </xsd:restriction> </xsd:simpleType> In this example, the SafeSearchOptions data type is based on a string data type. Unlike a regular string, however, the value that SafeSearchOptions takes is restricted by the restriction element. In this case, the several enumeration elements that follow. SafeSearchOptions can only be what is given in this enumeration list. That is, SafeSearchOptions can only have a value of "Moderate", "Strict", or "Off". Restrictions are not the only reason to use a simple type. There can also be two other elements in place of restrictions. The first is a list. If an element is a list, it means that the value passed to it is a list of space-separated values. A list is defined with the list element followed by an attribute named itemType, which defines the allowed data type. For example, this example specifies an attribute named listOfValues, which comprises all integers.     <xsd:simpleType name="listOfValues">        <xsd:list itemType="xsd:integer" />    </xsd:simpleType> The second is a union. Unions are basically a combination of two or more restrictions. This gives you a greater ability to fine-tune the allowed value. Back to our age example, if our service was for a hospital's pediatrics ward that admits only those under 18 years old, we can restrict the value with a union.     <xsd:simpleType name="Age">        <xsd:union>            <xsd:simpleType>                <xsd:restriction base="decimal">                        <xsd:minInclusive value="0" />                </xsd:restriction>            </xsd:simpleType>            <xsd:simpleType>                <xsd:restriction base="decimal">                        <xsd:maxExclusive value="18" />                </xsd:restriction>            </xsd:simpleType>        </xsd:union>    </xsd:simpleType> Finally, it is important to note that while simple types are, especially in the case of WSDLs, used mainly in the definition of elements, they can be used anywhere that requires the definition of a number. For example, you may sometimes see an attribute being defined and a simple type structure being used to restrict the value. Complex Type Generically, a complex type is anything that can have multiple elements or attributes. This is opposed to a simple type, which can have only one element. A complex type is represented by the element complexType in the WSDL. The most common use for complex types is as a carrier for objects in SOAP transactions. In other words, to pass an object to a SOAP service, it needs to be serialized into an XSD complex type in the message. The purpose of a complexType element is to explicitly define what other data types make up the complex type. Let's take a look at a piece of Google's WSDL for an example:     <xsd:complexType name="ResultElement">        <xsd:all>            <xsd:element name="summary" type="xsd:string"/>            <xsd:element name="URL" type="xsd:string"/>            <xsd:element name="snippet" type="xsd:string"/>            <xsd:element name="title" type="xsd:string"/>            <xsd:element name="cachedSize" type="xsd:string"/>            <xsd:element name=                        "relatedInformationPresent" type="xsd:boolean"/>            <xsd:element name="hostName" type="xsd:string"/>            <xsd:element name=                        "directoryCategory" type="typens:DirectoryCategory"/>            <xsd:element name="directoryTitle" type="xsd:string"/>        </xsd:all>    </xsd:complexType> First thing to notice is how the xsd: namespace is used throughout types. This denotes that these elements and attributes are part of the XSD specification. In this example, a data type called ResultElement is defined. We don't exactly know what it is used for right now, but we know that it exists. An element tag denotes complex type's equivalent to an object property. The first property of it is summary, and the type attribute tells us that it is a string, as are most properties of ResultElement. One exception is relatedInformationPresent, which is a Boolean. Another exception is directoryCategory. This has a data type of DirectoryCategory. The namespace used in the type attribute is typens. This tells us that it is not an XSD data type. To find out what it is, we'll have to look for the namespace declaration that declared typens.
Read more
  • 0
  • 0
  • 5329

article-image-aggregate-services-servicemix-jbi-esb
Packt
22 Oct 2009
10 min read
Save for later

Aggregate Services in ServiceMix JBI ESB

Packt
22 Oct 2009
10 min read
EAI - The Broader Perspective No one should have (or will) ever dared to build a 'Single System' which will take care of the entire business requirements of an enterprise. Instead, we build few (or many) systems,and each of them takes care of a set of functionalities in a single Line of Business (LOB). There is absolutely nothing wrong here, but the need of the hour is that these systems have to exchange information and interoperate in many new ways which have not been foreseen earlier. Business grows, enterprise boundaries expands and mergers and acquisition are all norms of the day. If IT cannot scale up with these volatile environments, the failure is not far. Let me take a single, but not simple problem that today's Businesses and IT face - Duplicate Data. By Duplicate Data we mean data related to a single entity stored in multiple systems and storage mechanisms, that too in multiple formats and multiple content. I will take the 'Customer' entity as an example so that I can borrow the 'Single Customer View' (SCV) jargon to explain the problem. We gather customer information while he makes a web order entry or when he raises a complaint against the product or service purchased or when we raise a marketing campaign for a new product to be introduced or ... The list continues, and in each of these scenarios we make use of different systems to collect and store the same customer information. 'Same Customer' - is it same? Who can answer this question? Is there a Data Steward who can provide you with the SCV from amongst the many information silos existing in your Organization? To rephrase the question, does your organization at least have a 'Single View of Truth', if it doesn't have a 'Single Source of Truth'? Information locked away inside disparate, monolithic application silos has proven a stubborn obstacle in answering the queries business requires, impeding the opportunities of selling, not to mention cross-selling and up-selling. Yeah, it's time to cleanse and distill each customer's data into a single best-record view that can be used to improve source system data quality. For that, first we need to integrate the many source systems available. Today, companies are even acquiring just to get access to it's invaluable Customer information! This is just one of the highlights of the importance of integration to control Information Entropy in the otherwise complicated IT landscape. Figure 1. The 'Single Customer View' Dilemma So Integration is not an end, but a means to end a full list of problems faced by enterprises today. We have been doing integration for many years. There exist many platforms, technologies and frameworks doing the same thing. Built around that, we have multiple Integration Architectures too, amongst which, the Point to Pont, Hub and Spoke, and the Message Bus are common. Figure 2 represents these integration topologies. Figure 2. EAI Topologies Let us now look at the salient features of these topologies to see if we are self-sufficient or need something more. Point to Point In Point to Point, we define integration solutions for a pair of applications. Thus, we have two end points to be integrated. We can build protocol and/or format adaptors/transformers at one or either end. This is the easiest way to integrate, as long as the volume of integration is low. We normally use technology specific APIs like FTP, IIOP, Remoting or batch interfaces to realize integration. The advantage is that between these two points, we have tight coupling, since both ends have knowledge about their peers. The downside is that if there are 6 nodes (systems) to be interconnected, we need at least 30 separate channels for both forward and reverse transport. So think of a mid-sized Enterprise with some 1000 systems to integrate! Hub & Spoke Hub And Spoke Architecture is also called as the Message Broker. It provides a centralized hub (Broker) to which all applications are connected. Each application connects with the central hub through lightweight connectors. The lightweight connectors facilitate application integration with minimum or no changes to the existing applications. Message Transformation and Routing takes place within the Hub. The major drawback of the Hub and Spoke Architecture is that if the Hub fails, the entire Integration topology fails. Enterprise Message Bus An Enterprise Message Bus provides a common communication infrastructure which acts as a platform-neutral and language-neutral adaptor between applications. This communication infrastructure may include a Message Router and/or Publish-Subscribe channels. So applications interact each other through the message bus with the help of Request-Response queues. Sometimes the applications have to use adapters that handle scenarios like invoking CICS transactions. Such adapters may provide connectivity between the applications and the message bus using proprietary bus APIs and application APIs. Service Oriented Integration (SOI) Service Oriented Architecture (SOA) provides us with a set of principles, patterns and practices, to provide and consume services which are orchestrated using open standards so as to remove single vendor lock-into provide an agile infrastructure where services range from business definition to technical implementation. In SOA, we no longer deal with single format and single protocol, instead we accept the fact that heterogeneity exists between applications. And our architecture still needs to ensure interoperability and thus information exchange. To help us do integration in the SOA manner, we require a pluggable service infrastructure where providers, consumers, and middleware services can collaborate in the famous 'Publish -- Find -- Bind' triangle. So, similar to the integration topologies described above, we need a backbone upon which we can build SOA that can provide a collection of middleware services that provides integration capabilities. This is what we mean by Service Oriented Integration (SOI). Gartner originally identified Enterprise Service Bus (ESB) Architecture as a core component in the SOA landscape. ESB provides a technical framework to align your SOA based integration needs. In the rest of the article we will concentrate on ESB. Enterprise Service Bus (ESB) Roy Schutle from Gartner defines an ESB as:"A Web-services-capable middleware infrastructure that supports intelligent program-to-program communication and mediates the relationships among loosely-coupled and uncoupled business components." In the ESB Architecture (Refer Figure 2), applications communicate through an SOA middleware backbone. The most distinguishing feature of the ESB Architecture is the distributed nature of the integration topology. This makes the ESB capabilities to spread out across the bus in a distributed fashion, thus avoiding any single point of failure. Scalability is achieved by distributing the capabilities into separately deployable service containers. Smart, intelligent connectors connect the applications to the Bus. Technical services like transformation, routing, security, etc. are provided internally by these connectors. The Bus federates services which are hosted locally or remotely, thus collaborating distributed capabilities. Many ESB solutions are based on Web Services Description Language (WSDL) technologies, and they use Extensible Markup Language (XML) formats for message translation and transformation. The best way to think about an ESB is to imagine the many features which we can provide to the message exchange at a mediation layer (the ESB layer), a few among them is listed below: Addressing & Routing  Synchronous and Asynchronous style invocations  Multiple Transport and protocol bindings  Content transformation and translation  Business Process Orchestration (BPM)  Event processing  Adapters to multiple platforms  etc... Service Aggregation in ESB ESB provides you the best ways of integrating services so that services are not only interoperable but also reusable in the form of aggregating in multiple ways and scenarios. This means, services can be mixed and matched to adapt to multiple protocols and consumer requirements. Let me explain you this concept, as we will explore more into this with the help of sample code too. In code and component reuse, we try to reduce ‘copy and paste’ reuse and encourage inheritance, composition and instance pooling. Similar analogy exists in SOI where services are hosted and pooled for multiple clients through multiple transport channels, and ESB can do this in the best way integration world has ever seen. We call this as the notion of shared services. For example, if a financial organization provides a ‘credit history check service’, an ESB can facilitate reuse of this service by multiple business processes (like a Personal Loan approval process or a Home Mortgage approval process). So, once we create our 'core services', we can then arbitrarily compose these services in a declarative fashion so as to define and publish more and more composite services. Business Process Management (BPM) tools can be integrated over ESB to leverage service aggregation and service collaboration. This facilitates reuse of basic or core (or fine grained) services at Business Process level. So, granularity of services is important which will also decide the level of reusability. Coarse grained or composite services consume fine grained services. Applications that consume  coarse-grained services are not exposed to the fine-grained services they use. Composite services can be assembled from coarse-grained as well as fine-grained services. To make the concept clear, let us take the example of provisioning a new VOIP (Voice Over IP) Service for a new Customer. This is a composite service which in turn calls multiple coarse grained services like 'validateOrder', 'createOrVerifyCustomer', 'checkProductAvailability', etc. Now, the createOrVerifyCustomer coarse grained service in turn call multiple fine grained services like 'validateCustomer', 'createCustomer', 'createBillingAddress', 'createMailingAddress', etc. Figure 3. Service Composition Java Business Integration (JBI) Java Business Integration (JBI) provides a collaboration framework which provides standard interfaces for integration components and protocols to plug into, thus allowing the assembly of Service Oriented Integration (SOI) frameworks. JSR 208 is an extension of Java 2 Enterprise Edition (J2EE), but it is specific for Java Business Integration Service Provider Interfaces (SPI). SOA and SOI are the targets of JBI and hence it is built around Web Services Description Language (WSDL). The nerve of the JBI architecture is the NMR (Normalized Message Router). This is a bus through which messages flow in either directions from a source to a destination. You can listen to Ron Ten-Hove, the Co-spec lead for JSR 208 here and he writes more about JBI components in the PDF download titled JBI Components: Part 1. JBI provides the best available, open foundation for structuring applications by composition of services rather than modularized, structured code that we have been doing in traditional programming paradigms. A JBI compliant ESB implementation must support four different service invocations, leading to four corresponding Message Exchange Patterns (MEP):   One-Way (In-Only MEP): Service Consumer issues a request to Service Provider. No error (fault) path is provided.  Reliable One-Way (Robust In-Only MEP): Service Consumer issues a request to Service Provider. Provider may respond with a fault if it fails to process the request.  Request-Response (In-Out MEP): Service Consumer issues a request to Service Provider, with expectation of response. Provider may respond with a fault if it fails to process request.  Request Optional-Response (In Optional-Out MEP): Service Consumer issues a request to Service Provider, which may result in a response. Both Consumer and provider have the option of generating a fault in response to a message received during the interaction.
Read more
  • 0
  • 0
  • 4222
article-image-manual-generic-and-ordered-tests-using-visual-studio-2008
Packt
22 Oct 2009
6 min read
Save for later

Manual, Generic, and Ordered Tests using Visual Studio 2008

Packt
22 Oct 2009
6 min read
The following screenshot describes a simple web application, which has a page for the new user registration. The user has to provide the necessary field details. After entering the details, the user will click on the Register button provided in the web page to submit all the details so that it gets registered to the site. To confirm this to the user, the system will send a notification with a welcoming email to the registered user. The mail is sent to the email address provided by the user. In the application shown in the above screenshot, the entire registration process cannot be automated for testing. For example, the email verification and checking the confirmation email sent by the system will not be automated as the user has to go manually and check the email. This part of the manual testing process will be explained in detail in this article. Manual tests Manual testing, as described earlier, is the simplest type of testing carried out by the testers without any automation tool. This test may contain a single or multiple tests inside. Manual test type is the best choice to be selected when the test is too difficult or complex to automate, or if the budget allotted for the application is not sufficient for automation. Visual Studio 2008 supports two types of manual tests file types. One as text file and the other as Microsoft Word. Manual test using text format This format helps us to create the test in the text format within Visual Studio IDE. The predefined template is available in Visual Studio for authoring this test. This template provides the structure for creating the tests. This format has the extension of .mtx. Visual Studio servers act as an editor for this test format. For creating this test in Visual Studio, either create a new test project and then add the test or select the menu option Test | New Test... and then choose the option to add the test to a new project. Now create the test using the menu option and select Manual Test (Text Format) from the available list as shown in the screenshot below. You can see the list Add to Test Project drop–down, which lists the different options to add the test to a test project. If you have not yet created the test project and selected the option to create the test, the drop-down option selected will create a new test project for the test to be added. If you have a test project already created, then we can also see that project in the list to get this new test added to the project. We can choose any option as per our need. For this sample, let us create a new test project in C#. So the first option from the drop-down of Add to Test Project would be selected in this case. After selecting the option, provide the name for the new test project the system will ask for. Let us name it TestingAppTest project. Now you can see the project getting created under the solution and the test template is also added to the test project as shown next. The template contains the detailed information for each section. This will help the tester or whoever is writing the test case to write the steps required for this test. Now update the test case template created above with the test steps required for checking the email confirmation message after the registration process. The test document also contains the title for the test, description, and the revision history for the changes made to the test case. Before executing the test and looking into the details of the run and the properties of the test, we will create the same test using Microsoft Word format as described in the next section. Manual test using Microsoft Word format This is similar to the manual test that was created using text format, except that the file type is Microsoft Word with extension .mht. While creating the manual test choose the template Manual Test (Word format) instead of the Manual Test (Text Format) as explained in the previous section. This option is available only if Microsoft Word is installed in the system. This will launch the Word template using the MS Word installed (version 2003 or later) in the system for writing the test details as shown in the following screenshot. The Word format helps us to have richer formatting capabilities with different fonts, colors, and styles for the text with graphic images and tables embedded for the test. This document not only provides the template but also the help information for each and every section so that the tester can easily understand the sections and write the test cases. This help information is provided in both the Word and Text format of the manual tests. In the test document seen in previous screenshot, we can fill the Test Details, Test Target, Test Steps, and Revision History similar to the one we did for the text format. The completed test case test document will look like this: Save the test details and close the document. Now we have both formats of manual tests in the project. Open the Test View window or the Test List Editor window to see the list of tests we have in the project. It should list two manual tests with their names and the project to which the tests are associated with. The tests shown in the Test View window looks like the one shown here: The same tests list shown by the Test List Editor would look like the one shown below. The additional properties like test list name, the project name the test belongs to, is also shown in the list editor. There are options for each test either to run or get added to any particular list. Manual tests also have other properties, which we can make use of during testing. These properties can be seen in the Properties window, which can be opened by choosing the manual test either in the Test View or in the Test List Editor windows by right-clicking the test and selecting the Properties option. The same window can also be opened by choosing the menu option View | Properties window. Both formats of manual testing have the same set of properties. Some of these properties are editable while some are read-only, which will be set by the application based on the test type. Some properties are directly related to TFS. The VSTFS is the integrated collaboration server, which combines team portal, work item tracking, build management, process guidance, and version control into a unified server.
Read more
  • 0
  • 0
  • 3025

article-image-linq-objects
Packt
22 Oct 2009
10 min read
Save for later

LINQ to Objects

Packt
22 Oct 2009
10 min read
Without LINQ, we would have to go through the values one-by-one and then find the required details. However, using LINQ we can directly query collections and filter the required values without using any looping. LINQ provides powerful filtering, ordering, and grouping capabilities that requires minimum coding. For example, if we want to find out the types stored in an assembly and then filter the required details, we can use LINQ to query the assembly details using System.Reflection classes. The System.Reflection namespace contains types that retrieve information about assemblies, modules, members, parameters, and other entities as collections are managed code, by examining their metadata. Also, files under a directory are a collection of objects that can be queried using LINQ. We shall see some of the examples for querying some collections. Array of Integers The following example shows an integer array that contains a set of integers. We can apply the LINQ queries on the array to fetch the required values.     int[] integers = { 1, 6, 2, 27, 10, 33, 12, 8, 14, 5 };       IEnumerable<int> twoDigits =       from numbers in integers       where numbers >= 10       select numbers;       Console.WriteLine("Integers > 10:");       foreach (var number in twoDigits)       {          Console.WriteLine(number);       } The integers variable contains an array of integers with different values. The variable twoDigits, which is of type IEnumerable, holds the query. To get the actual result, the query has to be executed. The actual query execution happens when the query variable is iterated through the foreach loop by calling GetEnumerator() to enumerate the result. Any variable of type IEnumerable<T>, can be enumerated using the foreach construct. Types that support IEnumerable<T> or a derived interface such as the generic IQueryable<T>, are called queryable types. All collections such as list, dictionary and other classes are queryable. There are some non-generic IEnumerable collections like ArrayList that can also be queried using LINQ. For that, we have to explicitly declare the type of the range variable to the specific type of the objects in the collection, as it is explained in the examples later in this article. The twoDigits variable will hold the query to fetch the values that are greater than or equal to 10. This is used for fetching the numbers one-by-one from the array. The foreach loop will execute the query and then loop through the values retrieved from the integer array, and write it to the console. This is an easy way of getting the required values from the collection. If we want only the first four values from a collection, we can apply the Take() query operator on the collection object. Following is an example which takes the  first four integers from the collection. The four integers in the resultant collection are displayed using the foreach method.    IEnumerable<int> firstFourNumbers = integers.Take(4);   Console.WriteLine("First 4 numbers:");   foreach (var num in firstFourNumbers)   {      Console.WriteLine(num);   } The opposite of Take() operator is Skip() operator, which is used to skip the number of items in the collection and retrieve the rest. The following example skips the first four items in the list and retrieves the remaining.    IEnumerable<int> skipFirstFourNumbers = integers.Skip(4);   Console.WriteLine("Skip first 4 numbers:");   foreach (var num in skipFirstFourNumbers)   {      Console.WriteLine(num);   } This example shows the way to take or skip the specified number of items from the collection. So what if we want to skip or take the items until we find a match in the list? We have operators to get this. They are TakeWhile() and SkipWhile(). For example, the following code shows how to get the list of numbers from the integers collection until 50 is found. TakeWhile() uses an expression to include the elements in the collection as long as the condition is true and it ignores the other elements in the list. This expression represents the condition to test the elements in the collection for the match.    int[] integers = { 1, 9, 5, 3, 7, 2, 11, 23, 50, 41, 6, 8 };   IEnmerable<int> takeWhileNumber = integers.TakeWhile(num =>      num.CompareTo(50) != 0);   Console.WriteLine("Take while number equals 50");   foreach (int num in takeWhileNumber)      {         Console.WriteLine(num.ToString());      } Similarly, we can skip the items in the collection using SkipWhile(). It uses an expression to bypass the elements in the collection as long as the condition is true. This expression is used to evaluate the condition for each element in the list. The output of the expression is boolean. If the expression returns false, the remaining elements in the collections are returned and the expression will not be executed for the other elements. The first occurrence of the return value as false will stop the expression for the other elements and returns the remaining elements. These operators will provide better results if used against ordered lists as the expression is ignored for the other elements once the first match is found.    IEnumerable<int> skipWhileNumber = integers.SkipWhile(num =>      num.CompareTo(50) != 0);   Console.WriteLine("Skip while number equals 50");   foreach (int num in skipWhileNumber)   {      Console.WriteLine(num.ToString());   } Collection of Objects In this section we will see how we can query a custom built objects collection. Let us take the Icecream object, and build the collection, then we can query the collection. This Icecream class in the following code contains different properties such as Name, Ingredients, TotalFat, and Cholesterol.     public class Icecream    {        public string Name { get; set; }        public string Ingredients { get; set; }        public string TotalFat { get; set; }        public string Cholesterol { get; set; }        public string TotalCarbohydrates { get; set; }        public string Protein { get; set; }        public double Price { get; set; }     } Now build the Icecreams list collection using the class defined perviously.     List<Icecream> icecreamsList = new List<Icecream>        {            new Icecream {Name="Chocolate Fudge Icecream", Ingredients="cream,                milk, mono and diglycerides...", Cholesterol="50mg",                Protein="4g", TotalCarbohydrates="35g", TotalFat="20g",                Price=10.5        },        new Icecream {Name="Vanilla Icecream", Ingredients="vanilla extract,            guar gum, cream...", Cholesterol="65mg", Protein="4g",            TotalCarbohydrates="26g", TotalFat="16g", Price=9.80 },            new Icecream {Name="Banana Split Icecream", Ingredients="Banana, guar            gum, cream...", Cholesterol="58mg", Protein="6g",            TotalCarbohydrates="24g", TotalFat="13g", Price=7.5 }        }; We have icecreamsList collection which contains three objects with values of the Icecream type. Now let us say we have to retrieve all the ice-creams that cost less. We can use a looping method, where we have to look at the price value of each object in the list one-by-one and then retrieve the objects that have less value for the Price property. Using LINQ, we can avoid looping through all the objects and its properties to find the required ones. We can use LINQ queries to find this out easily. Following is a query that fetches the ice-creams with low prices from the collection. The query uses the where condition, to do this. This is similar to relational database queries. The query gets executed when the variable of type IEnumerable is enumerated when referred to in the foreach loop.     List<Icecream> Icecreams = CreateIcecreamsList();    IEnumerable<Icecream> IcecreamsWithLessPrice =    from ice in Icecreams    where ice.Price < 10    select ice;    Console.WriteLine("Ice Creams with price less than 10:");    foreach (Icecream ice in IcecreamsWithLessPrice)    {        Console.WriteLine("{0} is {1}", ice.Name, ice.Price);     } As we used List<Icecream> objects, we can also use ArrayList to hold the objects, and a LINQ query can be used to retrieve the specific objects from the collection according to our need. For example, following is the code to add the same Icecreams objects to the ArrayList, as we did in the previous example.     ArrayList arrListIcecreams = new ArrayList();    arrListIcecreams.Add( new Icecream {Name="Chocolate Fudge Icecream",        Ingredients="cream, milk, mono and diglycerides...",        Cholesterol="50mg", Protein="4g", TotalCarbohydrates="35g",        TotalFat="20g", Price=10.5 });    arrListIcecreams.Add( new Icecream {Name="Vanilla Icecream",        Ingredients="vanilla extract, guar gum, cream...",        Cholesterol="65mg", Protein="4g", TotalCarbohydrates="26g",        TotalFat="16g", Price=9.80 });    arrListIcecreams.Add( new Icecream {Name="Banana Split Icecream",        Ingredients="Banana, guar gum, cream...", Cholesterol="58mg",        Protein="6g", TotalCarbohydrates="24g", TotalFat="13g", Price=7.5    }); Following is the query to fetch low priced ice-creams from the list.     var queryIcecreanList = from Icecream icecream in arrListIcecreams    where icecream.Price < 10    select icecream; Use the foreach loop, shown as follows, to display the price of the objects retrieved using the above query.     foreach (Icecream ice in queryIcecreanList)    Console.WriteLine("Icecream Price : " + ice.Price);
Read more
  • 0
  • 0
  • 2159

article-image-creating-accessible-tables-joomla
Packt
22 Oct 2009
5 min read
Save for later

Creating Accessible Tables in Joomla!

Packt
22 Oct 2009
5 min read
Creating Accessible Tables Tables got a bad review in accessibility circles, because they used to create complex visual layouts. This was due to the limitations in the support for presentational specifications like CSS and using tables for layout was a hack—that worked in the real world—when you wanted to position something in a precise part of the web page. Tables were designed to present data of all shapes and sizes, and that is really what they should be used for. The Trouble with Tables So what are tables like for screen reader users? Tables often contain a lot of information, so sighted users need to look at the information at the top of the table (the header info), and sometimes the first column in each row to associate each data cell. Obviously this works for sighted users, but in order to make the tables accessible to a screen reader user we need to find a way of associating the data in each cell with its correct header so the screen reader can inform the user which header relates to each data cell. Screen reader users can navigate between data cells easily using the cursor keys. We will see how to make tables accessible in simple steps. There are methods of conveying the meaning and purpose of a table to the screen reader user by using the caption element and the summary attribute of the table element that you will find more on in the next section. We will learn how to build a simple table using Joomla! and the features contained within the WYSIWYG editors that can make the table more accessible. Before we do that though I want you to ask yourself about why you want to use tables (though sometimes it is unavoidable) and what forms should they take. Simple guidelines for tables: Try to make the table as simple as possible.    If possible don't span multiple cells etc. The simpler the table, the easier it is to make accessible.    Try to include the data you want to present in the body text of your site. Time for Action—Create an Accessible Table (Part 1) In the following example we will build a simple table that will list the names of some artists, some albums they have recorded, and the year in which they recorded the albums. First of all click the table icon from the TinyMCE interface and add a table with a suitable number of columns and rows.            By clicking on the Advanced tab you will see the Summary field. The summary information is very important. It provides the screen reader user a summary of the table. For example, I filled in the following text: "A list of some funk artists, my favorite among their records, and the year they recorded it in". My table then looked as follows: What Just Happened? There is still some work to be done in order to make the content more accessible. The controls that the WYSIWYG editor offers are also a little limited so we will have to edit the HTML by hand. Adding the summary information is a very good start. The text that I entered "A list of some funk artists, my favorite among their records, and the year they recorded it in." will be read out by the screen reader as soon as it receives a focus by the user. Time for Action—Create an Accessible Table (Part 2) Next we are going to add a Caption to the table, which will be helpful to both sighted and non-sighted users. This is how it's done. Firstly, select the top row of the table, as these items are the table heading. Then click on the Table Row properties icon beside the Tables icon and select Table Head under General Properties. Make sure that the Update current Row is selected in the dialogue box in the bottom left. You will apply these properties to your selected row. If you wish to add a caption to your table you need to add an extra row to the table and then select the contents of that row and add the Caption in the row properties dialogue box. This will tell the browser to display the caption text, in this case Funky Table Caption, else it will remain hidden. What Just Happened? By adding caption to the table, you provide useful information to the screen reader user. This caption should be informative and should describe something useful about the table. As the caption element is wrapped in a heading it is read out by the screen reader when the user starts exploring the table—so it is slightly different to the summary attribute, which is read out automatically. Does it Work? What we just did using the WYSIWYG editor, TinyMCE, is enough to make a good start towards creating a more accessible table, but we will have to work a little more in order to truly make the table accessible. So we will now edit the HTML. The good news is that you have made some good steps in the right direction and the final step is of associating the data cells with their suitable headers, as this is something that we cannot really do with the WYSIWYG editor alone, and is essential to make your tables truly accessible.
Read more
  • 0
  • 0
  • 2244
article-image-deploying-net-based-applications-microsoft-windows-ce-enabled-smart-devices
Packt
22 Oct 2009
4 min read
Save for later

Deploying .NET-based Applications on to Microsoft Windows CE Enabled Smart Devices

Packt
22 Oct 2009
4 min read
Introducing Microsoft Windows Mobile There exist several types of smart devices in the market including Smart Phones, Pocket PCs, Pocket PC Phones, Tablet PCs, etc. Every smart device is installed with a mobile‑based operating system with respect to the features of the device. One of such operating systems is Microsoft Windows CE. Microsoft Windows CE is a small, embedded operating system (runs from ROM) that has a look and feel similar to Microsoft Windows 95/98. It includes scaled down versions of Microsoft Excel, Microsoft Word, Microsoft Internet Explorer, etc. Microsoft Windows Mobile (Windows Mobile in short) is a complete software platform built on Windows CE. Unlike Windows CE, the Windows Mobile for Smart Phone or Pocket PC operating systems is specifically designed for devices that require a specialized hardware configuration. The software includes standardized interfaces and applications that ensure compatibility across hardware designs. The Pocket PC is the best example device that gets equipped with Microsoft Windows Mobile operating system. The Pocket PC runs Windows CE as its core operating system. Pocket PCs come with mobile versions of Microsoft Office applications in addition to Microsoft Outlook Mobile. Though there are different Pocket PCs, many come with Wi-Fi to enable you to connect to the Internet when you are near to a wireless hotspot. You can compose email messages and send them wirelessly or by synchronizing with your desktop computer. A Pocket PC Phone is a bit different from an ordinary Pocket PC. You can do everything with a Pocket PC Phone that you can do with a Pocket PC, but with the addition of cellular phone capabilities. If you have a Pocket PC Phone, you can access the Internet through the GPRS service. A Smart Phone has phone capabilities and comes with a smaller set of applications. Though you can add third-party software titles to your Smart Phone, the smaller keypad and screen are designed to give you quick one-handed access to important data. A Smart Phone is a good choice for business users who need to check email, keep track of their calendars, and take voice notes. Microsoft.NET enables us to develop and deploy .NET applications on Microsoft Windows Mobile-enabled smart devices like Smart Phones, Pocket PCs, Tablet PCs, etc. To develop for either Smart Phones or Pocket PCs, we need not really buy those devices. We simply need to have smart device client extensions installed as a part of Visual Studio 2005 (which automatically installs .NET Compact Edition). When the extensions are installed, we are provided with few device emulators for developing and testing .NET-based mobile applications. However, for testing and production, it is recommended to have physical smart devices. The next section focuses on developing a simple Pocket PC application, which consumes the web service developed previously. Consuming a Web Service from Pocket PC Now, let us make use a web service for the Pocket PC. You need not have a physical Pocket PC in your hands to test it. We can simply use existing emulators available as part of Visual Studio 2005. The following are the steps: Open Visual Studio 2005 Environment    Go to File | New | Project.    Select and provide information as shown in the following figure:      Add a Web Reference for the web service you created.    Drag and drop a DataGrid on to the Pocket PC emulator as shown below:      Modify the existing code as follows: Public Class Form1 Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load Me.DataGrid1.DataSource = (New EmpService.Service).getList.Tables(0) End SubEnd Class     Press F5, and select any Emulator for deployment. The output should look like the following: Conclusion We have seen the deployment of .NET-based application on to smart devices enabled with Microsoft Windows Mobile operating system.
Read more
  • 0
  • 0
  • 2906

article-image-blogger-improving-your-blog-google-analytics-and-search-engine-optimization
Packt
22 Oct 2009
7 min read
Save for later

Blogger: Improving Your Blog with Google Analytics and Search Engine Optimization

Packt
22 Oct 2009
7 min read
If you've ever wondered how people find your website or how to generate more traffic, then this article tells you more about your visitors. Knowing where they come from, what posts they like, how long they stay, and other site metrics are all valuable information to have as a blogger. You would expect to pay for such a deep look into the underbelly of your blog, but Google wants to give it to you for free. Why for free? The better your site does, the more likely you are to pay for AdWords or use other Google tools. The Google Analytics online statistics application is a delicious carrot to encourage content rich sites and better ad revenue for everyone involved. You also want people to find your blog when they perform a search about your topic. The painful truth is that search engines have to find your blog first before it will show up in their results. There are thousands of new blogs being created everyday. If you want people to be able to find your blog in the increasingly crowded blogosphere, optimizing your blog for search engines will improve the odds. Improving Your Blog with Google Analytics Analytics gives you an overwhelming amount of data to use for measuring the success of your sites, and ads. Once you've had time to analyze that data, you will want to take action to improve the performance of your blog, and ads. We'll now look at how Analytics can help you make decisions about the design, and content of your site. Analyzing Navigation The Navigation section of the Content Overview report reveals how your visitors actually navigate your blog. Visitors move around a site in ways we can't predict. Seeing how they actually navigate a site and where they entered the site are powerful tools we can use to diagnose where we need to improve our blog. Exploring the Navigation Summary The Navigation Summary shows you the path people take through your site, including how they get there and where they go. We can see from the following graphical representation that our visitors entered the site through the main page of the blog most of the time. After reaching that page, over half the time, they went to other pages within the site. Entrance Paths We can see the path, the visitors take to enter our blog using the Entrance Paths report. It will show us from where they entered our site, which pages they looked at, and the last page they viewed before exiting. Visitors don't always enter by the main page of a site, especially if they find the site using search engines or trackbacks. The following screenshot displays a typical entrance path. The visitor comes to the site home page, and then goes to the full page of one of the posts. It looks like our visitors are highly attracted to the recipe posts. Georgia may want to feature more posts about recipes that tie in with her available inventory. Optimizing your Landing Page The Landing Page reports tell you where your visitors are coming from, and if they have used keywords to find you. You have a choice between viewing the source visitors used to get to your blog, or the keywords. Knowing the sources will give you guidance on the areas you should focus your marketing or advertising efforts on. Examining Entrance Sources You can quickly see how visitors are finding your site, whether through a direct link, or a search engine, locally from Blogger, or from social networking applications such as Twitter.com. In the Entrance Sources graph shown in the following screenshot, we can see that the largest among the number of people are coming to the blog using a direct link. Blogger is also responsible for a large share of our visitors, which is over 37%. There is even a visitor drawn to the blog from Twitter.com, where Georgia has an account. Discovering Entrance Keywords When visitors arrive at your site using keywords, the words they use will show up on the report. If they are using words in a pattern that do not match your site content, you may see a high bounce rate. You can use this report to redesign your landing page to better represent the purpose of your site by the words, and phrases that you use. Interpreting Click Patterns When visitors visit your site they show their attraction to links, and interactive content by clicking on them. Click Patterns are the representation of all those mouse clicks over a set time period. Using the Site Overlay reporting feature, you can visually see the mouse clicks represented in a graphical pattern. Much like collared pins stuck on a wall chart they will quickly reveal to you, which areas of your site visitors clicked on the most, and which links they avoided. Understanding Site Overlay Site Overlay shows the number of clicks for your site by laying them transparently in a graphical format on top of your site. Details with the number of clicks, and goal tracking information pop up in a little box when you hover over a click graphic with your mouse. At the top of the screen are options that control the display of the Site Overlay. Clicking the Hide Overlay link will hide the overlay from view. The Displaying drop-down list lets you choose how to view mouse Clicks on the page, or goals. The date range is the last item displayed. The graphical bars shown on top of the page content indicate where visitors clicked, and how many of them did so. You can quickly see what areas of the page interest your visitors the most. Based on the page clicks you see, you will have an idea of the content, and advertising that is most interesting to your visitors. Yes, Site Overlay will show the content areas of the page the visitors clicked on, and the advertisement areas. It will also help you see which links are tied to goals, and whether they are enticing your visitors to click. Optimizing Your Blog for Search Engines We are going to take our earlier checklists and use them as guides on where to make changes to our blog. When the changes are complete, the blog will be more attractive to search engines and visitors. We will start with changes we can make "On-site", and then progress to ways we can improve search engine results with "Off-site" improvements. Optimizing On-site The most crucial improvements we identified earlier were around the blog settings, template, and content. We will start with the easiest fixes, then dive into the template to correct validation issues. Let's begin with the settings in our Blogger blog. Seeding the Blog Title and Description with Keywords When you created your blog, did you take a moment to think about what words potential visitors were likely to type in when searching for your blog? Using keywords in the title and description of your blog gives potential visitors a preview and explanation of the topics they can expect to encounter in your blog. This information is what will also display in search results when potential visitors perform a search. Updating the Blog Title and Description It's never too late to seed your blog title and description with keywords. We will edit the blog title and description to optimize them for search engines. Login to your blog and navigate to Settings | Basic. We are going to replace the current title text with a phrase that more closely fits the blog. Type Organic Fruit for All into the Title field. Now, we are going to change the description of the blog. Type Organic Fruit Recipes, seasonal tips, and guides to healthy living into the description field. Scroll down to the bottom of the screen and click the Save Settings button. Y ou can enter up to 500 characters of descriptive text. What Just Happened? When we changed the title and description of our blog in the Basic Settings section, Blogger saved the changes and updated the template information as well. Now, when search engines crawl our blog, they will see richer descriptions of our blog in the blog title and blog description. The next optimization task is to verify that search engines can index our blog.
Read more
  • 0
  • 0
  • 4913
Modal Close icon
Modal Close icon