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

How-To Tutorials

7018 Articles
article-image-using-bean-validation-jsr-303-annotations-apache-myfaces-12
Packt
30 Mar 2010
9 min read
Save for later

Using Bean Validation (JSR 303) annotations with Apache MyFaces 1.2

Packt
30 Mar 2010
9 min read
Using annotations in JavaBeans is an elegant way of defining validation rules in a declarative way. Apart from MyFaces ExtVal there are other projects that introduced declarative validation, such as the Hibernate Validator and the Bean Validation Framework for Spring. Some framework developers realized that it would be a good idea to standardize this type of validation. This led to the Bean Validation specification that was developed as JSR 303 in the Java Community Process. Accordingly, Bean Validation will be a standard part of Java EE 6, but it can be used in Java EE 5 by manually including a Bean Validation implementation. One of the benefits of having an official standard for validation is that various user interface frameworks can implement support for this type of validation. For example, JavaServer Faces 2.0 will have support for Bean Validation embedded in it, and other UI frameworks will probably follow But at the moment, we’re still building Java EE 5 and JSF 1.2 applications. And although we can use Bean Validation in Java EE 5, JSF 1.2 doesn’t have Bean Validation support. And that’s where ExtVal comes in. We can use ExtVal to integrate JSR 303 Bean Validation into JSF 1.2 (and even JSF 1.1) projects. This section will discuss some Bean Validation basics and show how to use Bean Validation with ExtVal. Note that we can only cover some basics of Bean Validation here. As Bean Validation is a new standard, there is not much reference documentation available yet. However, some decent documentation comes bundled with Hibernate Validator—the reference implementation of JSR 303. That documentation is also available online at http://docs.jboss.org/hibernate/stable/validator/reference/. As an alternative, the official specification of JSR 303 can be used as documentation. The official specification can be found at http://jcp.org/en/jsr/summary?id=303. Setting up Bean Validation and ExtVal To use Bean Validation, we need a JSR 303 implementation, unless we’re using a Java EE 6 compliant application server. Currently, the only available JSR 303 implementation is the reference implementation, which is Hibernate Validator 4.0. Hibernate Validator can be downloaded from http://www.hibernate.org/subprojects/validator/download.html . We should make sure we download a 4.0 version, as versions before 4.0 do not implement the JSR 303 standard. At the time of writing this article, the latest release is 4.0.2 GA. After downloading Hibernate Validator, we have to add the Bean Validation libraries to our project. All libraries have to be in the shared lib directory of our EAR. We also have to add the libraries that Hibernate Validator depends on. The following table shows a list of libraries that have to be added to our project in order to be able to use the Hibernate Validator. If we had used Maven, these libraries would have been downloaded and added to our project automatically by Maven. Library Description Where to get hibernate-validator-4.0.2.GA.jar The main Hibernate Validator library. Included in the root directory of the Hibernate Validator distribution. validation-api-1.0.0.GA.jar Contains all interfaces and annotations defined by the JSR 303 standard. Included in the lib directory of the Hibernate Validator distribution. slf4j-log4j12-1.5.6.jar slf4j-api-1.5.6.jar log4j-1.2.14.jar jpa-api-2.0.Beta-20090815.jar   Runtime dependencies of Hibernate Validator. Included in the lib directory of the Hibernate Validator distribution. activation-1.1.jar jaxb-api-2.1.jar jaxb-impl-2.1.3.jar stax-api-1.0-2.jar Runtime dependencies for Hibernate Validator. These libraries are only needed if we run Hibernate Validator on a JDK 5 version. So even if we use a Java EE 5 server that runs on a JDK 6, we don't need these libs. Included in the lib/jdk5 directory of the Hibernate Validator distribution. Once we have added the Bean Validation libraries to our project, we have to make sure that we have also added ExtVal’s Bean Validation module to our project. The Bean Validation module is only available from ExtVal version 1.2.3 onwards. See the Setting up ExtVal section for more details. Using Bean Validation annotations The basic usage of Bean Validation is very similar to the use of ExtVal’s Property Validation annotations. There are some differences in the annotations, though. The following table lists all of the annotations that are defined in the Bean Validation specification: Annotation Attributes Description @AssertFalse   Assure that the element that is annotated is false. @AssertTrue   Assure that the element that is annotated is true. @DecimalMin value The value of the annotated element must be a numeric value greater than or equal to the indicated value. The value attribute must be a String that will be interpreted as a BigDecimal string representation. @DecimalMax value The value of the annotated element must be a numeric value less than or equal to the indicated value. The value attribute has the same behavior as the value attribute of the @DecimalMin annotation. @Digits integer, fraction The annotated element must have a numeric value that can't have more integer digits and fraction digits than indicated by the integer and fraction attributes. @Past   Can be applied to java.util.Date and java.util.Calendar elements. The value of the annotated element must be in the past. @Future   Can be applied to java.util.Date and java.util.Calendar elements. The value of the annotated element must be in the future. @Min value Only for integer values. The value of the annotated element must be greater than or equal to the given value. @Max value Only for integer values. The value of the annotated element must be less than or equal to the given value. @NotNull   The annotated value can't be null. @Null   The annotated value must be null. @Pattern regexp, flags Can only be applied to Strings. The annotated String must match the regular expression that is given in the regexp attribute. The flags attribute can be set to an array of Pattern.Flag values, indicating which flags should be set to the java.util.regex.Pattern that will be used to match the value against. Valid flags are UNIX_LINES, CASE_INSENSITIVE, COMMENTS, MULTILINE, DOTALL, UNICODE_CASE, and CANON_EQ. See the JavaDoc documentation of java.util.regex.Pattern for an explanation of the flags. (http://java.sun.com/javase/6/docs/api/java/util/regex/Pattern.html) @Size min, max Can be applied to Strings, Collections, Maps, and arrays. Verifies that the size of the annotated element is between the given min and max values, min and max included. @Valid   For recursive validation. All annotations are defined in the javax.validation.constraints package. Apart from the attributes mentioned in the previous table, all annotations (except the @Valid annotation) have the following common attributes: message: This attribute can be used to set a custom error message that will be displayed if the constraint defined by the annotation is not met. If we want to set a message bundle key instead of a literal message, we should surround it with braces. So we can set message to either "This value is not valid" or "{inc.monsters.mias.not_valid}". groups: This attribute can be used to associate a constraint with one or more validation processing groups. Validation processing groups can be used to influence the order in which constraints get validated, or to validate a bean only partially. (See http://docs.jboss.org/hibernate/stable/validator/reference/en/html/validator-usingvalidator.html#validator-usingvalidator-validationgroups for more on validation groups.) payload: This attribute can be used to attach extra meta information to a constraint. The Bean Validation standard does not define any standard metadata that can be used, but specific libraries can define their own metadata. This mechanism can be used with ExtVal to add severity information to constraints, enabling the JSF pages to show certain constraint violations as warnings instead of errors. See the Using payloads to set severity levels section for an example of this. OK, now we know which annotations can be used. Let’s see how we can use Bean Validation annotations on our Employee class: // Package declaration and imports omitted for brevitypublic class Employee implements Serializable { @Id @GeneratedValue(strategy=GenerationType.AUTO) private int id; @Temporal(TemporalType.DATE) @Column(name="BIRTH_DATE") @Past private Date birthDate; @Column(name="FIRST_NAME") private String firstName; @Temporal(TemporalType.DATE) @Column(name="HIRE_DATE") @Past private Date hireDate; @Column(name="JOB_TITLE") @NotNull @Size(min=1) private String jobTitle; @Column(name="LAST_NAME") private String lastName; @Min(value=100) private int salary; @Column(name="KIDS_SCARED") private int kidsScared; @OneToMany(mappedBy="employee") private List<Kid> kids; // Getters and setters and other code omitted.} The Bean Validation annotations are highlighted in the code example. Note that the annotations are applied to the member variables here. Alternatively, we could have applied them to the getter methods. In this example, the birthDate and hireDate are annotated with @Past so that only dates in the past can be set. The jobTitle is set to have a minimum length of one character by the @Size annotation. The salary must have a minimum value of 100, as set by the @Min annotatiion. Reusing validation Bean Validation does not have a solution like the @JoinValidation annotation of ExtVal’s Property Validation module. However, Bean Validation offers other ways to avoid repetitive code and help us reusing validation. This section describes some of the possibilities Inheriting validation Constraints defined on (the properties of) super classes are inherited. This means that if we have a super class called Person, like the following example, our Employee class can inherit the properties—including the annotated constraints—as follows: public class Person { @Size(min=1) private String firstName; @Size(min=1) private String lastName; @Past private Date birthDate; // Getters and setters omitted.} No special actions have to be taken to inherit annotated validation constraints. Using recursive validation We can use the @Valid annotation to use recursive validation (or graph validation as it is called in the JSR 303 specification). The @Valid annotation can be used on single member objects as well as on Collections. If applied to a Collection, all objects in the collection are validated, but null values in the Collection are ignored. For example, we could use this to validate the List of scared Kids that is part of our Employee class, as follows: public class Employee implements Serializable { // Other member variables are left out here. @OneToMany(mappedBy="employee") @Valid private List<Kid> kids; // Getters and setters are omitted.} Now the List of Kids that is referenced by the kidsvariable can only contain valid Kid objects. This means that all Bean Validation constraints that are defined on the Kid class will be checked on all Kid objects in the List.
Read more
  • 0
  • 0
  • 4267

