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

How-To Tutorials - Web Development

1802 Articles
article-image-processing-twitter-and-new-york-times-apis-aspnet-ajax-microsoft-cdn
Packt
18 Nov 2009
7 min read
Save for later

Processing Twitter and New York Times APIs with ASP.NET Ajax on Microsoft CDN

Packt
18 Nov 2009
7 min read
APIs (Application Programming Interface) are application-to-application programming interfaces that support harvesting information on the web using the known web standards. These APIs are provided by the entities who wish to expose parts of their resources that a third party can use. The APIs run transparent to the user and exposes just what they want to expose, with some providing access to material for public consumption with others giving access to resources based on authentication. In a sense they may be called a basic form of SAAS. Amazon.com, Google etc have exposed their APIs for some time. Twitter and New York Times have also exposed their API's which can be used to do some digging into the information contained in them, a kind of web mining. Many others such as Netflix have provided their own APIs described on their web sites. What is Twitter API? Twitter API is provided by the Social Networking and Micro-blogging service. Twitter API adheres to the web standards and one can talk to Twitter using HTTP. You can just about access anything on the Twitter web site. One example of creating a Microsoft SQL Server Report using Twitter API is available here - Tweets with Reporting Services, wherein the response from the Twitter API was in XML format. JSON (JavaScript Object Notation) is another format in which data is returned when an API call is made. In this article we will be looking at API call that returns a JSON response. Twitter exposes a large number methods through their API's such as API's for Search, Timeline, Status, User, Direct Message, Friendship and many more. As previously mentioned the responses will be in XML or JSON. Also while some APIs may take parameters others may not. The Twitter API used in this tutorial We will be looking at trends in Twitter API exposed by the url, http://search.twiiter.com/trends.format. We will be using the GET method and we will expect a JSON response. Since the volume of traffic may overwhelm, the calls that you can make to this in an hour are limited (also known as rate limiting) but not critical for the demo in this tutorial. Here is a typical call to the trends method on the Twitter API. Herein we will search for trends on the Twitter site and expect a response in JSON, if we use json instead of Format in the next URL address. Instead of:http://search.twitter.com/trends.Formattype-in, the following for URL address,http://search.twitter.com/trends.json When you plug the above in a web Brower you would get a response trends.json which you may save to your hard drive or, use it in any way you like. The next quoted text is what you get in response (note that this is what I got on Saturday 31, 2009 and what you get will be different), the content of the file trends.json you saved to your computer. Note that presently you get about top ten trends from this API call. {"as_of":"Sat, 31 Oct 2009 20:44:46 +0000","trends":[{"name":"Happy Halloween", "url":"http://search.twitter.com/search?q=%22Happy+Halloween%22+OR+%22Feliz+ Halloween%22"},{"name":"#nxzerosetechaves","url":"http://search.twitter.com/search?q=%23nxzerosetechaves"},{"name":"Danyl","url":"http://search.twitter.com/search?q=Danyl"},{"name":"#HappyHalloween","url":"http://search.twitter.com/search?q=%23HappyHalloween"},{"name":"#potterday","url":"http://search.twitter.com/search?q =%23potterday"},{"name":"X Factor","url":"http://search.twitter.com/search?q=%22X+ Factor%22"},{"name":"It's Halloween","url":"http://search.twitter.com/search?q=%22It %27s+Halloween%22+OR+%22Its+Halloween%22"},{"name":"Trick","url":"http://search.twitter.com/search?q=Trick+OR+%23trick"},{"name":"Paranormal Activity","url":"http://search.twitter.com/search?q=%22Paranormal+Activity%22"},{"name":"This Is It","url":"http://search.twitter.com/search?q=%22This+Is+It%22"}]} First of all what you see returned is a JSON object. If you are new to JSON review this article on my blog. The various elements that you see such as 'name', 'url' etc are fields in the response that are all described in the API documentation(look for Return Values). Some of the API calls can return a ton of information and you will have to know the API method so that you can correctly parse this data. Another thing you would notice is that the JSON object you get out is a nested object with many levels. You may need a JSON Parser to get a clearer picture of this nesting and I recommend using the online parser at this site. Using the above site, the JSON Object would appear as shown (only a portion is shown). New York Times API New York Times made available to the developers sometime in the middle of October 2008 APIs that can search New York Times for various kinds of information . Just like in Twitter there are a large number of APIs that you can use such as: Article Search; Best Sellers; Campaign Finance; Congress; and many others. Interested users can get on to this resource by signing up here requesting what APIs they would like to use. After signing up, New York Times would provide keys for the APIs that you want to access. It is important therefore, that the call should include the keys provided to you. For example, I received keys to access the following resources: Movie Reviews, Article Search, Best Sellers and Times Newswire. The key for the Movies Reviews API appears as shown here (the one shown here has been doctored and will not work). Movie Reviews API Key: b57378910b9fd80ecc73461547c93e8a:10:50673441 Using the New York Times API It is a valuable resource since you can get for example with the Article Search API access to more than 2.8 million articles from 1981. Using this is quite simple, just paste the URL shown below into the address box of your browser. Note that the key shown here is fake (but of correct format). http://api.nytimes.com/svc/search/v1/article?query=India&facets=publication_year&api-key=6c208890a4880093c30020be8fe17a40:0:50633441 This will display in the browser the JSON object that is returned as shown. You can use the previously mentioned site to parse it for more friendly display. {"facets" : {"publication_year" : [{"count" : 2724 , "term" : "2008"} , {"count" : 2345 , "term" : "2006"} , {"count" : 2311 , "term" : "2009"} , {"count" : 2282 , "term" : "2007"} , {"count" : 2144 , "term" : "2002"} ,{"count" : 2111 , "term" : "2001"} , {"count" : 1988 , "term" : "2005"} , {"count" : 1951 , "term" : "2004"} , {"count" : 1921 , "term" : "1985"} , {"count" : 1798 , "term" : "2003"} , {"count" : 1761 , "term" : "1999"} , {"count" : 1720 , "term" : "2000"} , {"count" : 1642 , "term" : "1998"} , {"count" : 1442 , "term" : "1984"} , {"count" : 1382 , "term" : "1986"}]} , "offset" : "0" , "results" : [{"body" : "BARSUR, India — At the edge of the Indravati River, hundreds of miles from the nearest international border, India effectively ends. Indian paramilitary officers point machine guns across the water. The dense jungles and mountains on the other side belong to Maoist rebels dedicated to overthrowing the government. "That is their liberated" , "byline" : "By JIM YARDLEY" , "date" : "20091101" , "title" : "Maoist Rebels Widen Deadly Reach Across India" , "url" : "http://www.nytimes.com/2009/11/01/world/asia /01maoist.html"} ,.........(there is more of this but abbreviated here) Response Format As you can see the responses to the API calls return JSON objects in general of the form shown belo w (this one is of the form returned by the Twiiter API). What we propose to do is to use jQuery's GetJSON() method to get the JSON Objects and use Microsoft AJAX JavaScript files to display the data on the web page. Both jQuery javascript files and Microsoft ASP.NET AJAX files are both available on the Microsoft ECN (CDN). The GetJSON() method as well as the Microsoft ASP.NET AJAX templates can be easily implemented in the Visual Studio 2008 IDE. Alternatively Microsoft AJAX can also be used to retrieve data from the web sites. In this article the GetJSON() method will be used. {"x":{"y":[{"a1":"b1", "c1":"d1"}, {"a2":"b2", "c2":"d2"}]},.... "f":"g",....}
Read more
  • 0
  • 0
  • 3838

article-image-fundamentals-xhtml-mp-mobile-web-development
Packt
23 Oct 2009
7 min read
Save for later

Fundamentals of XHTML MP in Mobile Web Development

Packt
23 Oct 2009
7 min read
Fundamentals of XHTML MP Since XHTML MP is based on XHTML, certain syntactical rules must be followed. Making syntactical errors is a good way to learn a programming language, but so that you don't get frustrated with them, here are some rules you must follow with XHTML MP! Remember, HTML is very forgiving in terms of syntax, but make a small syntax error in XHTML MP and the browser may refuse to show your page! Overall, XHTML elements consist of a start tag—element name and its attributes, element content, and closing tag. The format is like: <element attribute="value">element content</element> XHTML Documents Must be Well Formed Since XHTML is based on XML, all XHTML documents must adhere to thebasic XML syntax and be well formed. The document must also have a DOCTYPE declaration. Tags Must be Closed! All open tags must be closed. Even if it is an empty tag like "<br>", it must be used in the self-closed form like "<br />". Note the extra space before the slash. It's not mandatory, but makes things work with some older browsers. If you can validate within your editor, make it a practice to do that. Also cultivate the habit of closing a tag that you start immediately—even before you put in the content. That will ensure you don't miss closing it later on! Elements Must be Properly Nested You cannot start a new paragraph until you complete the previous one. You must close tags to ensure correct nesting. Overlapping is not allowed. So the following is not valid in XHTML MP: <p><b>Pizzas are <i>good</b>.</i></p> It should be written as: <p><b>Pizzas are <i>good</i>.</b></p> Elements and Attributes Must be in Lowercase XHTML MP is case sensitive. And you must keep all the element tags and all their attributes in lowercase, although values and content can be in any case. Attribute Values Must be Enclosed within Quotes HTML allowed skipping the quotation marks around attribute values. This will not work with XHTML MP as all attribute values must be enclosed within quotes—either single or double. So this will not work: <div align=center>Let things be centered!</div> It must be written as: <div align="center">Let things be centered!</div> Attributes Cannot be Minimized Consider how you would do a drop down in HTML: <select> <option value="none">No toppings</option> <option value="cheese" selected>Extra Cheese</option> <option value="olive">Olive</option> <option value="capsicum">Capsicum</option> </select> The same drop down in XHTML is done as: <select> <option value="none">No toppings</option> <option value="cheese" selected="selected">Extra Cheese</option> <option value="olive">Olive</option> <option value="capsicum">Capsicum</option> </select> The "selected" attribute of the "option" element has only one possible value and, with HTML, you can minimize the attribute and specify only the attribute without its value. This is not allowed in XHTML, so you must specify the attribute as well as its value, enclosed in quotes. Another similar case is the "checked" attribute in check boxes. XHTML Entities Must be Handled Properly If you want to use an ampersand in your XHTML code, you must use it as &amp; and not just &. & is used as a starting character for HTML entities—e.g. &nbsp;, &quot;, &lt;, &gt; etc. Just using & to denote an ampersand confuses the XML parser and breaks it. Similarly, use proper HTML Entities instead of quotation marks, less than/greater than signs, and other such characters. You can refer to http://www.webstandards.org/learn/reference/charts/entities/ for more information on XHTML entities. Most Common HTML Elements are Supported The following table lists different modules in HTML and the elements within them that are supported in XHTML MP version 1.2. You can use this as a quick reference to check what's supported. Module Element Structure body, head, html, title Text abbr, acronym, address, blockquote, br, cite, code, dfn, div, em, h1, h2, h3, h4, h5, h6, kbd, p, pre, q, samp, span, strong, var Presentation b, big, hr, i, small Style Sheet style element and style attribute Hypertext a List dl, dt, dd, ol, ul, li Basic Forms form, input, label, select, option, textarea, fieldset, optgroup Basic Tables caption, table, td, th, tr Image img Object object, param Meta Information meta Link link Base base Legacy start attribute on ol, value attribute on li Most of these elements and their attributes work as in HTML. Table support in mobile browsers is flaky, so you should avoid tables or use them minimally. We will discuss specific issues of individual elements as we go further. XHTML MP Does Not Support Many WML Features If you have developed WAP applications, you would be interested in finding the differences between WML (Wireless Markup Language—the predecessor of XHTML MP) and XHTML MP; apart from the obvious syntactical differences. You need to understand this also while porting an existing WML-based application to XHTML MP. Most of WML is easily portable to XHTML MP, but some features require workarounds. Some features are not supported at all, so if you need them, you should use WML instead of XHTML MP. WML 1.x will be supported in any mobile device that conforms to XHTML MP standards. Here is a list of important WML features that are not available in XHTML MP: There is no metaphor of decks and cards. Everything is a page. This means you cannot pre-fetch content in different cards and show a card based on some action. With XHTML MP, you either have to make a new server request for getting new content, or use named anchors and link within the page. You could use the <do> tag in WML to program the left and right softkeys on the mobile device. Programming softkeys is not supported in XHTML MP; the alternative is to use accesskey attribute in the anchor tag (<a>) to specify a key shortcut for a link. WML also supports client-side scripting using WMLScript—a language similar to JavaScript. This is not supported in XHTML MP yet, but will come in near future in the form of ECMA Script Mobile Profile (ECMP). WML also supported client-side variables. This made it easier to process form data, validate them on the client side, and to reuse user-filled data across cards. This is not supported in XHTML MP. With XHTML MP, you have to submit a form with a submit button. WML allowed this on a link. WML also had a format attribute on the input tag—specifying the format in which input should be accepted. You need to use CSS to achieve this with XHTML MP. There are no timers in XHTML MP. This was a useful WML feature making it easier to activate certain things based on a timer. You can achieve a similar effect in XHTML MP using a meta refresh tag. The WML events ontimer, onenterbackward, onenterforward, and onpick are not available in XHTML MP. You can do a workaround for the ontimer event, but if you need others, you have to stick to using WML for development. XHTML MP also does not support the <u> tag, or align attribute on the <p> tag, and some other formatting options. All these effects can be achieved using CSS though. Summary In this article, we had a look at the fundamentals of XHTML MP and also at the grammar that must be followed for development with it. Next, we listed different modules in HTML and the elements within them that are supported in XHTML MP version 1.2. We finished the article by listing the important WML features that are not available in XHTML MP.
Read more
  • 0
  • 0
  • 3834