article-image-configuring-and-formatting-ireport-elements
Packt
29 Mar 2010
7 min read
Save for later

Configuring and Formatting iReport Elements

Packt
29 Mar 2010
7 min read
A complete report is structured by composing a set of sections called bands. Each band has its own configurable height, a particular position in the structure, and is used for a particular objective. The available bands are: Title, Page Header, Column Header, Detail 1, Column Footer, Page Footer, Last Footer, and Summary. A report structured with bands is shown in the following screenshot: Besides the mentioned bands, there are two special bands which are Background and No Data. Band Description Title Is the first band of the report and is printed only once. Title can be shown on a new page. You can configure this from the report properties discussed in the previous section of this chapter. Just to review-go to report Properties | More... and check the Title on a new page checkbox. Page Header Is printed on each page of the report and is used for setting up the page header. Column Header Is printed on each page, if there is a detail band on that page. This band is used for the column heading. Detail This band is repeatedly printed for each row in the data source. In the List of Products report, it is printed for each product record. Column Footer Is printed on each page if there is a detail band on that page. This band is used for the column heading. If the Floating column footer in report Properties is checked, then the column footer will be shown just below the last data of the column, otherwise it will be shown at the bottom of the page (above the page footer). Page Footer Is printed on each page except the last page, if Last Page Footer is set. If Last Page Footer is not set, then it is printed on the last page also. This band is a good place to insert page numbers. Last Page Footer Is printed only on the last page as a page footer. Summary Is printed only once at the end of the report. It can be printed on a separate page if it is configured from the report Properties. In the following chapters, we will produce some reports where you will learn about the suitability of this band. Background Is used for setting a page background. For example, we may want a watermark image for the report pages. No Data When no data is available for the reports, this band is printed if it is set as the When no data option in the report Properties. Showing/hiding bands and inserting elements Now, we are going to configure the report bands (setting height, visibility, and so on) and format the report elements. Select Column Footer from the Report Inspector. You will see the Column Footer - Properties on the right of the designer. Type 25 in the Band height field. Press Enter. Now you can see the Column Footer band in your report, which was invisible before you set the band height. A band becomes invisible in the report if its height is set to zero. We have already learned how to change the height of a band. We can also make a band invisible using the Print When Expression option. If we write new Boolean(false) in Print When Expression of a band, then that will make the band invisible, even though its height is set to greater than zero. If we write new Boolean(true), then the band will be visible. It is true by default. Drag a Static Text element from the Palette window and drop it on the Column Footer band. Double-click on Static Text and type End of Record, replacing the text Static Text. Select the static text element (End of Record). Go to Format | Position and then choose Center. Now the element has been positioned in the center of the Column Footer band. In the same way, insert two Line elements. Place one element at the left and another at the right of the static text. Select both the lines. Go to Format | Position, and then choose Center Vertically . The lines are now positioned in the center of the Column Footer vertically. Select both the lines and go to Format | Size and then choose Same Width. Now both the lines are equal in width. Select the static text element (End of Record) and the left line. Now go to Format | Position and choose Join Sides Right. This moves the line to the right, and it is now connected to the static text element. Repeat the previous step for the right line and finally choose Join Sides Left. Now the line has moved to the left and is connected with the static text element. In the same way, change the column headers as you want by double-clicking the labels on the Column Header band. Now, the columns may be Product Code, Name, and Description. Now your report design should look like the following screenshot: Preview the report, and you will see the lines and static text (End of Record) at the bottom of the column. By default, the Column Footer is placed at the bottom of the page. To show the Column Footer just below the table of data, the Float column footer option must be enabled from the report Properties window. Sizing elements We can increase or decrease the size of an element by dragging the mouse accordingly. Sometimes, we need to set the size of an element automatically based on other elements' sizes. There are various options for setting the automatic size of an element. These options are available in the format menu (Format | Size). Size Options Description Same Width This makes the selected elements of the same width. The width of the element that you select first is used as the new width of the selected elements. Same Width (max) The width of the largest of the selected elements is set as the width of all the selected elements. Same Width (min) The width of the smallest of the selected elements is set as the width of all the selected elements. Same Height This makes the selected elements of the same height. The height of the element that you select first is used as the new height of the selected elements. Same Height (max) The height of the largest of the selected elements is set as the height of all the selected elements. Same Height (min) The height of the smallest of the selected elements is set as the height of all the selected elements. Same Size Both the width and the height of the selected elements become the same. Position Description Center Horizontally (band/cell based) The selected element is placed in the center of the band horizontally. Center Vertically (band/cell based) The selected element is placed in the center of the band vertically. Center (in band/cell) The selected element is placed in the center of the band both horizontally and vertically. Center (in background) If the Background band is visible and if the element is on the Background band, then it will be placed in the center both horizontally and vertically. Join Left Joins two elements. For joining, one element will be moved to the left. Join Right Joins two elements. For joining, one element will be moved to the right. Align to Left Margin The selected element will be joined with the left margin of the report. Align to Right Margin The selected element will be joined with the right margin of the report.
Read more
  • 0
  • 0
  • 6711

article-image-reports-and-statistics-openx-ad-server
Packt
29 Mar 2010
2 min read
Save for later

Reports and Statistics in OpenX Ad Server

Packt
29 Mar 2010
2 min read
OpenX provides a very detailed and useful statistics and reports mechanism to evaluate the progress as well as performance of any campaign. OpenX reports and statistics tools have the ability to retrieve data on several groupings such as advertisers, campaigns, banners, websites, and zones. Advertisers and campaigns statistics It is the default OpenX statistics type. It provides current statistics of all advertisers under an account. It is also possible to retrieve statistics according to start and end dates. Time for action – getting advertisers and campaign statistics Now, let's learn how to get the statistics for a certain advertiser and the campaigns under it. We will then see how to analyze them on a spreadsheet. Click on Statistics menu item. Advertisers & Campaigns screen should automatically open. If not, click on Advertisers & Campaigns link. Now, we should be able to see current date's statistics as a default for all the advertisers under an account. Note that following screenshots are from a real OpenX Ad Server implementation and do not necessarily have to match with your screens. Let's view all the statistics for the advertiser, starting from the installation of OpenX Ad Server. Select All statistics option from the date list. We can now see all of the statistics for the advertiser. Click on tiny arrow near the advertiser name. We can now see the all the campaigns statistics under the advertiser. Click on the Clicks column. You can note that the campaign's statistics are sorted accordingly: Click on the tiny arrow near one of the campaign names.
Read more
  • 0
  • 0
  • 3904

article-image-setting-ireport-pages
Packt
29 Mar 2010
2 min read
Save for later

Setting Up the iReport Pages

Packt
29 Mar 2010
2 min read
Configuring the page format We can follow the listed steps for setting up report pages: Open the report List of Products. Go to menu Window | Report Inspector. The following window will appear on the left side of the report designer: Select the report List of Products, right-click on it, and choose Page Format…. The Page format… dialog box will appear, select A4 from the Format drop-down list, and select Portrait from the Page orientation section. You can modify the page margins if you need to, or leave it as it is to have the default margins. For our report, you need not change the margins. Press OK. Page size You have seen that there are many preset sizes/formats for the report, such as Custom, Letter, Note, Legal, A0 to A10, B0 to B5, and so on. You will choose the appropriate one based on your requirements. We have chosen A4. If the number of columns is too high to fit in Portrait, then choose the Landscape orientation. If you change the preset sizes, the report elements (title, column heading, fields, or other elements) will not be positioned automatically according to the new page size. You have to position each element manually. So be careful if you decide to change the page size. Configuring properties We can modify the default settings of report properties in the following way: Right-click on List of Products and choose Properties. We can configure many important report properties from the Properties window. You can see that there are many options here. You can change the Report name, Page size, Margins, Columns, and more. We have already learnt about setting up pages, so now our concern is to learn about some of the other (More…) options.
Read more
  • 0
  • 0
  • 7006

article-image-preventing-attacks-joomla-15-websites
Packt
29 Mar 2010
9 min read
Save for later

Preventing Attacks on Joomla! 1.5 Websites

Packt
29 Mar 2010
9 min read
Whether or not we like to think about it, there is always the potential threat of an attacker gaining access to our Joomla! websites. The most common way in which security is breached in Joomla! is through third-party extension security flaws. Due to the number of extensions that have security defects, there is an official list of extensions that are considered insecure, available in the FAQ sections at http://help.joomla.org. It is very important that, as third-party extension developers, we take great care in making our extensions as secure as we can. How to Avoid Common Attacks The security flaws that we will investigate are some of the most likely to be exploited because they tend to be the easiest to initiate and there is plenty of literature explaining how to initiate them. The attack types described here should not be considered a complete list. There are many ways in which an attacker can attempt to exploit a system. If you are concerned about attacks, you should consider hiring a security professional to help evaluate security vulnerabilities in your extensions. Using the Session Token A session is created for every client that makes a request. Joomla! uses its own implementation of sessions; integral to this is the JSession class. The session token, also refered to as the 'token', is a random alphanumeric string that we can use to validate requests made by a client. The token can change during a session. Imagine that an attacker uses a utility to bombard a site with data; the data itself may not be suspicious. The attacker may just be attempting to fill your database with worthless information. If we include a hidden field in our forms with the name of the token, we can check if the user is submitting data via a form with a valid session. We can get the token using JUtility::getToken(). In our template, where we render the form we want to secure, we add this: <input type="hidden" name="<?php echo JUtility::getToken(); ?>" value="1" /> When we call JUtility::getToken() we can optionally provide the Boolean forceNew parameter. This will force the generation of a new token. Before doing this we must consider the context in which we are calling the method. If there are any other forms present on the page that also use the token we may inadvertently prevent these from working. Components are always rendered first so are generally safer when forcing a new token. Now all we need to do is verify the token when we receive a request from the form that we are trying to secure. In this example we specifically get the token from the $_POST hash, guaranteeing that the token came via the correct method. The error message is not very intuitive; this is purposeful, because it makes it harder for an attacker to determine the reason why they are receiving the error. if(!JRequest::getVar(JUtility::getToken(), false, 'POST')){ JError::raiseError('403', JText::_('Request Forbidden'));} Code Injection Code injection occurs when code is included in input. The injected code, if not properly sanitized, may end up being executed on a server or on a client. There are a number of different ways in which injected code can compromise a Joomla! installation or a system with which we are interacting. We will take a look at the two most common forms of code injection used to attack Joomla!: PHP and SQL code injection. PHP Code Injection We should use JRequest and, in some cases, REs to ensure that the input data that we are handling is valid. Most data validation is very simple and doesn't require much effort. Even when data comes from an XHTML form control that is restricted to specific values, we must still validate the data. There is one form of PHP code injection that we don't need to worry about. By default Joomla! always disables 'register globals'. In scripts where 'register globals' is enabled, all URI query values are automatically converted into variables, literally injecting variables into a script. Imagine we are using an input value to determine which class to instantiate. If we do not sanitize the incoming data, we run the risk of instantiating a class that could be used to malicious effect. To overcome this we could use a predefined list of class names to ensure the data is valid: // define allowed classes$allow = array('Monkey', 'Elephant', 'Lion');// get the class name$class = JRequest::getWord('class', 'Monkey', 'GET');$class = ucfirst(strtolower($class)); Notice that we use the getWord() method to retrieve the value; this ensures that the value only includes letters and underscores. We also modify the case of the value so as to ensure it is in the same format as the expected value. Once we have defined the expectable class names and retrieved the value we can validate the value: if(!in_array($class, $allow)){ // unknown class, use default $class = 'Monkey';} Imagine we want to execute a shell command. This type of process is potentially very risky; some unwanted malicious commands such as rm or del could potentially reduce our server to a gibbering wreck. In this example we define an array of acceptable commands and use the PHP escapeshellarg() function to escape any arguments passed to the command. $allowCmds = array('mysqld', 'apachectl');$cmd = JRequest::getVar('cmd', false, 'GET', 'WORD');$arg = JRequest::getVar('arg', false, 'GET', 'WORD');if( $cmd !== false && !in_array($cmd, $allow) ){ $cmd .= ' '.escapeshellarg( $arg ); system( $cmd );} Using the correct escape mechanism for the system we are accessing is imperative in preventing code injection attacks. SQL Injection Probably one of the most publicized vulnerabilities in PHP applications, SQL injection is potentially fatal. It is caused by inadequate processing of data before database queries are executed. Joomla! provides us with the JDatabase methods getEscaped() and Quote() specifically for avoiding SQL injection. Consider the following value a' OR name IS NOT NULL OR name='b. If we used this value without escaping the value, we could inadvertently give an attacker access to all the records in a table: SELECT * FROM `#__test` WHERE `name`='a' OR name IS NOT NULL OR name='b' We can overcome this using the Quote() method: $db =& JFactory::getDBO();$name = $db->QuotegetEscaped(JRequest('name')); Using the getEscaped() method escapes any special characters in the passed string. In our example the inverted comas will be escaped by prefixing them with a backslash. Our query now becomes: SELECT * FROM `#__test` WHERE `name`='a' OR name IS NOT NULL OR name='b' The Quote() method is identical to the getEscaped() method except that it also adds quotation marks around the value. Generally we should use Quote() in preference to getEscaped(), because this method guarantees that we are using the correct quotation marks for the database server that is being used. Something else that we can verify is the number of results returned after we submit a query. For example, if we know that we should only get one record from a query, we can easily verify this. $db->setQuery($query);$row = $db->loadAssoc();if( $db->getNumRows() !== 1 ){ // handle unexpected query result} XSS (Cross Site Scripting) XSS is the use of scripts that are executed client side that take advantage of the user's local rights. These attacks normally take the form of JavaScript. Another, slightly less common, form of XSS attack uses specially crafted images that execute code on the client; a good example of this is a Microsoft security flaw that was reported in 2004 (http://www.microsoft.com/technet/security/bulletin/MS04-028.mspx). When we use JRequest::getVar() we automatically strip out XSS code, unless we use the JREQUEST_ALLOWRAW mask. We generally use this mask when dealing with large text fields that use are rendered using an editor; if we do not, valuable XHTML formatting data will be lost. When we use the JREQUEST_ALLOWRAW mask we need to think carefully about how we process the data. When rendering the data remember to use the PHP htmlspecialchars() function or the static JOutput class to make the data safe for rendering in an XHTML page. When using the data with the database, remember to escape the data using the database object's Quote() method. If you want to allow your users to submit formatted data, you may want to consider using BBCode (Bulletin Board Code). BBCode is a simple markup language that uses a similar format to XHTML. Commonly used on forums, the language allows us to give the user the power to format their data without the worry of XSS. There are all sorts of BBCode tags; exactly how they are rendered may differ. BBCode XHTML Example [b]Bold text[/b] <b>Bold text</b> Bold text [i]Italic text[/i] <i>Italic text</i> Italic text [u]Underlined text[/u] <u>Underlined text</u> Underlined text :) <img src="/somewhere/smile.jpg" /> [quote]Some quote[/quote] <div class="quote">Some quote</div> Some quote Joomla! does not include any BBCode-parsing libraries. Instead we must either build our own parser or include an existing library. One such BBCode library is a class available from http://www.phpclasses.org/browse/package/951.html created by Leif K-Brooks and released under the PHP License. This class gives us lots of control; it allows us to define our own BBCode tags, use HTML entity encoded data, and import and export settings. When we use BBCode, or a similar parsing mechanism, it is important that if we intend to allow the data to be editable, we store the data in its RAW state. File System Snooping A common error when working with files is to allow traversal of the file system. Joomla! provides us with a number of classes for dealing with the file system. This example imports the joomla.filesystem library and builds a path based on the value of the CGI request file (the path must not be relative). jimport('joomla.filesystem');$path = JPATH_COMPONENT.DS.'files'.DS .JRequest('file', 'somefile.php', 'GET', 'WORD');JPath::check($path); When we use the JPath::check() method, if $path is considered to be snooping, an error will be raised and the application will be terminated. Snooping paths are identified as paths that do not start with JPATH_BASE and do not attempt to traverse the tree using the parent directory indicator .. (two periods). Other classes in the joomla.filesystem library include JFile, JFolder, and JArchive. It's important to realize that none of these classes validate path parameters to prevent snooping. This is because there are times when we expect a path to be classified as snooping.
Read more
  • 0
  • 0
  • 1870

article-image-triggers-zabbix-18
Packt
29 Mar 2010
8 min read
Save for later

Triggers in Zabbix 1.8