article-image-customizing-prestashop-theme-part-2
Packt
22 Jul 2010
13 min read
Save for later

Customizing PrestaShop Theme Part 2

Packt
22 Jul 2010
13 min read
(For more resources on PrestaShop 1.3, see here.) Let's move on with our next step. Of course, exploring every tab in the back office would be advantageous, but we will specifically touch only those points that will affect your theming process. We will now look at how we can modify the following: Logo Top of page Adding FEATURED PRODUCTS block Footer Title Placing the other modules useful for your store on other section of your pages. Before going further, I would like to emphasize two important points. They are: Always work on a copy of your default theme: If you have not copied the default theme file, I would advise that when you start your development work, you copy the default theme file so that you have a backup or a comparison to work with. We will be working on the copy of the default theme, as in some cases, we will still change a few lines of codes to modify the theme. This means that if you ever make a huge blunder, you will at least have the original to start with again. If the worst ever happens, you can always upload the original file again to overwrite your errors, but that will be a big waste of time. Keep a quick reference list of any modifications made to any file: It may sound a bit tedious, but you will find this advice useful to heed. There are a few ways of making modifications to your theme, sometimes through modification of your other files (which are not in the theme folder). You may copy the file and put it into the theme folder to make the changes, or it is also possible to merely modify them by overwriting the file in its location. Whichever way you chose, when you need to modify files which are not in your custom theme folder, you should make a quick note of what changes you have made and where have you made them. Why? Because when there is a new version of PrestaShop, you will need to upgrade your PrestaShop site, thus the modifications you have made will be lost. The modifications in the theme folders will remain even if you update the version of your PrestaShop site. By keeping a list of the modifications you've made, it will be much easier to track back to where to re-apply them after you have upgraded your PrestaShop installation. Never procrastinate on making this quick list because you will always find that it is a waste of time to find and trace those changes later; even just six months down the road. Copying the default theme file When you download PrestaShop, by default, you will have a copy of the PrestaShop theme folder. Go to the PrestaShop_1.3.1/themes/PrestaShop folder. Copy this entire folder and save it on your computer. You may rename the theme accordingly, for example, theme1. Compress this into a ZIP file. Upload the renamed folder into the themes directory on your hosting through your cPanel or FTP. You will now have two themes in your /themes folder which are PrestaShop and theme1. You can now log in to your PrestaShop Back Office | Preferences | Appearance and switch to your theme1 that you just installed and click on the Save button. On this page, you may also control what logo, favicon, and the navigation pipes you want to use throughout your website. Now, let's start with the modification of these theme elements to complete the look of your new theme. Logo A logo is an important element of a company's or store's image, and it can contribute to the brand's marketing success. Therefore, getting a good quality logo is fundamental for the business. Getting a unique and attractive logo design can be daunting, especially for those who are not born with a flair for design. However, fortunately, there are various resources that you can use to get ideas or even create a very professional looking logo that you can use in your new online store. Some online resources for logo designs can be found at: http://www.logomaker.com—This is an online resource that allows you to freely create a logo, but you have to pay to download your new creation, which basically uses their online inputs. Quite attractive and interesting looking logos can be found and designed here. http://cooltext.com—This one describes itself as A free graphics generator for web pages and anywhere else you need an impressive logo without a lot of design work. It allows you to choose the image you would like through a few simple steps. You only need to enter the words or company name using a form and you'll have your own custom image created on the fly. The logo you designed is downloadable for free. http://www.simwebsol.com/ImageTool/Default.aspx—This is a Web 2.0 logo generator. Free to use and download. It requires you to fill in a few fields and generates the image file quite easily. However, the background is limited to RGB flat choices and you only have 23 images that can be chosen from to insert. http://www.onlinelogomaker.com/ - A full featured free online logo design tool with a clean and easy interface and thousands of logo templates Another element, which is quite important here, is the favicon. The Favicon is the little icon representing the website you are visiting which gets displayed in the address bar of every browser. Usually, the favicon and the logo are the same thing, except for their sizes and the formats. They are not necessarily the same though. You may find some online resources that you can use to generate a favicon for the store. Make sure you have prepared the favicon icon before you try to replace the current favicon. If you are unsure of how to go about making a favicon, you may generate it online (using,http://www.favicon.cc/ or http://www.freefavicon.com/). Save the file on your hard drive and then upload it to your PrestaShop store. Uploading it is shown in the next section. Time for action—Replacing the default logo and favicon on your site The logo and the favicon can be replaced through Back Office | Preferences | Appearance, as shown in the following screenshot:     Browse the file you want to use from your computer. Upload the files and click on the Save button. You need to refresh your back office browser before you replace the logo and the new favicon.ico file. You also need to clean up your browser's cache and refresh the browser to see the favicon in the frontend of the website.     Upon saving and refreshing your browser, the updated images will be displayed. What just happened? In this simple exercise, you have just uploaded the logo that you had created, and PrestaShop has, by default, placed it in the correct directory in your new theme1 directory through the back office panel. If you did not choose the new theme, for example, theme1 in Preferences | Appearance under Themes, the logo you upload will go to the wrong directory. The Center Editorial Block The Center Editorial Block is where you see the main image at the center column, as we indicated previously in the front office. This is an important block, as this is where your visitors first arrive when they visit your store. It gives a first impression to your site visitor, and therefore, you need to consider what to include in it very carefully. Time for action—Modifying the Center Editorial block The Centre Editorial Block can be modified through Back Office | Modules | Tools | Home text editor. In this section, you can also edit the Centre Block image, which is referred to as Homepage's logo, and this title can be quite misleading as it may be confused with the actual logo. However, we have covered this matter in the previous article and did a mapping of each field here to the front office page of the store. You only need to upload the image you want to replace it with and continue with editing the Homepage logo link, which is the link for this image (Homepage's logo). You may just leave it set to your current website address if you want (for example, www.mydomainname.com). You can also leave it blank if you don't want the image to be a link. Furthermore, you will see Homepage logo subheading, which is the small letters you see on the default theme page that appear under the image. Let's replace the Homepage's logo image, Homepage logo link, and a new Homepage logo subheading: Click on the Update the editor button. Review your changes in your front office browser. You will need to refresh the page once to see the effect. It is possible to work with different image sizes, but the width of the image will "disturb" your column settings. If you are not going to make any unnecessary changes, then it is best to use images of the safe maximum width for the center column which is 530 pixels. If you exceed this width it will push your right column outside the standard browser view. Now let's have a look at what you have achieved so far. What just happened? You have modified your Center Editorial Block by inserting a new Homepage's logo image, Homepage logo link, and a new Homepage logo subheading. Top of pages block We will look at the header section of the page. The default layout comprises the following in the header section: Currency block (links to the available currencies used on the site). Languages block (links to the available language translation of the pages interface). Permanent link block: Contact (icon that links to the contact form page) Sitemap (icon that links to the sitemap page) Bookmark (icon that helps you bookmark a particular page on the site) Search block User links block: Your Account (icon that links to the login page or registration page). When logged in, it links to the account page that lists everything the customer can do with their account. It is only when the viewer is logged out that it links to the authentication page Cart (icon that links to the shopping cart summary page ) Welcome, Log in (links to the login page or registration page)     Time for action—Modifying the Top of pages To get these elements back on the pages, you will need to install and enable the relevant modules. These simple steps will need little modifications unless you want to add a new currency and a new language. Let's enable these modules through these simple steps: Currency block—go to Modules | scroll down to Blocks | Currency block. Languages block—go to Modules | scroll down to Blocks | Language block. Search block—go to Modules | scroll down to Blocks | Quick Search block. Permanent link block—go to Modules | scroll down to Blocks | Permanent links block. By default, these modules tend to appear on the pages in the order you installed and enabled them. The first one will appear the leftmost while the last one will be the rightmost. You can shift the arrangement by installing them according to what you want to appear on the leftmost or the rightmost sides. Notice that the Permanent link block is on the right as we enabled it last. There is an easier way to do this as well, which we will cover in the next section. You can modify this by working on the position of the modules within the Top of pages hooks. There are two similar hooks, which can be quite confusing, that is, the Top of pages and Header. The blocks are positioned or "transplanted" in a Top of pages hook and not Header of pages. The Welcome, Log in, Cart, and the User login links can be enabled through Back Office | Modules | Blocks | User info block. Upon installing and enabling the module, you will have the Welcome, Log in, Your Account, and Cart link displayed on your front office. By default, all those are automatically hooked to the Top of pages once they are enabled. If it is not, you can have it hooked through transplanting the module to the hook, as shown in the next screenshot. This can be done by following these simple steps: Go to Back Office | Modules | Position | Transplant a module.     Choose the Module you want to transplant from the drop-down menu. Choose the hook from Hook into, the one you want the Module to go into. Click on the Save button. The arrangement of the blocks can be done by moving them around within the hooks, which we will see next. Go to Modules | Positions. There you can arrange the position of the modules within the hooks by dragging each of them to the required position. As you can see, there are the two similar hooks which may be confusing, namely, the Header of pages and the Top of pages. Compare it with what you have at the front office in the next screenshot.   The Quick Search block does not appear despite it being hooked at the Header of pages. The other blocks which are hooked to the Top of pages are displayed in the front office. The same thing with the User info block; you only see the one which is hooked to the Top of pages and not the one in the Header of pages. The Top of pages hook is used to display a module at the top of the page. The Header of pages hook is used to put code in the <head> tag of the website. If you want to move a module or delete it from the top of the page, you should use the Top of pages hook, not the Header of pages hook. Modules that are in the Header of pages hook should not be removed, since they are required for the module to function correctly. For example, if you remove the Quick search block from the Header of pages hook, the search autocomplete will not work, since the code for it is missing. The resulting JavaScript error will also cause other problems on the website such as the Categories block not displaying any categories. To move the modules to the left or right, you need to move them up within the hook. The lower it is within the hook, the more to the right the module will appear, whereas the upper within the hook will be displayed on the left. For example, the Currency block is first in the list, and it is displayed on the left of the Top of pages section on the webpage. What just happened? You just learnt the differences between the hooks Top of pages and Header of pages in PrestaShop. You also get to modify the blocks you want to use on the top of the page and how to move them around within the hook.
Read more
  • 0
  • 0
  • 3828

article-image-restful-web-service-implementation-resteasy
Packt
18 Nov 2009
2 min read
Save for later

RESTful Web Service Implementation with RESTEasy

Packt
18 Nov 2009
2 min read
Getting the tools If you have already downloaded and installed Java's JDK and the Tomcat web server, you only need to download the JBoss's RESTEasy framework. Nevertheless, the complete list of the software needed for this article is as follows: Software Web Location Java JDK http://java.sun.com/ Apache Tomcat http://tomcat.apache.org/download-60.cgi Db4o http://developer.db4o.com/files/default.aspx RESTEasy Framework http://www.jboss.org/resteasy/ Install the latest Java JDK along with the latest version of Tomcat, if you haven't done so. Download and install Db4o and RESTEasy. Remember the location of the installs, as we'll need the libraries to deploy with the web application. RESTEasy — a JAX-RS implementation   RESTEasy is a full open source implementation of the JAX-RS specification. This framework works within any Java Servlet container, but because it's developed by JBoss, it offers extra features that are not part of the JAX-RS requirements. For example, RESTEasy offers out-of-the-box Atom support and also offers seamless integration with the EJB container portion of JBoss (none of these features are explored here). Web service architecture By now, you should be familiar with the coding pattern. Because we want to reuse a large portion of code already written, we have separate layers of abstraction. In this article, therefore, we only talk about the web layer and study in detail how to implement a full RESTful web service using RESTEasy. The full architecture of our web service looks as follows: In this diagram, we depict clients making HTTP requests to our web service. Each request comes to the web container, which then delegates the request to our RESTful layer that is composed of RESTEasy resource classes. The actual serialization of user and message records is delegated to our business layer, which in turns talks directly to our database layer (a Db4o database). Again, RESTEasy is a platform independent framework and works within any Servlet container. For this article we deploy our web service in Tomcat, as we've been working with it so far and are now familiar with deploying web applications to it, though we could as easily use the JBoss web container.
Read more
  • 0
  • 0
  • 3825

article-image-using-form-builder
Packt
11 Aug 2015
18 min read
Save for later

Using the Form Builder