Packt
29 Mar 2010
8 min read
Triggers are things that "fire". They are the ones that look at item data and raise a flag when the data does not fit whatever condition is defined. As we discussed before, simply gathering data is nice, but awfully inadequate. If you want anything past historical data gathering, including notifications—there would have to be a person looking at all the data all the time, so we have to define thresholds at which we want the condition to be considered worth looking into. Triggers provide a way to define what those conditions are. Earlier, we created a single trigger that was checking the system load on "A Test Host". It checks whether the returned value is larger than a defined threshold. Now, let's check for some other possible problems with a server—for example, when a service is down. The SMTP service going down can be significant, so we will try to look for such an event now. Navigate to Configuration | Hosts, choose Triggers in the first dropdown and click on the Create Trigger button. In the form that opens, we will fill in some values. Name: The contents of this field will be used to identify the trigger in most places, so it should be human-readable. This time, enter SMTP service is down. Notice how we are describing what the problem actually is. As opposed to an item, which is gathering statuses, a trigger has a specific condition to check, thus the name reflects it. If we had a host that should not ever have a running SMTP service, we could create a trigger named "SMTP service should not be running". Expression: This is probably the most important factor of a trigger. What is being checked, and for what conditions, will be specified here. Trigger expressions can vary from very simple to complex ones. This time we will create a simple one, and we will also use some help with that. Click the Select button next to the Expression fi eld to open expression building dialog. It has several fields to fill as well, so let's look at what those are. Item: Here, we can specify which item data should be checked. To do that click on the Select button. Another pop up opens. Select Linux servers in the Group dropdown, then select Another Host in the Host dropdown. We are interested in the SMTP service, so click on SMTP server status in the Description column. Pop up will close, and Item field will be populated with the chosen name. Function: Here we can choose the actual check to be performed. Maybe we can try remembering what the SMTP server status item values were—right, "1" was for server running, and "0" was for server down. If we want to check whenever the last value is 0, the default function seems to fit quite nicely, so we won't change it. N: This field allows us to set the constant used in the function above. We want to find out whenever server goes down (or status is "0"), so here the default fits as well. With the values set as above, click the Insert button. Expression field is now populated with a trigger expression {Another Host:smtp.last(0)}=0. Severity: There are five severity levels in Zabbix, and an additional "Not classified" severity. We will consider this problem to be of an average severity, so choose Average from the dropdown Before continuing, make sure the SMTP server is running on "Another Host", then click Save. Let's find out how it looks in the overview now—open Monitoring | Overview and make sure Type dropdown has Triggers selected. Great, we can see both hosts now have a trigger defined. As the triggers differ, we also have two unused cells. A newly added trigger will be flashing, thus indicating a recent change. Let's look at the trigger expression in more detail. It starts with an opening curly brace, and the first parameter is the hostname. Separated with a colon is the item key—smtp here. After the dot comes the more interesting and trigger specific thing—the trigger function. Used here is one of the most common functions, last. It always returns single value from the item history. Here it also has a parameter passed, 0, enclosed in parenthesis. For this particular function, a parameter passed with such syntax is ignored, while it could mean seconds, that would not make much sense (the function returns a single value only). Still, a parameter has to be provided even for functions that ignore it. But that's not the only parameter syntax this function supports—if the value is prefixed with a hash, it is not ignored. In that case it works like an Nth value  specifier. For example, last(#9) would retrieve the 9th most recent value. As wecan see, last(#1) is equal to last(0). Another overlapping function is prev. As the name might suggest, it returns the previous value, thus prev(0) is the same as last(#2). Continuing with the trigger expression, curly braces close to represent a string that retrieves some value. Then we have an operator, which in this case is a simple equal sign. Comparison is done with a constant number, zero. Trigger dependencies We now have one service being watched. Though there are some more monitored and now we can try to create a trigger for a HTTP server. Go to Configuration | Hosts, click on Triggers next to Another Host, then click on Create Trigger. Fill in the following values: Name: Enter WEB service is down. Expression: Click on Select, then again on Select next to the Item field. Make sure Linux servers is selected in the Group field and Another Host in the host field, then click on WEB server status in the Description column. Both function and its parameter are fine, so click on Insert. That inserts the expression {Another Host:net.tcp.service[http,,80]. last(0)}=0. The trigger depends on: Our host runs software that is a bit weird—the web service is a web e-mail frontend, and it goes down whenever the SMTP server is unavailable. This means the web service depends on SMTP service. To configure that, click on Add next to the New dependency. In the resulting window, make sure Linux servers is selected in the Group dropdown and Another Host is selected in the Host dropdown, then click on the only entry in the Description column—SMTP service is down. Severity: Select Average. Comments: Trigger expressions can get very complex. Sometimes the complexity can make it impossible to understand what a trigger is supposed to do without serious dissection. Comments provide a way to help somebody else, or yourself, to understand the thinking behind such complex triggers later. While our trigger still is very simple, we might want to explain the reason for the dependency, so enter something like Web service goes down if SMTP is inaccessible. When you are done, click Save. Notice how, in the trigger list, trigger dependencies are listed in the Name column. This allows for a quick overview of any dependent triggers without opening the details of each trigger individually. With the dependency set up, let's find out whether it changes anything in the frontend. Navigate to Monitoring | Overview. Indeed, the difference is visible immediately. Triggers involved in the dependency have arrows drawn over them. So an upwards arrow means something depends on this trigger or was it the other way around? Luckily, you don't have to memorize that. Move the mouse cursor over the SMTP service is down trigger for Another Host, the upper cell with the arrow. A pop up appears, informing you that there are other triggers dependent on this one. Dependent triggers are listed in the pop up. Now move the mouse cursor one cell below, over the downwards pointing arrow. Let's see what effect other than the arrows does this provide. Open Monitoring | Triggers and make sure both Host and Group dropdowns say all, then bring down web server on "Another Host". Wait for the trigger to fire, look at the entry. Notice how an arrow indicating dependency is displayed here as well. Move the mouse cursor over it again, and the dependency details are displayed in a pop up. Hey, what's up with the Show link in the Comments column? Let's find out—click on it. As can be seen, the comment we provided when creating the trigger is displayed. This allows for easy access to comments from the trigger list both for finding out more information about the trigger and updating the comment as well. Click on Cancel to return to the trigger list. Now, stop the SMTP service on the "Another Host".
Read more
  • 0
  • 0
  • 4725
Unlock access to the largest independent learning library in Tech for FREE!
Get unlimited access to 7500+ expert-authored eBooks and video courses covering every tech area you can think of.
Renews at €18.99/month. Cancel anytime
article-image-using-proxies-monitor-remote-locations-zabbix-18
Packt
29 Mar 2010
7 min read
Save for later

Using Proxies to Monitor Remote Locations with Zabbix 1.8

Packt
29 Mar 2010
7 min read
When proxies are useful A server is not always able to connect directly to the monitored machines. We could use active items everywhere (where Zabbix agents connect to a Zabbix server, discussed in Chapter 3), but that would require access from all of the monitored hosts to the Zabbix server. Additionally, that would not work for SNMP, IPMI, and other monitoring methods. This is common when devices from other organizations have to be monitored, or when such restrictions are in place in a large corporate network. This is where Zabbix proxy comes in. When set up, only connections to the Zabbix server come from the proxy, which, in turn, does all the monitoring on behalf of the Zabbix server. In this example, there's no need for individual connections from Zabbix to individual devices in the remote location or the other way around—single firewall rule to allow Zabbix proxy connections to the Zabbix server is sufficient. So how does the proxy work? Let's repeat: Only the Zabbix proxy connects to the Zabbix serverv. This bit of information is crucial to understanding how it actually works. When the proxy connects to the server, it requests configuration information about what it has to monitor, then goes and does just that. As data is gathered, proxy sends it back to the server. Does that sound familiar? It should, because that part sounds just like an active agent, except that the proxy can gather data from different systems pretty much like the Zabbix server can. It sounds almost like a super agent. Actually, it is said that the proxy was at first internally named "super agent", which confirms the similarity. The Zabbix proxy is a very useful feature, the first stable Zabbix version to introduce it was 1.6, back in 2008. Given the usefulness of the Zabbix proxy, it is surprising that for a long time no other solutions provided something comparable. Today, Zabbix proxies continue to lead the way by having and improving features that are considered most useful for remote data collection. As we will see later, there are other benefits that proxies can provide, so let's get to actually setting one up. Setting up the proxy W hen setting up the proxy for this exercise, it is suggested you use a separate (physical or virtual) machine. If not possible, you can choose to run proxy on the same machine, as hints will be provided for such a setup as well. Before proceeding, we will have to compile the proxy itself. When compiling the proxy there are a few mandatory parameters, --enable-proxy being one. Zabbix proxy also needs a database, so you have to include support for one. While it is not suggested to use SQLite on Zabbix itself because of the performance issue, the proxy might be a good candidate. Unless it is going to monitor lots of systems, SQLite's performance can be satisfactory, and it is trivial to set up because Zabbix server creates and populates the database automatically. Additionally, Zabbix proxy must have support compiled in for things it will be monitoring, like SNMP, IPMI, and web monitoring. Let's say we want to compile Zabbix proxy with SQLite support and the ability to monitor web, SNMP, and IPMI. Obviously, we will need all the relevant support libraries mentioned when we first compiled Zabbix, but this time we'll also need another one—SQLite development headers. On most distributions they will be included in a package named sqlite-devel or similar, so make sure to install this package before proceeding. Then, on the machine where you plan to install Zabbix proxy, enter the directory where the Zabbix installation source has been extracted to and execute: $ ./configure --enable-proxy --with-sqlite3 --with-libcurl --with-netsnmp--with-openipmi && make This will both configure and compile Zabbix proxy. We can again use the simple and universal solution to create a more or less proper package by executing as root: # checkinstall --nodoc --install=yes -y --pkgname=zabbix-proxy The proxy binary is now compiled and in place, we can put our hands on the configuration now. First things first—it must be placed in the correct location: # cp misc/conf/zabbix_proxy.conf /etc/zabbix Now open /etc/zabbix/zabbix_proxy.conf as root and make some changes to get the proxy running: Hostname=proxy Hostname is an important parameter. As with active agents, if it's wrong, nothing will work. Server=<Zabbix server IP address> Zabbix proxy connects to the Zabbix server, so it must know where to connect to. DBName=/tmp/zabbix_proxy.db We will try to use an SQLite database, thus the full path to the database file must be specified. Let's try to start the Zabbix proxy now, as root execute: # zabbix_proxy Wait, we did not create the database like we did when installing the server—the proxy couldn't start up, right? Let's look at the log file—open /tmp/zabbix_proxy.log. Paying close attention we can find some interesting log records. 27982:20090729:131636.530 Cannot open database file "/tmp/zabbix_proxy.db": No such file or directory27982:20090729:131636.531 Creating database ... Wonderful. Zabbix proxy can automatically create the required SQLite database and populate it. We could also verify that Zabbix proxy is listening on the port it should be by running: $ netstat -ntl | grep 10051 The output should confirm that everything is correct. Monitoring a host through a proxy N ow that we have the proxy compiled, configured, and running, we have to inform Zabbix about it somehow. To do this, open Administration | DM in the frontend, then select Proxies in the first dropdown. No proxies are listed, so we have to create one—click the Create Proxy button and complete the form. Enter proxy in the Proxy name field. The section below; Hosts, allows us to specify which hosts will be monitored by this proxy. To make one host monitored by proxy, mark Another Host in the Other Hosts list box and click on the << button. When you are done, click Save. This server should now be monitored by the proxy, right? Again, not quite. As you might remember, we were setting the Zabbix server IP address in the agent configuration files so that agents would accept connections from these servers and send active check data to them. When we change a host to be monitored by a proxy, all connections will be made from the proxy, thus the proxy address must be added to the agent daemon's configuration file. As root, edit /etc/zabbix/zabbix_agentd.conf on Another Host and change the Hostname line to have the Zabbix proxy IP address instead of the Zabbix server IP address. Save the file, then restart the agent daemon. Now this agent will send all data to the proxy only, no connection will be made to or from Zabbix server. If, on the other hand, you have the proxy running on the same host as Zabbix server, agent will not notice that it is now queried by the proxy, not by the server, because the source IP would not have changed. The agent is still requesting and sending active checks to port 10051, Zabbix server port. To change this for the proxy port, edit /etc/zabbix/zabbix_agentd.conf on Another Host as root and change the ServerPort line to read: ServerPort=10052 Don't forget to remove the leading hash mark, then restart the agent daemon. With the host monitored solely by the proxy, let's check whether there are any indications of that in the frontend. Open Configuration | Hosts, make sure Linux servers is selected in the Group dropdown and take a look at the Name column. As can be seen, Another Host is now prefixed by the proxy name and reads proxy:Another Host. Of course, we are not limited in our proxy name choice, we could have named it "Nothing to see here" for all that the Zabbix server cares. But do we have to always go to Administration | DM whenever we want to make a host monitored by proxy? Click on Another Host in the Name column, and observe the available properties. There's one dropdown available, Monitored by proxy. Using this dropdown we can easily assign a host to be monitored by the chosen proxy (remembering to change server IP address in the agent daemon configuration file, if using active checks).
Read more
  • 0
  • 0
  • 11685

article-image-users-and-permissions-cms-made-simple-16-part-2
Packt
29 Mar 2010
8 min read
Save for later

Users and Permissions with CMS Made Simple 1.6: Part 2

Packt
29 Mar 2010
8 min read
Designer permissions If you have a user with strong HTML and CSS knowledge who is able to make reasonable changes to the entire layout of the website or just to the module templates, then you can assign that user to the group Designer. A designer must have the following set of permissions: Add Stylesheet Associations Add Stylesheets Add Templates Manage Menu Manage Themes Modify Files Modify Stylesheet Associations Modify Stylesheets Modify Templates Remove Stylesheet Associations Remove Stylesheets Remove Templates View Tag Help This set of permissions allows the designer of the website to perform any task related to the design of the template. However, the designer will not be able to edit the content, submit news, or set any site preferences. Time for action – creating a test area for the designer In the admin console, click on Content | Pages. Click on Add New Content and create an inactive Section Header named Design Test as shown: Click on Submit. Click on Add New Content again, choose the section header Design Test (created in step 2) in the field Parent. Select the Options tab, scroll down, and select the user or the whole group Designer in the field Additional Editors. Click on Submit. Log out and log in again as Designer. Click on Content | Pages to see the test page. What just happened? You have created a new page and placed it below an inactive Section Header. The pages placed below inactive pages cannot be displayed in the website structure. Even if you use the parameter show_all with the Smarty plugin menu (for example, in the sitemap) the page will not be displayed. However, it is active, and it can be accessed directly through the magnifying glass icon, and can be used by the designer as a test area. In the admin console (Site Admin | Global Settings), under the Advanced Setup tab, you can define Basic Properties for the additional editors such as Image. Here, the editor can choose an image from a drop-down list and thus assign an image to a certain location in the template defined by the designer. There is a useful third-party module called Template Externalizer. It allows you to use any external editor to edit your templates and stylesheets. After installing and turning on Development Mode, the module automatically extracts all stylesheets and templates into the specified directory. If you modify templates in this external directory, changes are automatically detected, imported to the database, and take effect immediately. When the module is installed, there is the permission Template Externalizer that can be granted to the group Designer. Viewing the admin log The admin log records the details of the changes made to the site by all users. This log can be found in the admin console (Site Admin | Admin Log) and includes records about the creating, deleting, and changing of: Pages and global content blocks Templates and stylesheets Users, groups, and permissions Site preferences Modules At the top of the log, you will find a navigation section providing links to the first, next, previous, and last pages of the log. There is also a link to download the complete log as a tab separated text file. At the bottom is the Clear Admin Log link. This will clear the entire log. Important! You won't be asked to confirm the Clear Admin Log, and this action cannot be undone once completed. Once the admin log is cleared, there is no evidence of who has changed anything on the website and what the changes were. Therefore, there is even a separate permission called Clear Admin Log that is granted separately from the permission Modify Site Preferences. There are five columns in each log entry, which are as follows: User: This shows the username of the user who performed the action. Even if the user is deleted later, the username is still saved in the log. Item ID: This shows the database ID of the affected item. Note that item IDs are only unique to the Item Name shown in the next column and not across the whole database, so the same item ID may appear repeatedly. Item Name: This shows the name of the item affected. Action: This describes the type of change made to the item. Date: This saves the date and time the change was made. If you have novice users with access to the admin console, then you probably would like to keep all versions of the content to be able to restore them if something goes wrong. There is no such feature in the standard installation of CMS Made Simple, but there is a nice third-party module that you can install additionally. Archiving changes and restoring them Once the Archiver module is installed, it keeps a copy of every content page, global content block, stylesheet, or template that is edited or deleted. It also provides the possibility to restore anything in the archive to the current state. This means that your users can edit various aspects of the site, and you can reverse their changes later. To install the Archiver module, open the admin console, and click on Extensions | Module Manager. Click on the Available Modules tab, and then click the Download & Install link which can be found in the same line as the module name. The module is installed. After installation, the module will automatically start saving changes into the archives. For example, if you would like to track the changes of the start page, open the page, and save it without any changes, so that the first version of the page is created. This version will be used as a base for future restorations. Time for action – restoring changes made by an editor Assuming that you have installed the Archiver module, as just described, you can restore the changes made by the editor as follows: Log in as the editor and edit any page that you are allowed to. Log out and then log in again with the administrator account. Click on Content | Archive Manager Module. Search for the name of the page that has been edited in step 1, and click on it. In the Expanded Archive View, find the second last version (revision) of the page and click on the last icon in the column Operation. View the page. What just happened? You have restored the older version of the content and made it to the current one. The editor's version is not deleted but just replaced, so that you can restore it any time. You can automatically purge archives either by the number of stored versions for each item (that is, keep only the last five versions of each page, global content block, stylesheet, or template) or by date (that is, keep the versions of the last seven days only). For automatic purge setup, click the Archive Preferences link in the admin area of the module (Content | Archive Manager Module). You do not have to purge archives, though you can keep accumulating all changes. However, if you have a lot of changes made daily, you must purge your archive to prevent an overflow of the database. Overview of all default permissions Permissions are always given to the group and are shared by all users assigned to this group. In the following table, the first column is the name of the permission, the second column is a suggestion as to what role the permission can be granted to, and the third column advises you if there are some preconditions for the permission to take effect. Permission Suggestion for the role Description Add Global Content Blocks Editor The group is allowed to create new global content blocks (Content | Global Content Blocks). Depends upon the permission Modify Global Content Blocks. Add Groups Admin The group is allowed to create user groups (Users & Groups | Groups). Depends upon the permission Modify Groups. Add Pages Editor The group allows the creation of children content pages below the pages where the user is an owner or an additional editor. The user must be set as Owner of the page or an Additional Editor. Add Stylesheet Associations Designer The group is allowed to associate stylesheets with templates. Add Stylesheets Designer The group is allowed to create new stylesheets. Add Templates Designer The group is allowed to create new templates. Add Users Admin The group is allowed to create new users with access to the admin console. Allow usage of advanced profile in TinyMCE Editor Users in this group will automatically get advanced profile settings made for the TinyMCE module. However, they are not able to change the profile itself. Approve News For Frontend Display Editor Allows changing the Status field of the news item from Draft to Published. The user in this group is also able to edit news articles. Clear Admin Log Admin Clear the history in Site Admin | Admin Log. Depends upon the permission Modify Site Preferences. Delete News Articles Editor The group is allowed to delete news articles. Depends upon the permission Modify News. Manage All Content Editor The group is allowed to create, move, and delete pages. The group is allowed to access the Options tab while editing the pages and change anything that can be found on the tab in contrast to the permission Modify Any Page. Manage Menu Designer The group can modify menu templates and create new menu templates.
Read more
  • 0
  • 0
  • 1587

article-image-users-and-permissions-cms-made-simple-16-part-1
Packt
29 Mar 2010
6 min read
Save for later

Users and Permissions with CMS Made Simple 1.6: Part 1

Packt
29 Mar 2010
6 min read
Understanding users and their roles A role is a collection of permissions grouped by general tasks that the user has to be able to perform on the website. An editor may be responsible for creating, reorganizing, and editing pages. A designer does not need to have any permission for page operations, but for creating and editing templates (including module templates). An administrator is a person who has all permissions in the admin console and has unrestricted access to the entire admin console. In CMS Made Simple, three roles are suggested by default—editor, designer, and administrator. The first user created during installation of CMS Made Simple gets the administrator role by default. This user cannot be deleted, deactivated, or removed from the administrator group, as it would mean that there is no administrator for the website at all. You should choose the name of this user and pay attention to the password strength. Members of the administrator group automatically get all the permissions. Let's see how you can create a new user and learn about the minimum features that every user has, independent of his/her role. Time for action – creating a new user In the admin console, click on Users & Groups | Users. Click on Add New User, and fill in the fields, as shown in the following screenshot: Click on Submit. Log out (CMS | Logout) and log in as Peter. The admin console should now look as shown in the following screenshot: What just happened? You have created a new user without assigning him to any group. This user can log in to the admin console. There are only two main menu items that the user can access—CMS and My Preferences. The user can change his name, password, and e-mail address in the MyAccount section. He can define his personal preferences such as language, admin template, set default start page for the admin console, and more. He is also able to manage his personal shortcuts. It is important to define an e-mail address for every user, as this e-mail is used to recover the password, in case the user forgets it. On the login screen of the admin console of CMS Made Simple (when you are not logged in), you will find the link Forgot your password. Click it, enter Peter in the Username field, and click on Submit. An e-mail will be sent to the e-mail address associated with this user. If no e-mail address has been set for this user, then automatic password recovery is not possible. In this case, only the administrator of the website can reset the user's password. The administrator of the website can set any user as inactive by clicking the icon with a green tick in the column Active (Users & Groups | Users). The user account is not deleted, but the user is not able to log in to the admin console until his account has been activated again. If you delete the user, all permissions and personal user preferences will be irrevocably removed. If the user is not assigned to any group, then he is not allowed to do anything other than changing his personal settings. Let's assign the user Peter to the editor group to see what tasks he will be allowed to perform as an editor. Time for action – assigning a user to a group In the admin console, click on Users & Groups | Users. Select the user Peter for edit by clicking on his username. Select the Editor checkbox at the bottom of the screen, as shown in the following screenshot: Click on Submit. Log out (CMS | Logout) and log in as Peter. The admin console should look as shown in the following screenshot: What just happened? You have given the user additional permissions. Now, he can access a new menu item called Content. There are no content pages, but only News that Peter can submit. Let's see what permissions Peter has now. In the admin console, click on Users & Groups | Group Permissions. In the first column, all available permissions are listed. To the right of the permission, there are three columns, one for each group—Admin, Editor, and Designer. You can limit the view to only one group by selecting the group at the top of the table from the drop-down list. Find all selected checkboxes in the Editor column to see what permissions the user assigned to this group gets. You can see that only the Modify News permission is checked for the group. This means that the user can create news articles and edit existing news. When the user creates a new item, the news is automatically saved as a draft, so that only the administrator of the page or a user who has the Approve News For Frontend Display permission can publish the article on the website. Peter is not allowed to delete news articles (permission Delete News Articles) and has no access to the content pages (permission Modify Any Page or Manage All Content). Content permissions As the target goal of CMS Made Simple is content management, the permissions on editing content are the most flexible. You can create and manage as many editors for the website as you like. Moreover, you can create editors with different access levels thus thoroughly separating who is allowed to do what on your website. For example, the permission Manage All Content will give the group full access to all the features that are available with the administrator account in Content | Pages. A user assigned to this group can: Create new pages Reorder and move them through the hierarchy Make pages inactive or prevent them from showing in the navigation Change the default page of the website Delete pages Edit pages including all the information placed in the Options tab To restrict the features mentioned above, you can grant the permission Modify Any Page. This permission allows us to edit the content only. The Options tab is not shown for the users with this permission, so that any information placed in the Options tab cannot be changed. In addition to the last permission, you can allow some fields from the Options tab, so that the editor is able to change the template or mark the page as inactive.
Read more
  • 0
  • 0
  • 3498

article-image-openx-advanced-reports
Packt
29 Mar 2010
3 min read
Save for later

OpenX Advanced Reports

Packt
29 Mar 2010
3 min read
Advanced reports section provides a more organized and easier way to analyze OpenX statistics to work further with MS Excel. There are three types of advanced analysis reports: Advertising analysis report: This report provides a breakdown of advertising statistics for a particular advertiser or publisher. The generated report has three sections—daily, campaign, and zone breakdowns. Campaign analysis report: This report type is suitable to analyze the details of a particular campaign. There are three breakdowns including day, banner, and zone. Campaign delivery report: This advanced report shows the delivery statistics of campaigns for a certain selected period. It also highlights the underperforming campaigns. Advertising analysis report Now let's learn how to retrieve one of the most useful analysis reports in OpenX. Time for action – getting advertising analysis reports Click on Advanced Reports link in Statistics menu. Click on Advertising Analysis Report link in Standard Reports section. Click on the Generate button, without changing any options. Choose Open with Microsoft Office Excel (default) and click on OK button. We can see the Daily Breakdown tab selected by default. Click on Campaign Breakdown tab to get the details of all campaigns. Finally, click on Zone Breakdown tab to see the statistics of all zones What just happened? We learned how to generate an advertising analysis report in a few steps. This helps us get very useful statistics to determine the daily progress, success rates of campaigns, and zones that are organized in separate Excel tabs for easy analysis. Have a go hero – exploring other advanced report types Now, go and examine other report types including campaign analysis report and campaign delivery report. Try to understand the differences between the report types. Have a go hero – playing with statistics columns Try to specify the columns you need for online statistics screen using the account preferences. Pop quiz – understanding OpenX reports and statistics Suppose we (as an account manager) opened an advertiser account user for one of the advertisers. Which of the following report types will be available for the new user? Advertiser analysis report Campaign analysis report Campaign delivery report All of the reports None of the reports Summary In this article series, we have learned how to use reports and online statistics to evaluate the performance of OpenX advertisers, campaigns, banners, websites, and zones. We have specifically covered: Advertisers and campaigns statistics Exporting data to Excel for further analysis Types of advanced OpenX reports Getting advertising analysis reports in Excel If you have read this article you may be interested to view : Reports and Statistics in OpenX Ad Server Start Ad Serving with OpenX Start Ad Serving with OpenX- A Sequel
Read more
  • 0
  • 0
  • 1855
article-image-start-ad-serving-openx
Packt
29 Mar 2010
3 min read
Save for later

Start Ad Serving with OpenX

Packt
29 Mar 2010
3 min read
Basic OpenX Ad serving steps diagram The following diagram shows the necessary steps for the completion of the serving an advertisement on a website using OpenX Ad Server: Sample Amazon.com banner serving flowchart In this scenario, we will start adding an Advertiser (Amazon). Then, we will create a Campaign (Amazon Toys & Games). We will add a Banner (Amazon Puzzle Games for Kids) to this campaign. Then, we will define our sample website at OpenX. We will create a zone (Toys & Games Zone) for this website. The next step is to link a banner to this zone. Finally, we will complete serving advertisements by embedding the zone code to a page on the website and visiting this page through a browser. Time for action – adding Amazon.com as an advertiser In this section, we will learn how to add Amazon.com as an advertiser. As you may have probably heard, Amazon runs a very popular affiliate program that is called as Amazon Associates. You can earn commissions from each sale that results from the links and banners you placed on your website by using this program. Read more about Amazon Associates program and register for free at http://affiliate-program.amazon.com. As the example will be a fictional one here, you don't essentially need to register at Amazon affiliate program before starting. The example will help you understand how to add any advertiser in a similar way. Let's log in to OpenX Authentication panel. Use the Username and Password that we have created earlier.The login page looks like this: Click on Inventory tab at the top menu and then click on Add new advertiser link. We are now in Add new advertiser page. Fill Name, Contact, and Email fields. You can type your own information for Contact and Email fields. Leave other fields as they are, untouched with default settings. Click Save Changes button to complete adding an advertiser. What just happened We have learned how to add a new advertiser to OpenX. We have logged into OpenX management screen using the administrator user and provided the basic necessary fields: Name, Contact, and Email. Time for action – adding a campaign for Amazon.com Now, let's add a simple campaign for Amazon.com. Click on Add new campaign link near Amazon advertiser on Advertisers page. Fill the Name field in as Amazon – Toys & Games and select Contract (Exclusive) option under it Leave Date, Pricing, and Priority in relation to other campaign sections to their default settings. Leave Delivery capping per visitor and Miscellaneous sections untouched as well. Click on Save Changes button to complete adding Amazon - Toys & Games campaign. What just happened We have learned how to add a campaign for an advertiser using minimum requirements. We used Name and Campaign type fields and ignored other fields as we will cover them later.
Read more
  • 0
  • 0
  • 2810

article-image-start-ad-serving-openx-sequel
Packt
29 Mar 2010
2 min read
Save for later

Start Ad Serving with OpenX- A Sequel

Packt
29 Mar 2010
2 min read
Time for action – adding a zone to the website In this section, we will add a zone to the website. Click on Add new zone link on websites screen near our newly defined website name. Note that your website name differs from this sample. We only need to fill in the Name field and choose the Size that is exactly the size of the banner we have provided before. As our banner size is 728x90, we do the same for zone size. The fi elds highlighted with a red rectangular border in the following screenshot show these fields: Click Save Changes button to complete adding a zone for the website. What just happened We have learned how to add a zone for the newly added website definition. We defined a name for the zone and a size, which is the same size as the previously uploaded banner Time for action – linking the Amazon banner to the zone In this section, we will link the banner to the newly created zone Click on the Linked Banners link near our zone definition. Select Link individual banners option. Let's browse until we find our banner and let's choose it. Click the small arrow near the banner name. Now, we have completed linking the banner to our zone. What just happened We have learned how to link a banner to a website zone. We chose Link individual banners option, then browsed advertisers, campaign, and banners lists until we find and choose our banner from the list. Note that banner and zone sizes have to match in order to list the available banners in the linking screen.
Read more
  • 0
  • 0
  • 1783

article-image-customizing-and-extending-apache-myfaces-extval
Packt
29 Mar 2010
8 min read
Save for later

Customizing and Extending Apache MyFaces ExtVal

Packt
29 Mar 2010
8 min read
The ExtVal framework is very extensible, and extending it is fairly simple. The framework uses the convention over configuration paradigm. This means that if we’re happy with the conventions of the framework, we don’t have to configure anything. As an example of the extensibility of ExtVal, in this section we’re going to change the default behavior of ExtVal’s @Pattern annotation. The @Pattern annotation accepts an array of Strings for the value argument. This means that more than one regular expression can be used to validate the input. By default, all regular expressions have to be matched in order for an input string to be valid. For example, if the patterns [A-Z].S* and [A-Za-z]* are combined, this effectively means that only words starting with a capital letter and containing only the characters a through to z, which may or may not be in capitals, are allowed. Note that this can be achieved with one single expression too—[A-Z].[A-Za-z]*. Although combining two regular expressions with an “and” relation might be useful sometimes, having multiple expressions where only one of them has to be matched can be quite powerful too. We can think of a list of patterns for various (international) phone number formats. The input would be valid if one of the patterns is matched. The same can be done for postal codes, social security codes, and so on. So let’s see how we can change the behavior of ExtVal to achieve this Implementing a custom validation strategy ExtVal uses the concept of Validation Strategy for every type of validation. So, if an @Pattern annotation is used, ExtVal will use a PatternStrategy to execute the validation. We can implement our own ValidationStrategy to override the functionality of ExtVal’s standard PatternStrategy. The easiest way to do this is to create a subclass of AbstractAnnotationValidationStrategy <Pattern>: package inc.monsters.mias.extval;import javax.faces.application.FacesMessage;import javax.faces.component.UIComponent;import javax.faces.context.FacesContext;import javax.faces.validator.ValidatorException;import org.apache.myfaces.extensions.validator.baseval.annotation.Pattern;import org.apache.myfaces.extensions.validator.core.metadata.MetaDataEntry;import org.apache.myfaces.extensions.validator.core.validation.strategy.AbstractAnnotationValidationStrategy;public class PatternOrValidationStrategy extends AbstractAnnotationValidationStrategy<Pattern> { @Override protected String getValidationErrorMsgKey(Pattern annotation) { return annotation.validationErrorMsgKey(); } @Override protected void processValidation(FacesContext facesContext, UIComponent uiComponent, MetaDataEntry metaDataEntry, Object convertedObject) throws ValidatorException { Pattern annotation = metaDataEntry.getValue(Pattern.class); boolean matched = false; String expressions = null; for (String expression : annotation.value()) { if (convertedObject != null && java.util.regex.Pattern.compile(expression).matcher(convertedObject.toString()).matches()) { matched = true; break; } else {  if (expressions == null) { expressions = expression; } else { expressions += ", " + expression; } } } if(!matched) { FacesMessage fm = new FacesMessage(FacesMessage.SEVERITY_ERROR, getErrorMessageSummary(annotation), getErrorMessageDetail(annotation).replace("{0}",expressions)); throw new ValidatorException(fm); } }} The most important part of this class is, of course, the processValidation() method. This uses the MetaDataEntry object to access the annotation that defines the validation. By calling annotation.value(), the array of Strings that was set in the @Pattern annotation’s value attribute is obtained. By iterating over that array, the user input (convertedObject.toString()) is matched against each of the patterns. If one of the patterns matches the input, the boolean variable matched is set to true and the iteration is stopped. A ValidatorException is thrown if none of the patterns matches the input. The else branch of the outer if statement is used to create a list of patterns that didn’t match. That list is appended to the error message if none of the patterns matches. Now that we’ve created our own custom validation strategy, we will have to tell ExtVal to use that instead of the default strategy for the @Pattern annotation. The next section shows how to do that. Configuring ExtVal to use a custom validation strategy The most straightforward way to configure a custom Validation Strategy in ExtVal is to write a custom Startup Listener that will add our Validation Strategy to the ExtVal configuration. A Startup Listener is just a JSF PhaseListener with some specific ExtVal functionality—it deregisters itself after being executed, thus guaranteeing that it will be executed only once. We can simply subclass ExtVal’s AbstractStartupListener. That way, we don’t have to implement much ourselves: package inc.monsters.mias.extval;import org.apache.myfaces.extensions.validator.baseval.annotation.Pattern;import org.apache.myfaces.extensions.validator.core.ExtValContext;import org.apache.myfaces.extensions.validator.core.initializer.configuration.StaticConfigurationNames;import org.apache.myfaces.extensions.validator.core.initializer.configuration.StaticInMemoryConfiguration;import org.apache.myfaces.extensions.validator.core.startup.AbstractStartupListener;public class PatternOrStartupListener extends AbstractStartupListener { @Override protected void init() { // 1. StaticInMemoryConfiguration config = new StaticInMemoryConfiguration(); // 2. config.addMapping(Pattern.class.getName(), PatternOrValidationStrategy.class.getName()); // 3. ExtValContext.getContext().addStaticConfiguration(StaticConfigurationNames.META_DATA_TO_VALIDATION_STRATEGY_CONFIG, config); }} There are three important steps here, which tie up with the numbers in the previous code: Create a new StaticInMemoryConfiguration object. Add a mapping to the StaticInMemoryConfiguration object. This maps the @Pattern annotation to our own PatternOrValidationStrategy validation strategy implementation. The addMapping() method expects two Strings, each containing a fully qualified class name. The safest way to get these class names is to use class.getName() because that will work even if the class is moved to another package. This step actually maps the @Pattern annotation to the PatternOrValidationStrategy. The created StaticInMemoryConfiguration object has to be added to the ExtValContext to become effective. Note that we don’t implement the usual PhaseListener methods here. They are already implemented by the AbstractStartupListener. The last thing that we have to do is to add this Startup Listener to our faces-config.xml file as an ordinary PhaseListener, as follows: <phase-listener>inc.monsters.mias.extval.PatternOrStartupListener</phase-listener> Mapping an annotation to a validation strategy is one of the many name mappings that are performed inside the ExtVal framework. ExtVal implements its own NameMapper mechanism for all mappings that are performed inside the framework. As with nearly every part of ExtVal, this NameMapper mechanism can be overridden if desired. See also the Extending ExtVal in many other ways section. Using alternative configuration add-ons Although implementing a custom Startup Listener is fairly simple, it might not be the most ideal way to configure ExtVal—especially if a lot of configuration changes have to be made. The author of ExtVal has created two add-ons for ExtVal that provide alternative ways to configure ExtVal. Those add-ons are not apart of the ExtVal project. The author of ExtVal provides them as examples, but no support is available for them. If they fit your needs, you can use them. If not, you can use them as a starting point to implement your own configuration add-on. One alternative is the annotation-based configuration. In this case, custom implementations can be annotated with special annotations, and should be put in a special base package. At application startup, the base package will be scanned for annotations, and the found annotations will be used to create the necessary configuration. See the Extending ExtVal with add-ons section for the download location, and installation instructions for this add-on. Some basic usage documentation is provided at http://os890.blogspot.com/2008/10/myfaces-extval-config-extension.html. One alternative is the annotation-based configuration. In this case, custom implementations can be annotated with special annotations, and should be put in a special base package. At application startup, the base package will be scanned for annotations, and the found annotations will be used to create the necessary configuration. See the Extending ExtVal with add-ons section for the download location, and installation instructions for this add-on. Some basic usage documentation is provided at http://os890.blogspot.com/2008/10/myfaces-extval-config-extension.html. Testing the custom validation strategy Now that we’ve implemented our custom Validation Strategy, let’s do a simple test. For example, we could add the @Pattern annotation to the firstName property of the Kid class, as follows: @Column(name = "FIRST_NAME")@Pattern(value={"[A-Za-z]*", "[0-9]*"})private String firstName; In this case, “Shirley” would be valid input, as would be “4623”. But “Shirley7” wouldn’t be valid, as none of the regular expressions allow both letters and digits. If we had used the default PatternStrategy, no valid input for the firstName field would be possible, as the regular expressions in this example exclude each other Of course this test case is not very useful. As mentioned before, having different patterns where only one of them has to be matched can be very useful for different (international) phone number formats, postal codes, social security codes, and so on. The example here is kept simple in order to make it easy to understand what input will match and what input won’t match.
Read more
  • 0
  • 0
  • 1838
article-image-product-cross-selling-and-layout-using-panels-drupal-and-ubercart-2x
Packt
25 Mar 2010
7 min read
Save for later

Product Cross-selling and Layout using Panels with Drupal and Ubercart 2.x

Packt
25 Mar 2010
7 min read
Product cross-selling Product cross-selling is a very powerful policy that you might be familiar with. For instance Amazon.com was one of the early adopters of recommendation systems in a very sophisticated manner, and it boosted its online selling rates by hundreds of millions of dollars. If we move on to more algorithmic complexity, a more sophisticated example is Netflix, an online movie rental service, and the core of its business is its recommendation system and the hype that surrounds it. Finally, the most recent and simplest to implement is Last.fm with a very elegant and efficient recommendation algorithm. By adopting Drupal and Ubercart, things become pretty straightforward, as you have good modules that encapsulate the complexity of recommendation algorithms and require little configuration, and you may as well provide to your end customers a great consumer experience. In addition to that, do not forget the powerful and robust taxonomy mechanism that Drupal implements in its core and the site-wide content tagging it provides, so the relevant items and items that could be used in conjunction could be categorized. So now without further delay, we will go through all these interesting possibilities that our Drupal online shop could offer. Using taxonomies As we have already mentioned, taxonomies are the core of the Drupal system and grasping the high-level implementation can save us a lot of trouble most of the time. Taxonomies often help us create references for our Drupal system nodes, differentiate between them, and create easy-to-use, intuitive, and searchable views on our content. Therefore, in our example, the basic idea is to create a taxonomy not only for products that can be sold as groups (as we already have Ubercart product kit for that), but rather for the products administrator to be able to tag all these relevant products in a way that high-revenue electronic shops like ExpanSys and PixMania have adopted. To achieve this we do not need any new module installation but rather the plain old Drupal taxonomy system. We will make two taxonomies: one for product mangers, which they can edit while they add new products, and another in which users can free tag your content. These free taxonomy vocabularies are also referred as folksonomies. Furthermore, everyday practice has shown that relevant taxonomy blocks can really boost your site traffic, page views, and eventually conversions that translate to purchases. The vocabularies that we will alter are the following: Community Tagging. We need this particular free tagging vocabulary to allow our end users to tag the products of our site in order to provide non-intuitive connections. Product Types. This stands for an internal tagging vocabulary with predefined terms namely offer, best price, and new product and will help create the corresponding views in order to perform product promotion in your online electronics shop. To create the new vocabularies and change the existing one, we take the following steps: Navigate to Administer | Content management | Taxonomy. Click on Add vocabulary. Fill in the name as "Community Tagging" and provide a short description. Choose Product and Product Kit as the Content types that will be associated for tagging. In the Settings pane choose Tags to allow free tagging and Multiple select. Finally choose Not in Sitemap for XML Sitemap. To add another taxonomy for product visibility options and positioning, go back to the taxonomy page and again click on Add vocabulary. Add the name "Product Type" along with a short description and click on Product and Product Kit in the Content types section. Finally add a priority 1.0 to the XML sitemap element and click on the Save button. Navigate to your newly created vocabulary terms and add the terms "offer", "best price", and "new product". This is an example of a user-defined term-tagging procedure on one of our products. Use Taxonomies for Navigation and MenusYou can also use Drupal's system pages using the taxonomy view module for category listings. The end of the URL should look like this: taxonomy/term/1 or taxonomy/term/2.Note that taxonomy URLs always contain one or more Term IDs at the end of the URL. These numbers, 1 and 2 above, tell the Drupal engine which categories to display. Now combine the Term IDs above in one URL using a comma as a delimiter: taxonomy/term/1, 2. The resulting listing represents the boolean AND operation. It includes all nodes tagged with both terms. To get a listing of nodes using either taxonomy term 1 OR 2, use a plus sign as the operator: taxonomy/term/1+2 Using recommendation systems Recommendation systems have existed a long time and make a crucial contribution in some of the most successful online shops. In this section we will focus on examples of implicit data collection of the customer's activities that include the following: Observing the items that a user views in an online store. Analyzing item/user viewing time. Keeping a record of the items that a user purchases online. Obtaining a list of items that a user has listened to or watched on his or her computer. Analyzing the user's social network and discovering similar likes and dislikes. Having these data and customer behavior in our account, it is then easy to find the optimal item suggestions that fit people's profiles. We can then provide sections like "customers who bought this book also bought" on Amazon.com suggestions. Further to our discussion we will install recommendation API and two other modules that depend on it. The Ubercart-oriented module is the Ubercart Recommender module. This module collects data through the Drupal Core Statistics module about user purchases and provides suggestions about other products that could be relevant to the returning customer. All recommendation systems assign special weights in their recommendation algorithm to purchased products since this generates returned value and we have a fully converted customer. In order to handle suggestions to users that have not made any purchases yet from our online shop we will also use the Browsing History Recommender and Relevant Content modules. You can find more information about the algorithms and the recommendation procedure implemented in the Drupal Recommender API at http://mrzhou.cms.si.umich.edu/recommender. Next we provide a synopsis of the added value and the functionality of each module: Browsing History Recommender: This module adds two blocks in your site "Users who browsed this node also browsed" and "Recommended for you". To calculate the recommendations, this module uses Drupal statistics and in particular the history data and keeps track of 30 days of users' node browsing activity. The "Recommended for you" block provides personalized node recommendations based on a user's node browsing history. Relevant Content: This module provides two ways of referencing content relevant to the node in sight. Both of these methods provide configuration to filter for specific content types and vocabularies, limit the maximum size of the result, and provide some header text. The result in both cases is a list of nodes that the module considers most relevant, based on the categorization of the current page. You can configure multiple blocks with individual settings for node type, vocabulary, maximum result size, and optional header text. Ubercart Products Recommender: This module actually adds two extra block in our blocks section, one named "Customers who ordered this product also ordered", which performs a cross check between orders of customers that bought the particular product in sight and another named "Recommended for you", which provides personalized products recommendations based on a user's purchasing history. To configure your online shop to provide content-related recommendations we need to perform the following administration steps: Download Recommender from Drupal.org by navigating here:http://mrzhou.cms.si.umich.edu/recommender Unzip the file in your site's modules directory. Navigate to the modules administration screen and activate this module. Follow the preceding procedure for the following modules also:http://drupal.org/project/relevant_contenthttp://drupal.org/project/history_rec andhttp://drupal.org/project/uc_rec After you have uploaded and installed all modules you will be able to see the following blocks in your blocks page (Administer | Site building | Blocks). Although these modules have configuration screens, they do need extra configuration or property change actions and can be assigned to your theme regions as they are from the blocks section. You can find a very thorough discussion about all recommendation modules on Drupal at http://groups.drupal.org/node/12347.
Read more
  • 0
  • 0
  • 3304

article-image-user-interface-enhancement-techniques-drupal-and-ubercart-2x
Packt
25 Mar 2010
3 min read
Save for later

User Interface Enhancement Techniques with Drupal and Ubercart 2.x

Packt
25 Mar 2010
3 min read
Improving the shopping cart Sometimes, the shopping cart is the most critical part of an electronic shop. The customer may add a lot of products in it, but if it's difficult to see its contents or to make changes, he or she will leave our store. If we improve our shopping cart, we can reduce cart abandonment and maximize our profit. Pictured cart module This module creates an enhanced version of the Ubercart cart block. The default version is rather basic with few options, but this module adds new and very useful functionalities: It shows the images of the products. It can be oriented horizontally or vertically. The user can sort the contents of the cart by name, quantity, or price. It shows extra content such as product description or attributes. To install it, browse to http://drupal.org/project/uc_pic_cart_block and right after you download the module upload it and unzip it to your site's /sites/all/modules folder and go to Administer | Site building | Modules to enable it. Then go to Home | Administer | Site building | Blocks, find the block named Pictured cart block and assign it to a region. Don't forget to disable the default cart block. To configure it, click on configure. Apart from the standard block options, you can define format and visibility settings of the cart. Ajax Cart module This module creates a different version of the default cart block. It uses AJAX, so when the customer adds a product to the cart, it updates its contents without reloading the page. Unfortunately, it is not compatible with the pictured cart module, so you have to select which one is better for your needs. To install it, browse to http://drupal.org/project/uc_ajax_cart and right after you download the module, upload it and unzip it to your site's /sites/all/modules folder and go to Administer | Site building | Modules to enable it. Then go to Home | Administer | Site building | Blocks, find the block named Ubercart ajax shopping cart and assign it to a region. Don't forget to disable the default cart block. To configure it, click on configure. There are not only the standard block options, but format and visibility settings as well. Terms of Service module This is a very simple module. It just adds a terms or service text in the cart or checkout page. The customer has to accept these terms in order to proceed. To install it, browse to http://drupal.org/project/uc_termsofservice and right after you download the module upload it and unzip it to your site's /sites/all/modules folder and go to Administer | Site building | Modules to enable it. To configure it, go to Home | Administer | Store administration | Configuration | Terms of Service. Select the page in which the terms of service will be shown, whether agreement is required, and a node that contains them, and click on Save configuration: You also have to enable the terms and conditions agreement pane, so go to Home | Administer | Store administration | Configuration | Cart Settings | Cart Panes.
Read more
  • 0
  • 0
  • 2377
Modal Close icon
Modal Close icon