Packt
11 Aug 2015
18 min read
In this article by Christopher John Pecoraro, author of the book, Mastering Laravel, you learn the fundamentals of using the form builder. (For more resources related to this topic, see here.) Building web pages with Laravel Laravel's approach to building web content is flexible. As much or as little of Laravel can be used to create HTML. Laravel uses the filename.blade.php convention to state that the file should be parsed by the blade parser, which actually converts the file into plain PHP. The name blade was inspired by the .NET's razor templating engine, so this may be familiar to someone who has used it. Laravel 5 provides a working demonstration of a form in the /resources/views/ directory. This view is shown when the /home route is requested and the user is not currently logged in. This form is obviously not created using the Laravel form methods. The route is defined in the routes file as follows: Route::get('home', 'HomeController@index'); The master template This is the following app (or master) template: <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Laravel</title> <link href="/css/app.css" rel="stylesheet"> <!-- Fonts --> <link href='//fonts.googleapis.com/css?family=Roboto:400,300' rel='stylesheet' type='text/css'> <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries --> <!-- WARNING: Respond.js doesn't work if you view the page via file:// --> <!--[if lt IE 9]> <script src="https://oss.maxcdn.com/html5shiv/3.7.2/ html5shiv.min.js"></script> <script src="https://oss.maxcdn.com/respond/1.4.2/ respond.min.js"></script> <![endif]--> </head> <body> <nav class="navbarnavbar-default"> <div class="container-fluid"> <div class="navbar-header"> <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" datatarget="# bs-example-navbar-collapse-1"> <span class="sr-only">Toggle Navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" href="#">Laravel</a> </div> <div class="collapse navbar-collapse" id=" bs-example-navbar-collapse-1"> <ul class="navnavbar-nav"> <li><a href="/">Home</a></li> </ul> <ul class="navnavbar-navnavbar-right"> @if (Auth::guest()) <li><a href="{{ route('auth.login') }}">Login</a></li> <li><a href="/auth/register"> Register</a></li> @else <li class="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">{{ Auth::user()->name }} <span class="caret"></span></a> <ul class="dropdown-menu" role="menu"> <li><a href="/auth/ logout">Logout</a></li> </ul> </li> @endif </ul> </div> </div> </nav> @yield('content') <!-- Scripts --> <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/ 2.1.3/jquery.min.js"></script> <script src="//cdnjs.cloudflare.com/ajax/libs/twitterbootstrap/ 3.3.1/js/bootstrap.min.js"></script> </body> </html> The Laravel 5 master template is a standard HTML5 template with the following features: If the browser is older than Internet Explorer 9: Uses the HTML5 Shim from the CDN Uses the Respond.js JavaScript code from the CDN to retrofit media queries and CSS3 features Using @if (Auth::guest()), if the user is not authenticated, the login form is displayed; otherwise, the logout option is displayed Twitter bootstrap 3.x is included in the CDN The jQuery2.x is included in the CDN Any template that extends this template can override the content section An example page The source code for the login page is as follows: @extends('app') @section('content') <div class="container-fluid"> <div class="row"> <div class="col-md-8 col-md-offset-2"> <div class="panel panel-default"> <div class="panel-heading">Login</div> <div class="panel-body"> @if (count($errors) > 0) <div class="alert alert-danger"> <strong>Whoops!</strong> There were some problems with your input.<br><br> <ul> @foreach ($errors->all() as $error) <li>{{ $error }}</li> @endforeach </ul> </div> @endif <form class="form-horizontal" role="form" method="POST" action="/auth/login"> <input type="hidden" name="_token" value="{{ csrf_token() }}"> <div class="form-group"> <label class="col-md-4 controllabel"> E-Mail Address</label> <div class="col-md-6"> <input type="email" class="formcontrol" name="email" value="{{ old('email') }}"> </div> </div> <div class="form-group"> <label class="col-md-4 controllabel"> Password</label> <div class="col-md-6"> <input type="password" class="form-control" name="password"> </div> </div> <div class="form-group"> <div class="col-md-6 col-md-offset-4"> <div class="checkbox"> <label> <input type="checkbox" name="remember"> Remember Me </label> </div> </div> </div> <div class="form-group"> <div class="col-md-6 col-md-offset-4"> <button type="submit" lass="btn btn-primary" style="margin-right: 15px;"> Login </button> <a href="/password/email">Forgot Your Password?</a> </div> </div> </form> </div> </div> </div> </div> </div> @endsection From static HTML to static methods This login page begins with the following: @extends('app') It obviously uses the object-oriented paradigm to state that the app.blade.php template will be rendered. The following line overrides the content: @section('content') For this exercise, the form builder will be used instead of the static HTML. The form tag We will convert a static form tag to a FormBuilder method. The HTML is as follows: <form class="form-horizontal" role="form" method="POST"   action="/auth/login"> The method facade that we will use is as follows: Form::open(); In the FormBuilder.php class, the $reserved attribute is defined as follows: protected $reserved = ['method', 'url', 'route',   'action', 'files']; The attributes that we need to pass to an array to the open() method are class, role, method, and action. Since method and action are reserved words, it is necessary to pass the parameters in the following manner: Laravel form facade method array element HTML Form tag attribute method method url action role role class class Thus, the method call looks like this: {!! Form::open(['class'=>'form-horizontal', 'role =>'form', 'method'=>'POST', 'url'=>'/auth/login']) !!} The {!! !!} tags are used to start and end parsing of the form builder methods. The form method, POST, is placed first in the list of attributes in the HTML form tag. The action attribute actually needs to be a url. If the action parameter is used, then it refers to the controller action. In this case, the url parameter produces the action attribute of the form tag. Other attributes will be passed to the array and added to the list of attributes. The resultant HTML will be produced as follows: <form method="POST" action="http://laravel.example/auth/login" accept-charset="UTF-8" class="form-horizontal" role="form"> <input name="_token" type="hidden" value="wUY2hFSEWCzKHFfhywHvFbq9TXymUDiRUFreJD4h"> The CRSF token is automatically added, as the form method is POST. The text input field To convert the input fields, a facade is used. The input field's HTML is as follows: <input type="email" class="form-control" name="email" value="{{ old('email') }}"> Converting the preceding input field using a façade looks like this: {!! Form::input('email','email',old('email'), ['class'=>'form-control' ]) !!} Similarly, the text field becomes: {!! Form::input('password','password',null, ['class'=>'form-control']) !!} The input fields have the same signature. Of course, this can be refactored as follows: <?php $inputAttributes = ['class'=>'form-control'] ?> {!! Form::input('email','email',old('email'), $inputAttributes ) !!} ... {!! Form::input('password','password',null,$inputAttributes ) !!} The label tag The label tags are as follows: <label class="col-md-4 control-label">E-Mail Address</label> <label class="col-md-4 control-label">Password</label> To convert the label tags (E-Mail Address and Password), we will first create an array to hold the attributes, and then pass this array to the labels, as follows: $labelAttributes = ['class'=>'col-md-4 control-label']; Here is the form label code: {!! Form::label('email', 'E-Mail Address', $labelAttributes) !!} {!! Form::label('password', 'Password', $labelAttributes) !!} Checkbox To convert the checkbox to a facade, we will convert this: <input type="checkbox" name="remember"> Remember Me The preceding code is converted to the following code: {!! Form::checkbox('remember','') !!} Remember Me Remember that the PHP parameters should be sent in single quotation marks if there are no variables or other special characters, such as line breaks, inside the string to parse, while the HTML produced will have double quotes. The submit button Lastly, the submit button will be converted as follows: <button type="submit" class="btn btn-primary" style="margin-right: 15px;"> Login </button> The preceding code after conversion is as follows:   {!! Form::submit('Login', ['class'=>'btn btn-primary', 'style'=>'margin-right: 15px;']) !!} Note that the array parameter provides an easy way to provide any desired attributes, even those that are not among the list of standard HTML form elements. The anchor tag with links To convert the links, a helper method is used. Consider the following line of code: <a href="/password/email">Forgot Your Password?</a> The preceding line of code after conversion becomes: {!! link_to('/password/email', $title = 'Forgot Your Password?', $attributes = array(), $secure = null) !!} The link_to_route() method may be used to link to a route. For similar helper functions, visit http://laravelcollective.com/docs/5.0/html. Closing the form To end the form, we'll convert the traditional HTML form tag </form> to a Laravel {!! Form::close() !!} form method. The resultant form By putting everything together, the page now looks like this: @extends('app') @section('content') <div class="container-fluid"> <div class="row"> <div class="col-md-8 col-md-offset-2"> <div class="panel panel-default"> <div class="panel-heading">Login</div> <div class="panel-body"> @if (count($errors) > 0) <div class="alert alert-danger"> <strong>Whoops!</strong> There were some problems with your input.<br><br> <ul> @foreach ($errors->all() as $error) <li>{{ $error }}</li> @endforeach </ul> </div> @endif <?php $inputAttributes = ['class'=>'form-control']; $labelAttributes = ['class'=>'col-md-4 control-label']; ?> {!! Form::open(['class'=>'form-horizontal','role'=> 'form','method'=>'POST','url'=>'/auth/login']) !!} <div class="form-group"> {!! Form::label('email', 'E-Mail Address',$labelAttributes) !!} <div class="col-md-6"> {!! Form::input('email','email',old('email'), $inputAttributes) !!} </div> </div> <div class="form-group"> {!! Form::label('password', 'Password',$labelAttributes) !!} <div class="col-md-6"> {!! Form::input('password', 'password',null,$inputAttributes) !!} </div> </div> <div class="form-group"> <div class="col-md-6 col-md-offset-4"> <div class="checkbox"> <label> {!! Form::checkbox('remember','') !!} Remember Me </label> </div> </div> </div> <div class="form-group"> <div class="col-md-6 col-md-offset-4"> {!! Form::submit('Login',['class'=> 'btn btn-primary', 'style'=> 'margin-right: 15px;']) !!} {!! link_to('/password/email', $title = 'Forgot Your Password?', $attributes = array(), $secure = null); !!} </div> </div> {!! Form::close() !!} </div> </div> </div> </div> </div> @endsection Our example If we want to create a form to reserve a room in our accommodation, we can easily call a route from our controller: /** * Show the form for creating a new resource. * * @return Response */ public function create() { return view('auth/reserve'); } Now we need to create a new view that is located at resources/views/auth/reserve.blade.php. In this view, we can create a form to reserve a room in an accommodation where the user can select the start date, which comprises of the start day of the month and year, and the end date, which also comprises of the start day of the month and year. The form would begin as before, with a POST to reserve-room. Then, the form label would be placed next to the select input fields. Finally, the day, the month, and the year select form elements would be created as follows: {!! Form::open(['class'=>'form-horizontal', 'role'=>'form', 'method'=>'POST', 'url'=>'reserve-room']) !!} {!! Form::label(null, 'Start Date',$labelAttributes) !!} {!! Form::selectMonth('month',date('m')) !!} {!! Form::selectRange('date',1,31,date('d')) !!} {!! Form::selectRange('year',date('Y'),date('Y')+3) !!} {!! Form::label(null, 'End Date',$labelAttributes) !!} {!! Form::selectMonth('month',date('m')) !!} {!! Form::selectRange('date',1,31,date('d')) !!} {!! Form::selectRange('year',date('Y'), date('Y')+3,date('Y')) !!} {!! Form::submit('Reserve', ['class'=>'btn btn-primary', 'style'=>'margin-right: 15px;']) !!} {!! Form::close() !!} Month select Firstly, in the selectMonth method, the first parameter is the name of the input attribute, while the second attribute is the default value. Here, the PHP date method is used to extract the numeric portion of the current month—March in this case: {!! Form::selectMonth('month',date('m')) !!} The output, shown here formatted, is as follows: <select name="month"> <option value="1">January</option> <option value="2">February</option> <option value="3" selected="selected">March</option> <option value="4">April</option> <option value="5">May</option> <option value="6">June</option> <option value="7">July</option> <option value="8">August</option> <option value="9">September</option> <option value="10">October</option> <option value="11">November</option> <option value="12">December</option> </select> Date select A similar technique is applied for the selection of the date, but using the selectRange method, the range of the days in the month are passed to the method. Similarly, the PHP date function is used to send the current date to the method as the fourth parameter: {!! Form::selectRange('date',1,31,date('d')) !!} Here is the formatted output: <select name="date"> <option value="1">1</option> <option value="2">2</option> <option value="3">3</option> <option value="4">4</option> ... <option value="28">28</option> <option value="29">29</option> <option value="30" selected="selected">30</option> <option value="31">31</option> </select> The date that should be selected is 30, since today is March 30, 2015. For the months that do not have 31 days, usually a JavaScript method would be used to modify the number of days based on the month and/or the year. Year select The same technique that is used for the date range is applied for the selection of the year; once again, using the selectRange method. The range of the years is passed to the method. The PHP date function is used to send the current year to the method as the fourth parameter: {!! Form::selectRange('year',date('Y'),date('Y')+3,date('Y')) !!} Here is the formatted output: <select name="year"> <option value="2015" selected="selected">2015</option> <option value="2016">2016</option> <option value="2017">2017</option> <option value="2018">2018</option> </select> Here, the current year that is selected is 2015. Form macros We have the same code that generates our month, date, and year selection form block two times: once for the start date and once for the end date. To refactor the code, we can apply the DRY (don't repeat yourself) principle and create a form macro. This will allow us to avoid calling the form element creation method twice, as follows: <?php Form::macro('monthDayYear',function($suffix='') { echo Form::selectMonth(($suffix!=='')?'month- '.$suffix:'month',date('m')); echo Form::selectRange(($suffix!=='')?'date- '.$suffix:'date',1,31,date('d')); echo Form::selectRange(($suffix!=='')?'year- '.$suffix:'year',date('Y'),date('Y')+3,date('Y')); }); ?> Here, the month, date, and year generation code is placed into a macro, which is inside the PHP tags, and it is necessary to add echo to print out the result. The monthDayYear name is given to this macro method. Calling our macro two times: once after each label; each time adding a different suffix via the $suffix variable. Now, our form code looks like this: <?php Form::macro('monthDayYear',function($suffix='') { echo Form::selectMonth(($suffix!=='')?'month- '.$suffix:'month',date('m')); echo Form::selectRange(($suffix!=='')?'date- '.$suffix:'date',1,31,date('d')); echo Form::selectRange(($suffix!=='')?'year- '.$suffix:'year',date('Y'),date('Y')+3,date('Y')); }); ?> {!! Form::open(['class'=>'form-horizontal', 'role'=>'form', 'method'=>'POST', 'url'=>'/reserve-room']) !!} {!! Form::label(null, 'Start Date',$labelAttributes) !!} {!! Form::monthDayYear('-start') !!} {!! Form::label(null, 'End Date',$labelAttributes) !!} {!! Form::monthDayYear('-end') !!} {!! Form::submit('Reserve',['class'=>'btn btn-primary', 'style'=>'margin-right: 15px;']) !!} {!! Form::close() !!} Conclusion The choice to include the HTML form generation package in Laravel 5 can ease the burden of having to create numerous HTML forms. This approach allows developers to use methods, create reusable macros, and use a familiar Laravel approach to build the frontend. Once the basic methods are learned, it is very easy to simply copy and paste the previously created form elements, and then change their element's name and/or the array that is sent to them. Depending on the size of the project, this approach may or may not be the right choice. For a very small application, the difference in the amount of code that needs to be written is not very evident, although, as is the case with the selectMonth and selectRange methods, the amount of code necessary is drastic. This technique, combined with the use of macros, makes it easy to reduce the occurrence of copy duplication. Also, one of the major problems with the frontend design is that the contents of the class of the various elements may need to change throughout the entire application. This would mean performing a large find and replace operation, where changes are required to be made to HTML, such as changing class attributes. By creating an array of attributes, including class, for similar elements, changes made to the entire form can be performed simply by modifying the array that those elements use. In a larger project, however, where parts of forms may be repeated throughout the application, the wise use of macros can easily reduce the amount of code necessary to be written. Not only this, but macros can isolate the code inside from changes that would require more than one block of code to be changed throughout multiple files. In the example, where the month, date, and year is to be selected, it is possible that this could be used up to 20 times in a large application. Any changes made to the desired block of HTML can be simply done to the macro and the result would be reflected in all of the elements that use it. Ultimately, the choice of whether or not to use this package will reside with the developer and the designer. Since a designer who wants to use an alternative frontend design tool may not prefer, nor be competent, to work with the methods in the package, he or she may want to not use it. Summary The construction of the master template was explained and then the form components, such as the various form input types, were shown through examples. Finally, the construction of a form for the room reservation, was explained, as well as a "do not repeat yourself" form macro creation technique. Resources for Article: Further resources on this subject: Eloquent… without Laravel! [Article] Laravel 4 - Creating a Simple CRUD Application in Hours [Article] Exploring and Interacting with Materials using Blueprints [Article]
Read more
  • 0
  • 0
  • 3814

article-image-using-spring-jmx-within-java-applications
Packt
04 Aug 2010
6 min read
Save for later

Using Spring JMX within Java Applications

Packt
04 Aug 2010
6 min read
(For more resources on Java, see here.) Yet for all its powerful capabilities, JMX is greatly underutilized and few developers seem to take advantage of its power. I attribute this underutilization to two factors: the scope of the Java universe as well as JMX's complex development model. As a deep and wide universe composed of a seemingly infinite number of tools, frameworks, design patterns and a never ending stream of new thoughts and ideas, I believe that JMX rarely finds itself on the list of the next technologies a developer plans to explore. While other shiny objects steal the Java community spotlight, the benefits of JMX patiently wait to be discovered and seem to largely be the playing field of only seasoned Java veterans who have had the time or industry longevity to have already encountered it. In regard to its complex development model, JMX itself has an extremely low level, clumsy, and obtrusive API and that has directly hindered its adoption. While this complex development model is a fact of JMX life, the Spring framework, as with numerous other aspects of Java development, offers excellent JMX support that greatly simplifies and radically reduces the learning curve and time investment required to incorporate JXM into your application. Spring's JMX support transforms JMX from an obscure API into what could become a central component of your application's architecture. While all of this sounds great, a tangible example of how easy it is to incorporate Spring JMX (and therefore JMX itself) into your application will make things more concrete. The following code and configuration sample presents a classic example of the benefits of JMX and is a piece of functionality which has proven its usefulness dozens upon dozens of times within my career: the ability to dynamically change an application's Log4j log level at runtime. Example 1: package com.spiegssoftware.common.util.management.logging; import org.apache.log4j.Category; import org.apache.log4j.Level; import org.apache.log4j.LogManager; import org.apache.log4j.Logger; import org.springframework.jmx.export.annotation.ManagedOperation; /** * MBean exposing Log4j management operations. * <p> * This code is based on an example provided from http://uri.jteam.nl/?p=4 . */ public class Log4jJmxService { /** Logger for this class. */ private final Logger logger = Logger.getLogger(Log4jJmxService.class); @ManagedOperation(description = "Set this Logger to the DEBUG level") public boolean activateDebug(final String category) { return adjustLogLevel(category, Level.DEBUG); } @ManagedOperation(description = "Set this Logger to the INFO level") public boolean activateInfo(final String category) { return adjustLogLevel(category, Level.INFO); } @ManagedOperation(description = "Set this Logger to the WARN level") public boolean activateWarn(final String category) { return adjustLogLevel(category, Level.WARN); } @ManagedOperation(description = "Set this Logger to the ERROR level") public boolean activateError(final String category) { return adjustLogLevel(category, Level.ERROR); } @ManagedOperation(description = "Set this Logger to the FATAL level") public boolean activateFatal(final String category) { return adjustLogLevel(category, Level.FATAL); } protected boolean adjustLogLevel(final String category, final Level level) { boolean result = false; Category cat = LogManager.exists(category); if (cat == null) { logger.error("Logger '" + category + "' does not exist"); } else { logger.info("Activating " + level + " for category: " + category); cat.setLevel(level); result = true; } return result; } }   Example 2: <?xml version="1.0" encoding="UTF-8"?> <beans xsi_schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd"> <bean id="log4jJmxService" class="com.spiegssoftware.common.util.management.logging.Log4jJmxService" /> <bean id="exporter" class="org.springframework.jmx.export.MBeanExporter"> <property name="beans"> <util:map id="beans"> <entry key="com.spiegssoftware.common.util.management.logging:name=Log4jJmxService" value="log4jJmxService"/> </util:map> </property> </bean> </beans>   Based on code publicly available from Dev Thoughts, the class in Example 1 was decorated with Spring JMX annotations and the necessary Spring configuration was created in Example 2. To incorporate this functionality into your application, you will need to include this class (along with Spring JMX's dependencies) and the configuration into your project, rebuild, and deploy. Before starting your application server, you may need to enable its support for JMX; see the documentation for your specific application server for details. After your application server has started with JMX support enabled, any JMX console, such as the jConsole tool that ships with all recent JDK's, can be used to connect to the JVM the application is running within and the application's logging level can be adjusted without requiring a restart. The details of how to use jConsole are best left to its documentation, but for the impatient, jConsole can by be launched by opening a command window and issuing a "jconsole" command just as you would issue a "java -version". From there, select which JVM you wish to connect to; most likely you will want to connect to a local process. After selecting the MBeans tab, use the left hand navigation and find the Log4jJmxService under the key name you registered it under within your Spring configuration file; in Example 2 we chose to use a value of "log4jJmxService". After selecting the Log4jJmxService from the jConsole tree navigation and drilling down, you are presented with a screen that represents all of the public methods available on the Log4jJmxService. Simply clicking the invoke button next to each available public method results in the specified method on the Log4jJmxService being invoked just as if the bean's method had been invoked through traditional application user input; the application is unaware and indifferent as to the source of the invocation request and the normal execution flow takes place. You now have the ability to dynamically change the log level of your application at runtime. This JMX stuff is great, hu? With your toe now in the JMX waters, you're undoubtedly thinking of the numerous ways JMX can be incorporated within your applications: to inspect or alter application configuration, to access statistical data held within an application memory, or to manage an application by invoking application logic – all at runtime! JMX's uses are limited only by your creativity to incorporate it. JMX is so powerful and exposing your Spring based components through Spring JMX is so easy and convenient that it's likely you'll quickly find yourself wanting to expose every Spring bean throughout your entire application. While the two configuration strategies provided by Spring JMX (annotating classes or configuring beans in XML) are suitable for configuring a relatively low number of beans, when applied on a large scale each strategy has the disadvantage that it becomes tedious, verbose, and is the epitome of boilerplate; few would dispute that very quickly either your code or configuration becomes cluttered with JMX metadata. Having previously fallen into this advantageous trap of wanting to expose all Spring beans within an application multiple times before myself, it was time to take a step back and determine if this could accomplished in a better way.
Read more
  • 0
  • 0
  • 3813
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 $19.99/month. Cancel anytime
article-image-integrating-moodle-20-alfresco-manage-content-business
Packt
29 Apr 2011
8 min read
Save for later

Integrating Moodle 2.0 with Alfresco to Manage Content for Business

Packt
29 Apr 2011
8 min read
  Moodle 2.0 for Business Beginner's Guide Implement Moodle in your business to streamline your interview, training, and internal communication processes. The Repository integration allows admins to set up external content management systems and use them to complement Moodle's own file management system. Using this integration you can now manage content outside of Moodle and publish it to the system once the document or other content is ready. The Portfolio integration enables users to store their Moodle content in an external e-portfolio system to share with evaluators, peers, and others. Managing content in repositories The repository system of Moodle 2 allows you to store and manipulate content outside of Moodle and easily add it to courses. By managing content outside of Moodle, you can provide users with a more robust editing experience. Many organizations utilize workflows and approval processes to ensure the accuracy of the content used in the LMS. A content repository can help you manage that process, and then make the content available on Moodle when it is ready for final publication. Using Alfresco to manage content Alfresco is an open source, enterprise content management system, similar in many ways to Microsoft Sharepoint or EMC's Documentum. Alfresco has seen widespread adoption over the last few years as more people begin to recognize the advantages of open source software. We will start by installing Alfresco, then look at how to link it to Moodle and add content to a Moodle site. At the end of this section, we'll take a look at Alfresco's content conversion services as a tool to ensure content is reliably converted to web friendly formats. Time for action - installing Alfresco on your test site To get us started, we'll install Alfresco on our test system to experiment with the integration. Alfresco runs on a different architecture than Moodle. Alfresco requires a Java application server instead of PHP. Fortunately, there are installers available on the Alfresco site that include everything we will need to develop a test system on your local computer. To install Alfresco, run through the following steps: Open your browser and go to http:www.alfresco.com. Go to the Downloads tab and select the Download Now button for Alfresco Document Management in the Community Edition column. Select the installer for your operating system and download it to your computer. Double-click on the installer (it may take a moment to get started). Select your language for the installer. Choose the database option you want to use. Use the included database, unless you have a good reason not to. When prompted, enter a database password. Be sure to write it down somewhere. The next screen will prompt you for an Alfresco admin password. Definitely write this down. The final screen will prompt you to choose the packages you want to install. Choose the defaults and click on Next. For the examples below, you will need to make sure that you have the OpenOffice component installed. The installer will begin to run. This will probably take a while, so it may be time to go and get a cup of tea. Once the installer is complete, select Launch. This will take a while as well, so a second cup of tea might be in order. Once Alfresco has launched, you can configure the interface with Moodle. What just happened You now have a full-functioning open source enterprise content management system installed on your personal computer. Alfresco has a lot of power for manipulating and sharing documents, but we will only focus on a few features for now. There are a lot of books available to help you learn how to use the more advanced features in Alfresco (a few of them from this publisher as well). Time for action - add a repository plugin to Moodle To allow users to access your new Alfresco repository, you will need to configure Moodle to allow access to the repository. The new repository architecture of Moodle 2 enables developers to create plugins to connect Moodle with other systems. Each system will have its own type of plugin to allow a direct connection between Moodle and the system. To enable Moodle to talk to an external repository, we need to enable the plugin and any associated options. To enable the Alfresco repository plug-in, go through the following steps: Login to Moodle as a Moodle admin. From the Site administration menu, select Plugins and then Repositories. The Manage repositories screen allows you to select from all of the available plugin repositories. For now, we will focus on the Alfresco repository. From the menu in the Active column, select Enabled and visible.The Alfresco plugin allows users in Moodle to add multiple instances of the repository. Most of the time, you will not want to allow users to add additional instances of the repository. As the admin, you can create a single site-wide instance of the repository plugin to allow users to link to Alfresco files. However, if you have more than one Alfresco instance, you can allow multiple users to create additional repositories at either the course level or the user level. Click the Save button to save the initial settings. This will return you to the Manage repositories page. Click on Settings under the Settings column to the right of the Alfresco repository row. This will take you back to the Alfresco settings page, but will provide an additional ability to add a repository instance at the site level. Click the Create a repository instance button at the bottom of the page. Give the name of your Alfresco instance. If this is an institutional repository, give it the same name as you commonly use. For example, if you commonly refer to your Alfresco instance as the "ECM" (for Enterprise Content Management), name the Alfresco instance ECM. Add the URL of your Alfresco site. Be sure to point to the Alfresco Explorer, not the Share application. You will also need to add the API pointer at the end of the string. For example, if you are pointing to the locally installed Alfresco which we described in the preceding case, the URL should be http://127.0.0.1:8080/alfresco/api. Click on Save. You will now have an instance of Alfresco available for users to add content to their courses. If you get the following error: Notice SOAP extension must be enabled for Alfresco plugin, then make sure that the SOAP library is enabled in your php.ini file. The location of the file will vary depending on the system you are using. Find the php.ini file and un-comment the extension=php_soap.dll line. Then restart Moodle and this should solve the error. What just happened You have just configured the Alfresco repository plugin to enable Moodle to talk to Alfresco. When you bring up the file picker in a course or at the site level, you should now see the Alfresco repository as an option. Have a go hero In the next article, we will configure the Google Docs plugin for Moodle, but there are a number of other plugins. Picasa and Flickr are two photo repositories on the web where many people share their photos. Wikimedia and YouTube are two very popular sources of media as well. Enable one or two of these additional plugins to practice configuring Moodle on your own. Time for action - adding content to Alfresco In Moodle 2, repository integrations are read-only. The Moodle design team decided the repository integration should only read from repositories, and the portfolio integration should save content to portfolio repositories. So you can't add content directly to Alfresco with the default plugin. To add content to the repository, we need to use the repository's own interface, then we can add it to Moodle. With Alfresco, that interface is either the Alfresco Explorer or Alfresco Share. To add content to the repository using Share, run through the following steps: Go to your Alfresco share interface, found at http://<your Alfresco server>/share. If your Alfresco is on your local machine with the default install, go to http://127.0.0.1:8080/share. Login with your username and password. Select the Repository link from the top of the page. This will display the folder structure for the default Alfresco repository. Select User Homes and then select your user space. From the menu above the file browser, select Upload. Click on the Select file(s) to upload button at the top of the Upload Files screen. Browse to find your file and then click on the Upload File(s) button. The file you selected should now appear in the file browser. What just happened You have now added a file to your Alfresco repository. We've explored a very simple example of adding a single file with no workflow or approval needed. You can use Share to create content, share it with colleagues, and use versioning and other features to manage the content creation process. Have a go hero Now that you've added a simple file to Alfresco Share, try some of the other features. Check out a file for editing, change it and check it back in for others to use, or create some content directly in Share.
Read more
  • 0
  • 0
  • 3810

article-image-more-things-you-can-do-oracle-content-server-workflows
Packt
09 Aug 2010
5 min read
Save for later

More Things you can do with Oracle Content Server workflows

Packt
09 Aug 2010
5 min read
(For more resources on Oracle, see here.) The top three things As we've just seen, the most common things you can do are these: Get content approved: This is the most obvious use of the workflow we've just seen. Get people notified: Remember when we were adding workflow steps there was a number of required approvers on the Exit Conditions tab in the Add New Step dialog. If we set that to zero we accomplish one important thing: Approvers will get notified, but no action is required of them. It's a great way to "subscribe" a select group of people to an event of your choice. Perform custom actions: And if that's not enough you can easily add custom scripts to any step of a workflow. You can change metadata, release items, and send them to other workflows. You can even invoke your custom Java code. And here's another really powerful thing you can do with custom workflow actions. You can integrate with other systems and move from the local workflow to process orchestration. You can use a Content Server workflow to trigger external processes. UCM 10gR3 has an Oracle BPEL integration built in. This means that a UCM workflow can be initiated by (or can itself initiate) a BPEL workflow that spans many systems, not just the UCM. This makes ERP systems such as Siebel, PeopleSoft, SAP, and Oracle e-Business Suite easily accessible to the UCM, and content inside the UCM can be easily made available to these systems. So let's look at the jumps and scripting. Jumps and scripting Here's how to add scripting to a workflow: In Workflow Admin select a step of a workflow we've just created. Click on the Edit button on the right. The Edit Step dialog comes up. Go to the Events tab (as shown in the following screenshot): There are three events that you can add custom handlers for: Entry: This event triggers when an item arrives at the step. Update: This happens when an item or its metadata is updated. It's also initiated every hour by a timer event, Workflow Update Cycle. Use it for sending reminders to approvers or escalating the item to an alternative person after your approval period has expired. Exit: This event is triggered when an item has been approved and is about to exit the step. If you have defined Additional Exit Conditions on the Exit Conditions tab then those will be satisfied before this event fires. The following diagram illustrates the sequence of states and corresponding events that are fired when a content item arrives at a workflow step: Great! But how do we can actually add the jumps and custom scripts to a workflow step? How to add a jump to a workflow step Let's add an exception where content submitted by sysadmin will bypass our Manager Approval workflow. We will use a jump—a construct that causes an item to skip the normal workflow sequence and follow an alternative path. Here's how to do it: Add a jump to an Entry event of our very first step. On the Events tab of the Edit Step dialog, click on the Edit button—the one next to the Entry event. The Edit Script dialog displays (as shown in the following screenshot): Click on the Add button. The Add Jump dialog comes up (as shown in the following screenshot): Let's call the jump Sysadmin WF bypass. You don't need to change anything else at this point. Click on OK to get back to the Edit Script dialog. In the Field drop-down box pick Author. Click on the Select… button next to the Value box. Pick sysadmin (if you have trouble locating sysadmin in the list of users, make sure that the filter check-box is un-checked). Click the Add button below the Value field. Make sure that your clause appears in the Script Clauses box below. In the Target Step dropdown pick Next Step. Once you have done so the value will change to its script equivalent, @wfCurrentStep(1). If you have more than one step in the workflow, change 1 to the number of steps you have. This will make sure that you jump past the last step and exit the workflow. Here's how the completed dialog will look (as shown in the following screenshot): Click on OK to close. You're now back to the Events tab on the Edit Step dialog. Notice a few lines of script being added to the box next to the Entry event (as shown in the following screenshot): OK the dialog. It's time to test your changes. Check in a new document. Make sure you set the Author field to sysadmin. Set your Security Group to accounting, and Account to accounting/payable/current. If you don't, the item will not enter our workflow in the first place (as shown in the following screenshot): Complete your check-in and follow the link to go to the Content Info page. See the status of the item. It should be set to Released. That's right. The item got right out of the workflow. Check in a new document again, but use some other author. Notice how your item will enter the workflow and stay there. As you've seen, the dialog we used for creating a jump is simply a code generator. It created a few lines of script we needed to add the handler for the Entry event. Click on the Edit button next to that code and pick Edit Current to study it. You can find all the script function definitions in iDoc Reference Guide. Perfect! And we're still not done. What if you have a few common steps that you'd like to reuse in a bunch of workflows? Would you just have to manually recreate them? Nope. There are several solutions that allow you to reuse parts of the workflow. The one I find to be most useful is sub workflows.
Read more
  • 0
  • 0
  • 3809

article-image-routing-kohana-3
Packt
12 Sep 2011
8 min read
Save for later

Routing in Kohana 3

Packt
12 Sep 2011
8 min read
  (For more resources on this topic, see here.) The reader can benefit from the previous article on Request Flow in Kohana 3. Routing in Kohana If you remember, the bootstrap file comes preconfigured with a default route that follows a very simple structure: Route::set(‘default’, ‘(<controller>(/<action>(/<id>)))’) ->defaults(array( ‘controller’ => ‘welcome’, ‘action’ => ‘index’, )); This tells Kohana that when it parses the URL for any request, it first finds the base_url, and then the next segment will contain the controller, then the action, then an ID. These are all optional setgments, with the default controller and action being set in the array. We have taken advantage of this route with other controllers like our Profile and Message controller. When we visit http://localhost/egotist/profile, the route sets the controller to profile, and since no action or ID is explicitly defined in the URL, the default action of ‘index’ is used. When we requested http://localhost/egotist/messages/get_messages from within our Profile Controller, we also followed this route; however, neither defaults were needed, and the route asked for the Messages Controller and its get_messages action. In our Profile controller, we are only using one array of example messages to test functionality and the expected behavior of our application. When we implement a data store and have multiple users with profiles in our application, we will need a way to decipher which profile a user wants to see. Because the default route already has an available parameter for ID, we can use that to pass an ID to our Profile Controller’s index action, and have the messages controller then find the proper messages for that user.   Time for action – Making profiles dynamic using ID Once a database is tied to our application, and more than one user has a profile, we will need some way of knowing which profile to display. A simple and effective way to do this is to pass a user ID in the route, and have our controller use that ID to find the right messages for the right user. Let’s add some more test data to our messages system, and use an ID to display the right messages. Open the Profile Controller in our application/classes/controller/ directory named profile.php. Since the action_index() method is the controller action that is called when a profile is viewed, we will need to edit it to look for the ID parameter in the URI like this: public function action_index(){ $content = View::factory(<profile/public>) ->set(<username>, <Test User>) ->bind(<messages>, $messages); $id = (int) $this->request->param(‘id’); $messages_uri = "messages/get_messages/$id"; $messages = Request::factory($messages_uri)->execute()->response; $this->template->content = $content;} Now, we are retrieving the ID from the route and passing it along in our request to the Messages Controller. This means that class must also be updated. Open the messages.php file located in application/classes/controllers/ and modify its action_get_messages() method as follows: public function action_get_messages(){ $id = (int) $this->request->param(‘id’); $messages = array( 1 => array( ‘This is test message one for user 1’, ‘This is test message two for user 1’, ‘This is test message three for user 1’ ), 2 => array( ‘This is test message one for user 2’, ‘This is test message two for user 2’, ‘This is test message three for user 2’ ) ); $messages = array_key_exists($id, $messages) ? $messages[$id] :NULL; $this->request->response = View::factory(‘profile/messages’) ->set(‘messages’, $messages);} Open the page http://localhost/egotist/profile/index/2/. It should look like this: Browsing to http://localhost/egotist/profile/index/1/ will show the messages for user 1, i.e., the test messages placed in the message array under key 1. What just happened? At the very beginning of our index action in our Profile Controller, we set our $id variable by getting the ID parameter from the route. Since Kohana has parsed our route for us, we can now access these parameters via the request object’s param() method. Once we got the ID variable, we then created and executed the request for the message controller’s get_messages action, and passed the ID to that method for it to use. In the Message Controller, we used the same method to extract the ID from the request, and then used that ID to determine which messages from the messages array to display. Although this works fine for illustrating routing for these two users, the code is far from ready, even without a data store or real user data, but it does show how the parameters can be read and used. Because most of the functionality in the controller will be replaced with our database and more precise data being passed around, we can overlook the incompleteness of the current controller actions, and begin looking at creating a URL that is better looking than http://localhost/egotist/profile/index/2/ for finding a user profile by ID. Creating friendly URLs using custom routes Consider how nice it would be if our users could browse to a profile without putting ‘index’ in the action portion of the URI, like this: http://localhost/egotist/profile/2. This looks much more pleasing, and is more in line with what we would like our URLs to look like in web apps. It is in fact very easy to have Kohana use a route to remove the index action from the URI. Routes not only make our URLs more pleasing and descriptive, but they make our application easier to maintain in the long run. We have more control over where our users are being directed from how the URL is constructed, without having to create controller actions designed to handle routing.   Time for action – Creating a Custom Route So far, we have been using the default route that is in our application bootstrap. As our application grows, so will the number of available ‘starting points’ for our user’s requests. Not every controller, action, or parameter has to comply with the default route, and this gives us a lot of flexibility and freedom. We can add a custom route to handle user’s profiles by adding it to our bootstrap.php file. Open the bootstrap.php file located in application/directory and modify the routes block so it looks like this: /** * Set the routes.Each route must have a minimum of a name,a URI * and a set of defaults for the URI. */Route::set(‘profile’, ‘profile/<id>’) ->defaults(array( ‘controller’ => ‘profile’, ‘action’ => ‘index’, ));Route::set(‘default’, ‘(<controller>(/<action>(/<id>)))’) ->defaults(array( ‘controller’ => ‘welcome’, ‘action’ => ‘index’, )); Now, we can view the profile pages without having to pass the index action in the URL. Open http://localhost/egotist/profile/2 in a browser; it should look like this: Browsing to profiles with a more friendly URL is made possible through Kohana’s routes. What just happened? By setting routes using the Route::set static method, we are essentially creating filters that will be used to match requests with routes. We can name these routes; in this case we have one named default, and one named profile. Kohana uses the second parameter in the set() method to compare against the requested URI, and will call the first route that matches the request. Because it uses the first route that matches the request, it is very important when ordering route definitions. If we put the default route before the profile route, the profile route will never be used, as the default route would always match first. Because it looks for a match, it does not use discretion when determining the right route for a request. So if we browse to http://localhost/egotist/profile/index/2, we will be directed to the default route, and get the same result. The default route may not be available for all the routes we create in the future, so create routes that are as explicit as we can for our needs. Right now, our application assumes any data that is passed after a controller segment named ‘profile’ must be the ID for which we are looking. In our current application setup, we only need digits. If a user passes data into the URL that is not numeric for the ID parameter, we do not want it to go to that route. This can be accomplished easily inside the Route::set() method.  
Read more
  • 0
  • 0
  • 3791

article-image-nsb-and-security
Packt
06 Feb 2015
14 min read
Save for later

NSB and Security

Packt
06 Feb 2015
14 min read
This article by Rich Helton, the author of Learning NServiceBus Sagas, delves into the details of NSB and its security. In this article, we will cover the following: Introducing web security Cloud vendors Using .NET 4 Adding NServiceBus Benefits of NSB (For more resources related to this topic, see here.) Introducing web security According to the Top 10 list of 2013 by the Open Web Application Security Project (OWASP), found at https://www.owasp.org/index.php/Top10#OWASP_Top_10_for_2013, injection flaws still remain at the top among the ways to penetrate a web site. This is shown in the following screenshot: An injection flaw is a means of being able to access information or the site by injecting data into the input fields. This is normally used to bypass proper authentication and authorization. Normally, this is the data that the website has not seen in the testing efforts or considered during development. For references, I will consider some slides found at http://www.slideshare.net/rhelton_1/cweb-sec-oct27-2010-final. An instance of an injection flaw is to put SQL commands in form fields and even URL fields to try to get SQL errors and returns with further information. If the error is not generic, and a SQL exception occurs, it will sometimes return with table names. It may deny authorization for sa under the password table in SQL Server 2008. Knowing this gives a person knowledge of the SQL Server version, the sa user is being used, and the existence of a password table. There are many tools and websites for people on the Internet to practice their web security testing skills, rather than them literally being in IT security as a professional or amateur. Many of these websites are well-known and posted at places such as https://www.owasp.org/index.php/Phoenix/Tools. General disclaimer I do not endorse or encourage others to practice on websites without written permission from the website owner. Some of the live sites are as follows, and most are used to test web scanners: http://zero.webappsecurity.com/: This is developed by SPI Dynamics (now HP Security) for Web Inspect. It is an ASP site. http://crackme.cenzic.com/Kelev/view/home.php: This PHP site is from Cenzic. http://demo.testfire.net/: This is developed by WatchFire (now IBM Rational AppScan). It is an ASP site. http://testaspnet.vulnweb.com/: This is developed by Acunetix. It is a PHP site. http://webscantest.com/: This is developed by NT OBJECTives NTOSpider. It is a PHP site. There are many more sites and tools, and one would have to research them themselves. There are tools that will only look for SQL Injection. Hacking professionals who are very gifted and spend their days looking for only SQL injection would find these useful. We will start with SQL injection, as it is one of the most popular ways to enter a website. But before we start an analysis report on a website hack, we will document the website. Our target site will be http://zero.webappsecurity.com/. We will start with the EC-Council's Certified Ethical Hacker program, where they divide footprinting and scanning into seven basic steps: Information gathering Determining the network range Identifying active machines Finding open ports and access points OS fingerprinting Fingerprinting services Mapping the network We could also follow the OWASP Web Testing checklist, which includes: Information gathering Configuration testing Identity management testing Authentication testing Session management testing Data validation testing Error handling Cryptography Business logic testing Client-side testing The idea is to gather as much information on the website as possible before launching an attack, as there is no information gathered so far. To gather information on the website, you don't actually have to scan the website yourself at the start. There are many scanners that scan the website before you start. There are Google Bots gathering search information about the site, the Netcraft search engine gathering statistics about the site, as well as many domain search engines with contact information. If another person has hacked the site, there are sites and blogs where hackers talk about hacking a specific site, including what tools they used. They may even post security scans on the Internet, which could be found by googling. There is even a site (https://archive.org/) that is called the WayBack Machine as it keeps previous versions of websites that it scans for in archive. These are just some basic pieces, and any person who has studied for their Certified Ethical Hacker's exam should have all of this on their fingertips. We will discuss some of the benefits that Microsoft and Particular.net have taken into consideration to assist those who develop solutions in C#. We can search at http://web.archive.org/web/ or http://zero.webappsecurity.com/ for changes from the WayBack Machine, and we will see something like this: From this search engine, we look at what the screens looked like 2003, and walk through various changes to the present 2014. Actually, there were errors on archive copying the site in 2003, so this machine directed us to the first best copy on May 11, 2006, as shown in the following screenshot: Looking with Netcraft, we can see that it was first started in 2004, last rebooted in 2014, and is running Ubuntu, as shown in this screenshot: Next, we can try to see what Google tells us. There are many Google Hacking Databases that keep track of keywords in the Google Search Engine API. These keywords are expressions such as file: passwd to search for password files in Ubuntu, and many more. This is not a hacking book, and this site is well-known, so we will just search for webappsecurity.com file:passwd. This gives me more information than needed. On the first item, I get a sample web scan report of the available vulnerabilities in the site from 2008, as shown in the following screenshot: We can also see which links Google has already found by running http://zero.webappsecurity.com/, as shown in this screenshot: In these few steps, I have enough information to bring a targeted website attack to check whether these vulnerabilities are still active or not. I know the operating system of the website and have details of the history of the website. This is before I have even considered running tools to approach the website. To scan the website, for which permission is always needed ahead of time, there are multiple web scanners available. For a list of web scanners, one website is http://sectools.org/tag/web-scanners/. One of the favorites is built by the famed Googler Michal Zalewski, and is called skipfish. Skipfish is an open source tool written in the C language, and it can be used in Windows by compiling it in Cygwin libraries, which are Linux virtual libraries and tools for Windows. Skipfish has its own man pages at http://dev.man-online.org/man1/skipfish/, and it can be downloaded from https://code.google.com/p/skipfish/. Skipfish performs web crawling, fuzzing, and tests for many issues such as XSS and SQL Injection. In Skipfish's case, its fussing uses dictionaries to add more paths to websites, extensions, and keywords that are normally found as attack vectors through the experience of hackers, to apply to the website being scanned. For instance, it may not be apparent from the pages being scanned that there is an admin/index.html page available, but the dictionary will try to check whether the page is available. Skipfish results will appear as follows: The issue with Skipfish is that it is noisy, because of its fuzzer. Skipfish will try many scans and checks for links that might not exist, which will take some time and can be a little noisy out of the box. There are many configurations, and there is throttling of the scanning to try to hide the noise. An associated scan in HP's WebInspect scanner will appear like this: These are just automated means to inspect a website. These steps are common, and much of this material is known in web security. After an initial inspection of a website, a person may start making decisions on how to check their information further. Manually checking websites An experienced web security person may now start proceeding through more manual checks and less automated checking of websites after taking an initial look at the website. For instance, type Admin as the user ID and password, or type Guest instead of Admin, and the list progresses based on experience. Then try the Admin and password combination, then the Admin and password123 combination, and so on. A person inspecting a website might have a lot of time to try to perform penetration testing, and might try hundreds of scenarios. There are many tools and scripts to automate the process. As security analysts, we find many sites that give admin access just by using Admin and Admin as the user ID and password, respectively. To enhance personal skills, there are many tutorials to walk through. One thing to do is to pull down a live website that you can set up for practice, such as WebGoat, and go through the steps outlined in the tutorials from sites such as http://webappsecmovies.sourceforge.net/webgoat/. These sites will show a person how to perform SQL Injection testing through the WebGoat site. As part of these tutorials, there are plugins of Firefox to test security scripts, HTML, debug pieces and tamper with the website through the browser, as shown in this screenshot: Using .NET 4 can help Every page that is deployed to the Internet (and in many cases, the Intranet as well), constantly gets probed and prodded by scans, viruses, and network noise. There are so many pokes, probes, and prods on networks these days that most of them are seen as noise. By default, .NET 4 offers some validation and out-of-the-box support for Web requests. Using .NET 4, you may discover that some input types such as double quotes, single quotes, and even < are blocked in some form fields. You will get an error like what is shown in the following screenshot when trying to pass some of the values: This is very basic validation, and it will reside in the .NET version 4 framework's pooling pieces of Internet Information Services (IIS) for Windows. To further offer security following Microsoft's best enterprise practices, we may also consider using Model-View-Controller (MVC) and Entity Frameworks (EF). To get this information, we can review Microsoft Application Architecture Guide at http://msdn.microsoft.com/en-us/library/ff650706.aspx. The MVC design pattern is the most commonly used pattern in software and is designed as follows: This is a very common design pattern, so why is this important in security? What is helpful is that we can validate data requests and responses through the controllers, as well as provide data annotations for each data element for more validation. A common attack that appeared through viruses through the years is the buffer overflow. A buffer overflow is used to send a lot of data to the data elements. Validation can check whether there is sufficient data to counteract the buffer overflow. EF is a Microsoft framework used to provide an object-relationship mapper. Not only can it easily generate objects to and from the SQL Server through Visual Studio, but it can also use objects instead of SQL scripting. Since it does not use SQL, SQL Injection, which is an attack involving injecting SQL commands through input fields, can be counteracted. Even though some of these techniques will help mitigate many attack vectors, the gateway to backend processes is usually through the website. There are many more injection attack vectors. If stored procedures are used for SQL Server, a scan be tried to access any stored procedures that the website may be calling, as well as for any default stored procedures that may be lingering from default installations from SQL Server. So how do we add further validation and decouple the backend processes in an organization from the website? NServiceBus to the rescue NServiceBus is the most popular C# platform framework used to implement an Enterprise Service Bus (ESB) for service-oriented architecture (SOA). Basically, NSB hosts Windows services through its NServiceBus.Host.exe program, and interfaces these services through different message queuing components. A C# MVC-EF program can call web services directly, and when the web service receives an error, the website will receive the error directly in the MVC program. This creates a coupling of the web service and the website, where changes in the website can affect the web services and actions in the web services can affect the website. Because of this coupling, websites may have a Please do not refresh the page until the process is finished warning. Normally, it is wise to step away from the phone, tablet, or computer until the website is loaded. It could be that even though you may not touch the website, another process running on the machine may. A virus scanner, update, or multiple other processes running on the device could cause any glitch in the refreshing of anything on the device. With all the scans that could be happening on a website and that others on the Internet could be doing, it seems quite odd that a page would say Please don't' touch me, I am busy. In order to decouple the website from the web services, a service needs to be deployed between the website and web service. It helps if that service has a lot of out-of-the-box security features as well, to help protect the interaction between the website and web service. For this reason, a product such as NServiceBus is most helpful, where others have already laid the groundwork to have advanced security features in services tested through the industry by their use. Being the most common C# ESB platform has its advantages, as developers and architects ensure the integrity of the framework well before a new design starts using it. Benefits of NSB NSB provides many components needed for automation that are only found in ESBs. ESBs provide the following: Separation of duties: There is separation of duties from the frontend to the backend, allowing the frontend to fire a message to a service and continue in its processing, and not worrying about the results until it needs an update. Also, separation of workflow responsibility exists through separating out NSB services. One service could be used to send payments to a bank, and another service could be used to provide feedback of the current status of payment to the MVC-EF database so that a user may see their payment status. Message durability: Messages are saved in queues between services so that in case services are stopped, they can start from the messages in the queues when they restart, and the messages will persist until told otherwise. Workflow retries: Messages, or endpoints, can be told to retry a number of times until they completely fail and send an error. The error is automated to return to an error queue. For instance, a web service message can be sent to a bank, and it can be set to retry the web service every 5 minutes for 20 minutes before giving up completely. This is useful during any network or server issues. Monitoring: NSB ServicePulse can keep a heartbeat on its services. Other monitoring can easily be done on the NSB queues to report on the number of messages. Encryption: Messages between services and endpoints can be easily encrypted. High availability: Multiple services or subscribers could be processing the same or similar messages from various services that are living on different servers. When one server or service goes down, others could be made available to take over those that are already running. Summary If any website is on the Internet, it is being scanned by a multitude of means, from websites and others. It is wise to decouple external websites from backend processes through a means such as NServiceBus. Websites that are not decoupled from the backend can be acted upon by the external processes that it may be accomplishing, such as a web service to validate a credit card. These websites may say Do not refresh this page. Other conditions might occur to the website and be beyond your reach, refreshing the page to affect that interaction. The best solution is to decouple the website from these processes through NServiceBus. Resources for Article: Further resources on this subject: Mobile Game Design [Article] CryENGINE 3: Breaking Ground with Sandbox [Article] CryENGINE 3: Fun Physics [Article]
Read more
  • 0
  • 0
  • 3783
article-image-building-calender-application-joomla-using-fabrik
Packt
19 Feb 2010
3 min read
Save for later

Building a Calender Application in Joomla! using Fabrik

Packt
19 Feb 2010
3 min read
Getting ready You need a working installation of Joomla! 1.5.x. For exercise purpose, you can install that on your local computer. The web server should have PHP5 installed. Then you need to install Fabrik component. This component is available for free from http://fabrikar.com/download. Download the latest version of the component and install it from Extensions | Install/Uninstall screen in Joomla! administration panel. Also plan for the application you want to develop. For example, we are developing an event calender. This event calender will contain the following information: Event Category Event Name Venue Start Date & Time End Date & Time Event Description Attached Document Created by This is a very simple list of information we need. Based on the we will create two database tables: categories and events. The table structure is shown in the following diagram. The above table diagrams show that categories table is linked to events table by foreign key category_id. Similarly, we have added user_id field in events table, so that we can link it to jos_users table. Whenever a user creates an event, his or her user ID will be added to this field. For creating the tables in Joomla! database, connect to that database using phpMyadmin or some other interface, and run the following SQL command: CREATE TABLE `categories` (`id` INTEGER AUTO_INCREMENT DEFAULT NULL ,`name` VARCHAR(200) DEFAULT NULL ,PRIMARY KEY (`id`)) COMMENT 'contains categories of events';CREATE TABLE `events` (`id` INTEGER AUTO_INCREMENT DEFAULT NULL ,`category_id` INTEGER DEFAULT NULL ,`event_name` MEDIUMTEXT DEFAULT NULL ,`venue` VARCHAR(100) DEFAULT NULL ,`start` DATETIME DEFAULT NULL ,`end` DATETIME DEFAULT NULL ,`description` MEDIUMTEXT DEFAULT NULL ,`attachment` VARCHAR(250) DEFAULT NULL ,`user_id` INTEGER DEFAULT NULL ,PRIMARY KEY (`id`)) COMMENT 'list of events';ALTER TABLE `events` ADD FOREIGN KEY (category_id) REFERENCES `categories` (`id`); Successful execution of the above code block will create two tables and add a foreign key to events table linking it to categories table. With creation of these two table we are set to create our event calendar application. How to do it... Follow the steps below: From Joomla! Administration panel, click Components | Fabrik |  Connections. That shows existing database connections. By default, connection to Joomla! database is created. You can create  new database connection by clicking New button and filling in the form. Click on Tables link in this screen. That shows existing tables created in Fabrik. In Table screen, click on New button to add a new table. That shows Table: [New] screen. In Label field type Categories, and in Introduction field, type Event Categories. Then select Yes in Published radio box to the right side. Accept default values for other fields. Then click Access tab. That shows Access Rights. Accept the default values in Access tab. Now click Data tab. From here you have to configure which data table you want to use. From Connection drop down list, select site database. Then click on Link to Table drop down list and select categories table. In Order By drop down list, select name. There are some other options in this tab, but those cannot be configured until you save the table. Now click Save button to save the table.
Read more
  • 0
  • 0
  • 3776

article-image-managing-and-enhancing-multi-author-blogs-wordpress-27part-2
Packt
20 Oct 2009
8 min read
Save for later

Managing and Enhancing Multi-Author Blogs with WordPress 2.7(Part 2)

Packt
20 Oct 2009
8 min read
Displaying author picture on posts Did you like the previous recipe in the first part? I hope you did! But personally, I must admit that even though displaying author information looks very cool, something is missing from the previous recipe. Can you guess what is it? It is a picture of the author, of course. Even if your author-related information is precise and complete, a picture is still essential. This is because it is the easiest, and quickest, way for a reader to recognize an author. But sadly, WordPress can't handle author pictures by default. Let's learn how to create a hack that will allow us to display the author's picture in the way that we want to. Getting ready As we'll be using author pictures in this recipe, you should start by requesting a picture of all of your authors. Although it isn't necessary, it will be really better if all of the pictures have the same width and height. A square of 80 to 110 pixels is a good standard. Also, make sure that all of your pictures have the same format, such as .jpg, .png, or .gif. How to do it Now that you have collected pictures of all of your authors, we can start to hack WordPress and insert author pictures in the posts First, you have to rename your images with the author IDs. You can also use author's last name if you prefer, but in this example I am going to use their IDs. Once you have your renamed authors' pictures, upload them to the wp-content/themes/yourtheme/images directory. Open the file single.php and add the following code within the loop: <img src="<?php bloginfo('template_url); ?>/images/<?php the_author_ID(); ?>.jpg" alt="<?php the_author(); ?>" /> Save the single.php file and you're done. Each post now displays a picture of its author! How it works The working of this code is pretty simple. You simply concatenated the result of the the_author_ID() function with the theme URL to build an absolute URL to the image. As the images are named with the author ID (for example, 1.jpg, 4.jpg, 17.jpg, and so on), the the_author_ID() function gives us the name of the picture to be displayed. You just have to add the .jpg extension. There's more... Now that you've learnt how to display the picture of the current author, you should definitely use this recipe to enhance the previous recipe. The following code will retrieve the author information, and display the author picture as we have learnt earlier: <div id="author-info"><h2>About the author: <?php the_author();?></h2><img src="<?php bloginfo('template_url); ?>/images/<?php the_author_ID(); ?>.jpg" alt="<?php the_author(); ?>" /><?php the_author_description(); ?><?php the_author();?>'s website: <a href="<?php the_author_url(); ?>"><?php the_author_url(); ?></a><br />Other posts by <?php the_author_posts_link(); ?></div><!--/author-info--> The outcome of the preceding piece of code will look similar to the following screenshot: Displaying the author's gravatar picture on posts Gravatars (which stands for Globally recognized avatars) is a popular service, that allows you to associate an avatar image to your email address. On October 18, 2007, Automattic (The company behind WordPress) acquired Gravatar. Since WordPress 2.5 the popular blogging engine is fully gravatar-compatible, which results, in the ability to include gravatars in comments. In this recipe, I'll show you how to modify the previous code to use the author gravatar instead of a personal picture. Getting ready As we're going to use Gravatars, you (and each of your authors) first need a gravatar account. Carry out the following steps to create a gravatar account and associate an image to your email address. Go to the web site http://en.gravatar.com/site/signup, and enter your email address into the text field. Gravatar will send you a confirmation via email. Check your emails and open the one received from Gravatar. Click on the link to confirm your email address. Choose a username and a Password for your account. Once your username and Password has been created successfully, you'll see a text that reads Whoops, looks like you don't have any images yet! Add an image by clicking here. Click on the given link, and choose to upload a picture from your computer's hard drive, or the Internet. Once you are done choosing and cropping (if necessary) your picture, you have to rate it. Click on G unless—except, if your avatar is meant for mature audiences only. Done! You now have your own gravatar. How to do it Open the file single.php from the theme you're using and paste the following code: $md5 = md5(get_the_author_email());$default = urlencode( 'http://www.yoursite.com/wp-content/themes/yourtheme/images/default_avatar.gif' );echo "<img src='http://www.gravatar.com/avatar.php?gravatar_id=$md5&amp;size=60&amp;default=$default' alt='' />"; How it works The first thing to do is to get an md5 sum from the author's email address. To do so, I used the php md5() function along with the get_the_author_email() function. I didn't use the_author_email() because this function directly prints the result without allowing you to manipulate it with php I then encoded the URL of a default picture that is to be shown if the author hasn't signed up to Gravatar yet. Once done, the gravatar can be displayed. To do so, visit the web site: http://www.gravatar.com/avatar.php with the following parameters: gravatar_id: The gravatar id, which is an md5 sum of the user email size: The gravatar size in pixels default:The absolute URL to an image which will be used as a default image if the author hasn't signed up to gravatar yet Adding moderation buttons to the comments A common problem with comments is spam. Sure, you can moderate comments and use the Akismet plugin. However, sometimes someone leaves a normal comment, you approve it, and then the spammer—who knows that his comments aren't being accepted by the moderator—starts to spam your blog. Even though you can do nothing against this (except moderating all of the comments), a good idea is to either add spam and delete buttons to all of the comments. This way, if you see a comment saying spam while reading your blog, then you can edit it, delete it, or mark it as spam. I got this useful tip from Joost de Valk, who blogs at www.yoast.com Getting ready The following screenshot shows normal comments without the edit, delete and spam buttons: There's nothing complicated at all with this recipe. However, you must be sure to know which kind of blog the users are allowed to edit or delete your comments. For a list of actions and user roles, see the section named Controlling what users can do, which is later in this article. How to do it Open the file functions.php and paste the following piece of code: function delete_comment_link($id){if (current_user_can('edit_post')){echo '| <a href="'.admin_url("comment.php?action=cdc&c=$id").'">del</a> ';echo '| <a href="'.admin_url("comment.php?action=cdc&dt=spam&c=$id").'">spam</a>';}} Save the file functions.php and open the file comments.php. Find the comments loop and add the following lines: <?phpedit_comment_link();delete_comment_link(get_comment_ID());?> Save the file comments.php and visit your blog. You now have three links on each of the comments to edit, to delete (del), and to mark as spam as shown in the following screenshot: How it works In this recipe we started by creating a function. This function first verifies whether the current user has the right to edit posts. If yes, then the admin URLs to mark the comment as spam or delete it are created and displayed. In the file comments.php, we have used the edit_comment_link(), which is a built-in WordPress function. Some themes include this by default. We then used the comment ID as a parameter to the delete_comment_link() function that you had created earlier.
Read more
  • 0
  • 0
  • 3768

article-image-eloquent-relationships
Packt
28 Jan 2013
12 min read
Save for later

Eloquent relationships

Packt
28 Jan 2013
12 min read
(For more resources related to this topic, see here.) 1 — Eloquent relationships ActiveRecord is a design pattern that describes an object-oriented way of interacting with your database. For example, your database's users table contains rows and each of these rows represents a single user of your site. Your User model is a class that extends the Eloquent Model class. When you query a record from your database, an instantiation of your User model class is created and populated with the information from the database. A distinct advantage of ActiveRecord is that your data and the business logic that is related to the data are housed within the same object. For example, it's typical to store the user's password in your model as a hash, to prevent it from being stored as plaintext. It's also typical to store the method, which creates this password hash within your User class. Another powerful aspect of the ActiveRecord pattern is the ability to define relationships between models. Imagine that you're building a blog site and your users are authors who must be able to post their writings. Using an ActiveRecord implementation, you are able to define the parameters of the relationship. The task of maintaining this relationship is then simplified dramatically. Simple code is the easy code to change. Difficult to understand code is the easy code to break. As a PHP developer, you're probably already familiar with the concept of database normalization. If you're not, normalization is the process of designing databases so that there is little redundancy in the stored data. For example, you wouldn't want to have both a users table which contains the user's name and a table of blog posts which also contains the author's name. Instead, your blog post record would refer to the user using their user ID. In this way we avoid synchronization problems and a lot of extra work! There are a number of ways in which relationships can be established in normalized database schemas. One-to-one relationship When a relationship connects two records in a way that doesn't allow for more records to be related, it is a one-to-one relationship. For example, a user record might have a one-to-one relationship with a passport record. In this example, a user record is not permitted to be linked to more than one passport record. Similarly, it is not permitted for a passport record to relate to more than one user record. How would the database look? Your users table contains information about each user in your database. Your passports table contains passport numbers and a link to the user which owns the passport. In this example, each user has no more than one passport and each passport must have an owner. The passports table contains its own id column which it uses as a primary key. It also contains the column user_id, which contains the ID of the user to whom the passport belongs. Last but not least, the passports table contains a column for the passport number. First, let's model this relationship in the User class: class User extends Eloquent { public function passport() { return $this->has_one('Passport'); } } We created a method named passport() that returns a relationship. It might seem strange to return relationships at first. But, you'll soon come to love it for the flexibility it offers. You'll notice that we're using the has_one() method and passing the name of the model as a parameter. In this case, a user has one passport. So, the parameter is the name of the passport model class. This is enough information for Eloquent to understand how to acquire the correct passport record for each user. Now, let's look at the Passport class: class Passport extends Eloquent { public function users() { return $this->belongs_to('User'); } } We're defining the passport's relationship differently. In the User class, we used the has_one() method. In the Passport class we used belongs_to(). It's vital to identify the difference early so that understanding the rest of the relationships is more simple. When a database table contains a foreign key, it is said that it belongs to a record in another table. In this example, our passports table refers to records in the users table through the foreign key user_id. Consequently, we would say that a passport belongs to a user. Since this is a one-to-one relationship the user has one (has_one()) passport. Let's say that we want to view the passport number of the user with the id of 1. $user = User::find(1); If(is_null($user)) { echo "No user found."; return; } If($user->passport) { echo "The user's passport number is " . $user->passport->number; } else { echo "This user has no passport."; } In this example, we're dutifully checking to make sure that our user object was returned as expected. This is a necessary step that should not be overlooked. Then, we check whether or not the user has a passport record associated with it. If a passport record for this user exists, the related object will be returned. If it doesn't exist, $user->passport will return null. In the preceding example, we test for the existence of a record and return the appropriate response. One-to-many relationships One-to-many relationships are similar to one-to-one relationships. In this relationship type, one model has many of other relationships, which in turn belongs to the former. One example of a one-to-many relationship is a professional sports team's relationship to its players. One team has many players. In this example, each player can only belong to one team. The database tables have the same structure. Now, let's look at the code which describes this relationship. class Team extends Eloquent { public function players() { return $this->has_many('Player'); } } class Player extends Eloquent { public function team() { return $this->belongs_to('Team'); } } This example is almost identical to the one-to-one example. The only difference is that the team's players() relationship uses has_many() rather than has_one(). The has_one() relationship returns a model object. The has_many() relationship returns an array of model objects. Let's display all of the players on a specific team: $team = Team::find(2); if(is_null($team)) { echo "The team could not be found."; } if(!$team->players) { echo "The team has no players."; } foreach($team->players as $player) { echo "$player->name is on team $team->name. "; } Again, we test to make sure that our team could be found. Then, we test to make sure that the team has players. Once we know that for sure, we can loop through those players and echo their names. If we tried to loop through the players without first testing and if the team had players, we'd get an error. Many-to-many relationships The last relationship type that we're going to cover is the many-to-many relationship. This relationship is different in that each record from each table could potentially be tied simultaneously to each record in another. We aren't storing foreign keys in either of these tables. Instead, we have a third table that exists solely to store our foreign keys. Let's take a look at the schema. Here we have a students table and a courses table. A student can be enrolled in many courses and a course can contain many students. The connection between students and courses is stored in a pivot table. A pivot table is a table that exists to connect two tables specifically for many-to-many relationships. Standard convention for naming a pivot table is to combine the names of both of the related tables, singularized, alphabetically ordered, and connected with an underscore. This gives us the table name course_student. This convention is not only used by Laravel and it's a good idea to follow the naming conventions covered in this document as strictly as possible as they're widely used in the web-development industry. It's important to notice that we're not creating a model for the pivot table. Laravel allows us to manage these tables without needing to interact with a model. This is especially nice because it doesn't make sense to model a pivot table with business logic. Only the students and courses are a part of our business. The connection between them is important, but only to the students and to the course. It's not important for its own sake. Let's define these models, shall we? class Student extends Eloquent { public function courses() { return $this->has_many_and_belongs_to('Course'); } } class Course extends Eloquent { public function students() { return $this->has_many_and_belongs_to('Student'); } } We have two models, each with the same type of relationship to each other. has_many_and_ belongs_to is a long name. But, it's a fairly simple concept. A course has many students. But, it also belongs to (belongs_to) student records and vice-versa. In this way, they are considered equal. Let's look at how we'll interact with these models in practice: $student = Student::find(1); if(is_null($student)) { echo "The student can't be found."; exit; } if(!$student->courses) { echo "The student $student->name is not enrolled in any courses."; exit; } foreach($student->courses as $course) { echo "The student $student->name is enrolled in the course $course->name."; } Here you can see that we can loop through the courses much the same way we could with the one-to-many relationship. Any time a relationship includes the word many, you know that you'll be receiving an array of models. Conversely, let's pull a course and see which students are a part of it. $course = Course::find(1); if(is_null($course)) { echo "The course can't be found."; exit; } if(!$course->students) { echo "The course $course->name seems to have no students enrolled."; exit; } foreach($course->students as $student) { echo "The student $student->name is enrolled in the course $course->name."; } The relationship functions exactly the same way from the course side. Now that we have established this relationship, we can do some fun things with it. Let's look at how we'd enroll a new student into an existing course: $course = Course::find(13); if(is_null($course)) { echo "The course can't be found."; exit; } $new_student_information = array( 'name' => 'Danielle' ); $course->students()->insert($new_student_information); Here we're adding a new student to our course by using the method insert(). This method is specific to this relationship type and creates a new student record. It also adds a record to the course_student table to link the course and the new student. Very handy! But, hold on. What's this new syntax? $course->students()->insert($new_student_information); Notice how we're not using $course->students->insert(). Our reference to students is a method reference rather than a property reference. That's because Eloquent handles methods that return relationship objects differently from other model methods. When you access a property of a model that doesn't exist, Eloquent will look to see if you have a function that matches that property's name. For example, if we try to access the property $course->students, Eloquent won't be able to find a member variable named $students. So it'll look for a function named students(). We do have one of those. Eloquent will then receive the relationship object from that method, process it, and return the resulting student records. If we access a relationship method as a method and not as a property, we directly receive the relationship object back. The relationship's class extends the Query class. This means that you can operate on a relationship object in the same way that you can operate on a query object, except that it now has new methods that are specific to the relationship type. The specific implementation details aren't important at this point. It's just important to know that we're calling the insert() method on the relationship object returned from $course->students(). Imagine that you have a user model and it has many relationships and belongs to a role model. Roles represent different permission groupings. Example roles might include customer, admin, super admin, and ultra admin. It's easy to imagine a user form for managing its roles. It would contain a number of checkboxes, one for each potential role. The name of the checkboxes is role_ids[] and each value represents the ID of a role in the roles table./p> When that form is posted we'll retrieve those values with the Input::get() method. $role_ids = Input::get('role_ids'); $role_ids is now an array that contains the values 1, 2, 3, and 4. $user->roles()->sync($role_ids); The sync() method is specific to this relationship type and is also perfectly suited for our needs. We're telling Eloquent to connect our current $user to the roles whose IDs exist within the $role_ids array. Let's look at what's going on here in further detail. $user->roles() is returning a has_ many_and_belongs_to relationship object. We're calling the sync() method on that object. Eloquent now looks at the $role_ids array and acknowledges it as the authoritative list of roles for this user. It then removes any records that shouldn't exist in the role_user pivot table and adds records for any role that should exist in the pivot table. Summary In this article we discussed three types of Eloquent relationships—one-to-one relationship, one-to-many relationship, and many-to-many ralationship. Resources for Article : Further resources on this subject: Modeling Relationships with GORM [Article] Working with Simple Associations using CakePHP [Article] NHibernate 2: Mapping relationships and Fluent Mapping [Article]
Read more
  • 0
  • 0
  • 3766
article-image-building-news-aggregating-site-using-drupal-6-2
Packt
14 Aug 2009
4 min read
Save for later

Building a News Aggregating Site Using Drupal 6

Packt
14 Aug 2009
4 min read
Weird Hap'nins requirements will be the need to: Get external feed sources and allocate them to menu links on the web site Create the means to automatically fetch and display article items located in the feeds Display blocks of latest content from each feed source on the front page Theme The theme chosen is "Strange Little Town", which is a contributed theme that fits the description of this unique web site. Build Weird Hap'nins Vaughan Pyre is a very ambitious webpreneur. What he really hopes for is a web site that is completely self-maintaining, and on which he can place some Google AdSense blocks. Clicks from the visitors to his site will ensure that he makes lots of money. For this, he needs a site where the content updates regularly with fresh content so that visitors will keep coming back to click on some more Google ads. Vaughan's ultimate objective is to create several of these web sites. Modules This is, surprisingly, a very simple site to build, and much of the requirements can be achieved by using the Core Aggregator module. Indeed, were it not for the fact that Vaughan needs the content to automatically update, we needn't use any module other than the Aggregator module. Optional Core modules We will be using the following Core modules, which can be enabled via the Modules page: Aggregator—for aggregating syndicated content (RSS, RDF, and Atom feeds) Contributed modules We will also be using the following contributed modules from Drupal.org. Install, and enable them via the Modules page: Poormanscron—internal scheduler for users without a cron application Configure the Poormanscron module First we need to enable the Poormanscron module, so that the incoming feeds will be able to self-refresh. From the Administer page, we will access the Poormanscron configuration page, mainly to set the time interval between runs of cron to update feed items, as shown in the following screenshot: In this case, we have left the Time intervals at the default value of 60 minutes. Configure the Aggregator module The Aggregator module should be configured to define the feed sources, how often they will be polled, and how they're categorized. For this, if we select the Feed aggregator link on the Administer page, then we should arrive at the following page: On the Settings page, we will define some more requirements, as follows: Allowed HTML tags—which are the tags that are embedded in the incoming feed that we want Drupal to accept. The allowed tags do not include image tags. So if any images are coming with the feed, then they will be excluded. However, we don't want this to happen, so we have added the image tag <img> to the list. Items shown in sources and categories pages—we have defined this to be 20 items, but you may select another figure. Discard items older than—we want the feed items to be completely refreshed every week so we have set this at 1 week. Category selection type—we are not categorizing the feeds, so we will leave this setting as it is. Basic content The site is built around the Aggregator module, and no other Content type will need to be created. Vaughan has decided to initially use three feeds obtained from www.newsfeedmaker.com, as follows: Bad News—http://www.newsfeedmaker.com/feed.php?code=ddb874f7 Crime—http://www.newsfeedmaker.com/feed.php?code=33a5a46a Paranormal—http://www.newsfeedmaker.com/feed.php?code=936f006a It is from these feeds that we will create the necessary content. Tips and trapsAn excellent source for "mashup" feeds on any topic is pipes.yahoo.com. Add feeds On the Add feeds page, which is under the Feed aggregator configuration page, we finally get to define our feeds, and how often we want them to be polled. We want our Bad News feed to be polled every hour, so we have configured it this way. The same procedure is followed to create the feeds for Crime and Paranormal.
Read more
  • 0
  • 0
  • 3766

article-image-navigating-your-site-using-codeigniter-17-part-2
Packt
30 Nov 2009
9 min read
Save for later

Navigating Your Site using CodeIgniter 1.7: Part 2

Packt
30 Nov 2009
9 min read
Designing a better view At this stage, you might ask: Why are we going through so much effort to serve a simple HTML page? Why not put everything in one file? For a simple site, that's a valid point—but whoever heard of a simple site? One of the coolest things about CI is the way it helps us to develop a consistent structure. So, as we add to and develop our site, it is internally consistent, well laid out, and simple to maintain. At the start, we need to take these three common steps: Write a view page Write a stylesheet Update our config file to specify where the stylesheet is After this is done, we need to update our controller to accept parameters from the URL, and pass variables to the view. First, let's redesign our view and save it as testview.php, at /www/codeigniter/application/views/testview.php. <html><head><!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0Strict//EN'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd'><html ><title>Web test Site</title><link rel="stylesheet" type="text/css" href="<?php echo$base."/".$css;?>"></head><body><h1><?php echo $mytitle; ?> </h1><p class='test'> <?php echo $mytext; ?> </p></body></html> It's still mostly HTML, but notice the PHP "code islands" in the highlighted lines. You'll notice that the first bits of PHP code build a link to a stylesheet. Let's save a simple stylesheet as styles.css, at www/codeigniter/css/styles.css. It just says: h1{margin: 5px;padding-left: 10px;padding-right: 10px;background: #ffffff;color: blue;width: 100%;font-size: 36px;}.test{margin: 5px;padding-left: 10px;padding-right: 10px;background: #ffffff;color: red;width: 100%;font-size: 36px;} This gives us two styles to play with, and you'll see we've used both of them in the view. Firstly, let's add an entry to the config file: $config['css'] = 'css/styles.css'; This is simply to tell the name and address of the CSS file that we've just written to the site. But note that the link to the stylesheet is referenced at $base/$css: Where do those variables, $base and $css, get their values? And come to think of it, those variables $mytitle and $mytext at the end of the code? We need a new controller! Designing a better controller Now, we need a new controller. We'll call it Start and save it as start.php, at /www/codeigniter/application/controllers/start.php. This controller has to do several things: Call a view Provide the view with the base URL and the location of the CSS file we just wrote Provide the view with some data—it's expecting a title ($mytitle) and some text ($mytext) Lastly, accept a parameter from the user (that is using the URL request) In other words, we have to populate the variables in the view. So let's start with our Start controller. This is an OO class: <?phpclass Start extends Controller{var $base;var $css; Notice that here we've declared the $base and $css (the CSS filename) as variables or class properties. This saves us from having to redeclare them if we write more than one function in each class. But you can define and use them as local variables within one function, if you prefer. The constructor function now defines the properties we've declared, by looking them up in the config file. To do this, we use the syntax: $this->config->item('name_of_config_variable'); As in: function Start(){parent::Controller();$this->base = $this->config->item('base_url');$this->css = $this->config->item('css');} CI recovers whatever we entered in the config file against that name. Using this system, no matter how many controllers and functions we write, we'll have to change these fundamental variables only once. This is true even if our site becomes so popular that we have to move it to a bigger server. Getting parameters to a function Now, within the Start controller class, let's define the function that will actually do the work. function hello($name = 'Guest'){$data['css'] = $this->css;$data['base'] = $this->base;$data['mytitle'] = 'Welcome to this site';$data['mytext'] = "Hello, $name, now we're getting dynamic!";$this->load->view('testview', $data);} This function expects the parameter $name, but you can set a default value—myfunction($myvariable = 0), which it uses to build the string assigned to the $mytext variable. Well, as we just asked, where does that come from? In this case, it needs to come from the URL request, where it will be the third parameter. So, it comes through the HTTP request: http://127.0.0.1/codeigniter/start/hello/Jose This example code doesn't "clean" the passed variable Jose, or check it in any way. You might want to do this while writing the code. We'll look at how to check form inputs. Normally, variables passed by hyperlinks in this way are generated by your own site. A malicious user can easily add his or her own, just by sending a URL such as: http://www.mysite.com/index.php/start/hello/my_malicious_variable. So, you might want to check that the variables you receive are within the range you expect, before handling them. The last segment of the URL is passed to the function as a parameter. In fact, you can add more segments of extra parameters if you like, subject to the practical limits imposed by your browser. Let's recap on how CI handles URLs, since we've covered it all now: URL segment   What it does   http://www.mysite.com   The base URL that finds your site.   /index.php   Finds the CI router that sets about reading the rest of the URL and selecting the correct route into your site. If you have added the .htaccess file in the previous chapter, this part will not be visible, but will still work as supposed.   /start   The name of the controller that CI will call (If no name is set, CI will call whichever default controller you've specified).   /hello   The name of a function that CI will call, inside the selected controller (If no function is specified, it defaults to the index function, unless you've used _remap).   /Jose   CI passes this to the function as a variable.   If there is a further URL segment, for example, /bert   CI passes this to the function as the second variable. More variables   CI will pass further URL segments as consequent variables.   Passing data to a view Let's go back to the hello function: function hello($name){$data['css'] = $this->css;$data['base'] = $this->base;$data['mytitle'] = 'Welcome to this site';$data['mytext'] = "Hello, $name, now we're getting dynamic!";$this->load->view('testview', $data);} Notice how the hello() function first creates an array called $data, taking a mixture of object properties set up by the constructor and text. Then it loads the view by name, with the array it has just built as the second parameter. Behind the scenes, CI makes good use of another PHP function—extract(). This takes each value in the $data array and turns it into a new variable in its own right. So, the $data array that we've just defined is received by the view as a series of separate variables; $text (equal to "Hello, $name, now we're getting dynamic"), $css (equal to the value from the config file), and so on. In other words, when built, the $data array looks like this: Array([css] => 'mystyles.css';[base] => 'http://127.0.0.1/packt';[mytitle] => 'Welcome to this site';[mytext] => 'Hello, fred, now we're getting dynamic!';) But on its way to the view, it is unpacked, and the following variables are created in the view to correspond to each key/value pair in the array: $css = 'mystyles.css';$base = 'http://127.0.0.1/packt';$mytitle = 'Welcome to this site';$mytext = 'Hello, fred, now we're getting dynamic!';) Although you can only pass one variable to a view, you can pack a lot of information into it. Each value in the $data array can itself be another array, so you can pass pieces of information to the view in a tightly structured manner. Now navigate to http://127.0.0.1/codeigniter/start/hello/jose (note that the URL is different—it is looking for the start function we wrote in the index controller) and you'll see the result—a dynamic page written using MVC architecture. (well, VC at least! We haven't really used the M yet). You can see that the parameter jose is the last segment of the URL. It has been passed into the function, and then to the view. Please remember that your view must be written in parallel with your controller. If the view does not expect and make a place for a variable, it won't be displayed. If the view is expecting a variable to be set and it isn't, you are likely to get an error message (your view can of course accept variables conditionally). Also, a controller can use more than one view; this way we can separate our pages into sections such as the header, the menu, and so on. Each of these views can be nested one inside the other. Child views can even inherit variables passed by the controller to their parent view. Loading a view from inside another view is very easy; just put something like this PHP snippet in your HTML code: <body><div id="menu"><?php $this->load->view('menu'); ?> This way we can load a view inside a view, with all variables in the first one also available into the nested one.
Read more
  • 0
  • 0
  • 3765
Modal Close icon
Modal Close icon