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
All Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Newsletter Hub
Free Learning
Arrow right icon
timer SALE ENDS IN
0 Days
:
00 Hours
:
00 Minutes
:
00 Seconds

How-To Tutorials - CMS & E-Commerce

830 Articles
article-image-managing-discussion-forums-using-php-nuke
Packt
30 Mar 2010
8 min read
Save for later

Managing the Discussion Forums Using PHP-Nuke

Packt
30 Mar 2010
8 min read
PHP-Nuke has an awesome discussion board module, the Forums module, which is a complete application. phpBB—the leading free, open-source discussion board application—has been 'refitted' as a PHP-Nuke module, providing integration with the PHP-Nuke user accounts. Forum Structure Rather than having a single discussion area, with topics intermingling with other topics, themes of conversation are organized into a number of different containers, rather like the folder and file structure of your hard disk. The top-level of organization is the category. Note that the categories here are different from the categories we have met in the other modules! Within categories, the next level of organization is into forums. Forums consist of topics, and finally, users are able to creating postings on these topics. Thus categories, forums, and topics act like folders, with postings being analogous to the files, to continue the file system analogy. Only forum administrators can create categories and forums. Topics (and obviously postings, since they are the real body of a discussion area) can be added by users of the forum. A topic is essentially a 'first' posting, with subsequent postings on that topic being replies to the topic subject. Here is a diagram of the forums hierarchy: Although a forum is contained in a category, the term 'forum' is generally used informally to refer to the whole discussion environment, covering categories, forums, topics, and postings. When you 'post to a forum', you are actually posting to a topic in a particular forum of a certain category! The general term 'board' or 'discussion board' is usually used to refer to the whole forum experience. Access to categories and forums can be restricted to groups of users. These restricted categories and forums can also be made invisible to those unable to access them. This is in contrast with other modules in PHP-Nuke where you restrict access to the entire module. In general, visitors either see all the contents of the module or none of it. The Forums module enables a set of 'mini-administrators', forum moderators, who are able to control who is able to post what, and where. We'll see more about that later. The Forums Administration Area The Forums administration area is accessed through the PHP-Nuke Administration area, in the same way as for any other module. This brings you to an area very different from the other PHP-Nuke module administration areas. This is the phpBB administration area, and is the nerve center of your phpBB forums. The page has a frame-based layout, with the left-hand frame being the navigation panel, giving you links to the various phpBB administration tasks. The right-hand frame holds the main page content. This screen shows you some statistics about your board, and the details of current, online visitors. Clicking on the Admin Index link will return you to this page, with the Forum Index link taking you into your forums. The Preview Forum link also takes you to your forums, but opens them up in the right-hand frame of the browser, retaining the phpBB administration navigation in the left-hand frame, so you can continue to work in the phpBB administration area if you need to. phpBB is truly awesome. It is arguably one of the most impressive free, open-source PHP web applications available, and we can only scratch the surface of its true power here.. Here we will step through the tasks of creating the structure to allow users to make postings, follow the posting process, and also see how to make some basic configuration changes. Forum Configuration Just as with PHP-Nuke where we began by making changes to PHP-Nuke's site configuration, here too, we begin with some global configuration settings for phpBB. Clicking on the Configuration link in the General Admin part of the left-hand panel takes you to the phpBB configuration area. There are many options; only some of the top ones are shown here: The Domain Name, Site name, and Site description fields are similar to the Site URL, Site Name, and Slogan fields of the PHP-Nuke preferences. The Domain Name field holds the domain name of your site, and we'll set the Site name and Site description fields to match those in our PHP-Nuke site configuration. We will also set the Cookie Domain to our site domain name, and the Cookie name to dinoportalforum. Note that if you change these settings after your site has gone live with people having visited the forums and logged in, then they won't be able to log in automatically since the Forums module will be looking for a different cookie from the one they have stored in their browser. PHP-Nuke generally uses the PHP mail() function to send its emails, but the Forums module offers the option to use an SMTP server to send mail. If you know the details of an SMTP server that you can use (possibly your Internet Service Provider has given you access to an SMTP server), then you can enter the settings for this in the Email Settings panel. If you don't have access to an SMTP server, then the default action of the Forums module is to use the PHP mail() function, as PHP-Nuke would normally do. Scrolling down the screen you will find a Submit button that will save your changes. Creating a Category Click on the Management link in the Forum Admin panel to begin creating the forum structure. First, you will need to create a category: Once you enter the name for the category into the box and click on the Create new category button, you have a category. Creating a Forum When the page reloads after creating the category, you are presented with a screen confirming the creation of your forum, and a Click Here to return to Forum Administration link. Clicking this link brings you to a page with the list of current categories displayed, along with links to edit, delete, or change their ordering in the list. You are also able to continue creating new categories. Immediately underneath our new category is a box for entering the name of a new forum for that category, and clicking on the Create new forum button will create a forum of that name: When the page reloads, you will be given a screen into which you can enter a description of the forum, and set some properties for it. You can assign the forum to another category from the Category dropdown, or you can set the Forum Status. The Forum Status is Locked or Unlocked. An Unlocked forum is free for all to view and contribute to; a Locked forum requires the user to have specific access to write or post to it. There are also 'pruning' options available for removing topics that haven't seen enough activity in the forum. These options will be useful for keeping your 'board' clean over time. Clicking on the Create new forum button creates the forum: Now we have forums, we are ready for topics. It is only a matter of time before we are posting! The Visitor Experience Open a new browser window, visit your PHP-Nuke site, and click on the Forums link. The visitor is welcomed to the Forums module with a list of the categories: Clicking on the Who is Online link presents you with a list of people who are currently viewing the forum, and where they are in the forum. Clicking on one of the forums takes you to the list of topics in that forum. At the moment, our forum is empty. As the screen is encouraging us to do, we can click on the new topic button to post a new topic to the forum. We do not have to be an administrator to do this, but we do have to be a registered user of the PHP-Nuke site. Posting a Topic The form for posting a new topic is rather exciting: You can enter the Subject of your topic, and enter the body of the topic in the Message body box. You are able to use a range of formatting effects within the body of your posting, including inserting those the little emoticons by clicking on them to add them to your text. Before posting your topic, it is worth taking a moment to preview it by clicking on the Preview Post button: If you are happy with the posting as it is, click on the Submit button and the posting is submitted. Your new topic is displayed in the forum's topic list: Clicking on the topic title brings up the submitted postings for that topic. At this point, we have only one—the topic posting: Users can now continue the discussion by posting a reply to this post. The author of the post is able to reply to, edit, or delete his or her own post with the aid of the three icons in the top right-hand corner of the post before any replies have been posted to the posting.
Read more
  • 0
  • 0
  • 3309

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

article-image-customized-effects-jquery-14
Packt
30 Mar 2010
5 min read
Save for later

Customized Effects with jQuery 1.4

Packt
30 Mar 2010
5 min read
Some of the examples in this article use the $.print() function to print results to the page. This is a simple plug-in, not covered in the article. Customized effects We will describe how to create effects that are not provided out of the box by jQuery. .animate() Perform a custom animation of a set of CSS properties. .animate(properties[, duration][, easing][, callback]).animate(properties, options) Parameters (first version) properties: A map of CSS properties that the animation will move toward duration (optional): A string or number determining how long the animation will run easing (optional): A string indicating which easing function to use for the transition callback (optional): A function to call once the animation is complete Parameters (second version) properties: A map of CSS properties that the animation will move toward options: A map of additional options to pass to the method. Supported keys are: duration: A string or number determining how long the animation will run easing: A string indicating which easing function to use for the transition complete: A function to call once the animation is complete step: A function to be called after each step of the animation queue: A Boolean indicating whether to place the animation in the effects queue. If false, the animation will begin immediately specialEasing: A map of one or more of the CSS properties defined by the properties argument and their corresponding easing functions Return value The jQuery object, for chaining purposes. Description The .animate() method allows us to create animation effects on any numeric CSS property. The only required parameter is a map of CSS properties. This map is similar to the one that can be sent to the .css() method, except that the range of properties is more restrictive. All animated properties are treated as a number of pixels, unless otherwise specified. The units em and % can be specified where applicable. In addition to numeric values, each property can take the strings 'show', 'hide', and 'toggle'. These shortcuts allow for custom hiding and showing animations that take into account the display type of the element. Animated properties can also be relative. If a value is supplied with a leading += or -= sequence of characters, then the target value is computed by adding or subtracting the given number to or from the current value of the property. Durations are given in milliseconds; higher values indicate slower animations, not faster ones. The 'fast' and 'slow' strings can be supplied to indicate durations of 200 and 600 milliseconds, respectively. Unlike the other effect methods, .fadeTo() requires that duration be explicitly specified. If supplied, the callback is fired once the animation is complete. This can be useful for stringing different animations together in sequence. The callback is not sent any arguments, but this is set to the DOM element being animated. If multiple elements are animated, it is important to note that the callback is executed once per matched element, not once for the animation as a whole. We can animate any element, such as a simple image: <div id="clickme"> Click here</div><img id="book" src="book.png" alt="" width="100" height="123" style="position: relative; left: 10px;" /> We can animate the opacity, left offset, and height of the image simultaneously. $('#clickme').click(function() { $('#book').animate({ opacity: 0.25, left: '+=50', height: 'toggle' }, 5000, function() { $.print('Animation complete.'); });}); Note that we have specified toggle as the target value of the height property. As the image was visible before, the animation shrinks the height to 0 to hide it. A second click then reverses this transition: The opacity of the image is already at its target value, so this property is not animated by the second click. As we specified the target value for left as a relative value, the image moves even farther to the right during this second animation. The position attribute of the element must not be static if we wish to animate the left property as we do in the example. The jQuery UI project extends the .animate() method by allowing some non-numeric styles, such as colors, to be animated. The project also includes mechanisms for specifying animations through CSS classes rather than individual attributes. The remaining parameter of .animate() is a string naming an easing function to use. An easing function specifies the speed at which the animation progresses at different points within the animation. The only easing implementations in the jQuery library are the default, called swing, and one that progresses at a constant pace, called linear. More easing functions are available with the use of plug-ins, most notably the jQuery UI suite. As of jQuery version 1.4, we can set per-property easing functions within a single .animate() call. In the first version of .animate(), each property can take an array as its value: The first member of the array is the CSS property and the second member is an easing function. If a per-property easing function is not defined for a particular property, it uses the value of the .animate() method's optional easing argument. If the easing argument is not defined, the default swing function is used. We can simultaneously animate the width and height with the swing easing function and the opacity with the linear easing function: $('#clickme').click(function() { $('#book').animate({ width: ['toggle', 'swing'], height: ['toggle', 'swing'], opacity: 'toggle' }, 5000, 'linear', function() { $.print('Animation complete.'); });}); In the second version of .animate(), the options map can include the specialEasing property, which is itself a map of CSS properties and their corresponding easing functions. We can simultaneously animate the width using the linear easing function and the height using the easeOutBounce easing function. $('#clickme').click(function() { $('#book').animate({ width: 'toggle', height: 'toggle' }, { duration: 5000, specialEasing: { width: 'linear', height: 'easeOutBounce' }, complete: function() { $.print('Animation complete.'); } });}); As previously noted, a plug-in is required for the easeOutBounce function.
Read more
  • 0
  • 0
  • 1241
Visually different images

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

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

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
  • 2227
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 $15.99/month. Cancel anytime
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
  • 1125

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

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

article-image-content-management-modules-php-nuke
Packt
24 Mar 2010
10 min read
Save for later

Content Management Modules In PHP-Nuke

Packt
24 Mar 2010
10 min read
Each of these modules handles a different type of content, as is hinted at by their name, and each offers a different amount of functionality for visitors to interact with the content. We will see all of this, and also see how each module organizes the content it manages. Content The Content module, as the name suggests, simply handles content. The Content module is handy for adding general pieces of information to your site, which are not particularly time-sensitive or intended to generate discussion. The 'content' of the Content module is called a content page, and content pages may be organized into categories. Note that these categories have nothing to do with the categories created for news stories. In fact, several of the modules in this article will organize their content into 'categories', and there will be no relation between the categories of one module and the categories of another module. A content page consists of some main page text, a title, a subtitle, a header and footer, and another field, called the signature. The display of a single content page may be split easily across several web pages, with PHP-Nuke providing Next and Previous page links automatically. Content pages are ideal for holding general pieces of HTML text that need to be organized into groups or categories. Using the Content module to handle such information means that you do not have to create a new module just to display things like site policy or privacy policy documents on your site. Content pages are not searched by the Search module. There are no comment features or ratings available for Content content, and only the administrator may add pages; there is no place for user-submitted content here. In versions of PHP-Nuke prior to 7.5, there was a module called Sections, which was almost identical in functionality to Content, with the addition of an image for the categories. From PHP-Nuke 7.5, the Sections module is no longer shipped with the standard installation of PHP-Nuke, and we will not consider it any further. Like the other modules, the Content module is not activated by default, if you didn't activate the Content module before, do so now. Time For Action—Creating a Content Category We are going to use the Content module to add site 'policy' documents, in this case a site Privacy Policy. Log in as administrator. To access the Content administration area, click on the Content link in the Administration block, or click on the Content icon in the Modules menu: In the Add a New Category panel, enter the text Site Documents into the Title field. Enter the following text into the Description field: Here you will find a collection of documents about the site. Click the Add button. When the page reloads, there isn't much evidence that your category has been entered, but if you scroll down the screen to the Edit Category panel, you will find the category in the Category drop-down box: What Just Happened? We just added a content category. They are added from the Content Manager area of the administration area. The disconcerting thing is that it's difficult to tell if your category has been added successfully; there is no list of the content categories displayed in the Content Manager area. You will have to look in the drop-down box in the Edit Category panel to confirm that your category has indeed been added. Now we have a category, let's add some pages. Time For Action—Adding a Content Page In the Content Manager area of the administration area, scroll down to find the Add a New Page panel. Enter the title of the page into the Title textbox. In our case, this page will be titled Privacy Policy. Select Site Documents from the Category drop-down box. Enter the Dinosaur Portal Privacy Policy into the Sub-Title field. Next comes the Header Text. Enter the following into that field:This policy applies to all web sites and email services provided by the Dinosaur Portal. By using these web sites you consent to the general terms and conditions of usage and to the terms of this privacy policy. The Page Text field contains the body of the page. We'll enter the following: <h2>Collection of your Personal Information</h2><p>We will ask you when we need information that personally identifies you (personal information) or allows us to contact you. Generally, we request this information when you are registering before ordering products from theDinosaurPortal.com, downloading or viewing limited-access content, entering a contest, ordering email newsletters. In each circumstance we try to limit the information we request to the minimum required to deliver the service to you. We also use various standard technologies such as cookies to track user activity on our sites.</p><!--pagebreak--><h2>Use of your Personal Information</h2><p>We use your personal information for the following purposes...</p> There are two fields remaining, Footer Text and Signature. We'll enter this for the Footer Text:If you require any further assistance, please contact [email protected] and this for the Signature:the DINOSAUR PORTAL – Just because you've never seen one, doesn't mean they've all died out... Click the Send button. When the page reloads, the details of our first page are visible in the Content Manager panel, confirming its creation: Now click on the Content link in the Modules block, or go straight to http://localhost/nuke/modules.php?name=Content. You will see the list of content categories: Click on the Site Documents link, and you will see the list of content pages in this category: Clicking on the Privacy Policy link will take us to our document: Click the Next Page link to see the rest of the document: What Just Happened? We just added a content page, and then viewed the page. We assigned the content page to the Site Documents category when we created the page. It is possible to create content pages that do not belong to any category. The current list of content pages is shown in a table in the Content Manager area; we saw this screenshot at the end of step 11. When you visit the front page of the Content module, the list of categories is displayed. Only the categories that have content pages associated with them are displayed. Also, if there are any content pages not associated with a category, their titles will be listed here. Clicking on a category takes you to a list of the content pages associated with that category. This list is ordered by the date on which the pages were entered; the content page created first is displayed at the top of the list and so on. For each content page, the text entered into its Title field is displayed in this list, along with the Sub-Title in brackets. Clicking on the title of a content page will take you to display of the page itself. The following diagram shows this navigation hierarchy: Note that there is no direct link to go back from the content page to its 'parent' category. You will have to use the Back button of your browser to do this. You can get back to the list of all categories by clicking the Content link in the Modules block, but you will still need to click again on the category to display the list of content pages it contains. Returning to our privacy content page, we see that our content page has been split into two pages. This is done by inserting the text into the Page Text field, which forces PHP-Nuke to break the page at that point. The contents of the Page Text field form the body of a content page, with the Title and Sub-Title always displayed at the top. The Next Page pager is automatically provided by PHP-Nuke, and with that you can navigate through the pages of the content page. On the first page, the Header Text is displayed before the Page Text starts, and on the final page, the Footer Text is displayed at the end of the Page Text, followed by the Signature text. A copyright notice, including the site name, follows the Signature, and then there is the date the page was created, followed by the number of times the page has been read. Since we were still logged in as an administrator, at each part of this journey there are panels allowing you to edit the details of either the category or the content pages. For example, there is a panel for altering the category on the page displaying that category's content pages, in addition to a 'content page editing' panel on each page of the content itself: Any of these links can be used to change the object in question. Of course, these links are visible only to an administrator. No visitor will be able to see these links or access their functionality. Deactivating a page makes it invisible to a visitor from the list of available content pages, and the page will not be displayed even if the visitor manages to enter the URL of the content page. The administrator will be able to see a list of deactivated pages on the front page of the Content module (http://localhost/nuke/modules.php?name=Content) or in the Content Manager area of the administration area. Currently, our Privacy Policy document is at the URL http://localhost/nuke/modules.php? name=Content&pa=showpage&pid=1. To view this page, the visitor need not go through the entire Content 'hierarchy' if they are provided with a direct link. We could, for example, add a link to the Privacy Policy in the footer of our page, from the Web Site Configuration menu. The link would point to the above URL, and the reader would be taken directly to our document. The pid value of the query string is the unique identifier for this piece of content in the same way as we saw the story ID when looking at stories. This value will not change with subsequent modifications of the content page, or even moving it to another category. The Content Block The Content block is part of the standard PHP-Nuke installation, but isn't loaded. You can load this block from Blocks area of the administration area by selecting Content from the Filename dropdown, and choosing a title for the block as usually done for file blocks. Once the block is activated, it will display a list of the titles of all active content pages, with links to view each content page in full. Note that the Content block will still display the list of titles present in the content pages even if the user does not have read access to the Content module. Managing Categories Categories can be edited or deleted through the Edit Category panel in the Content Manager area. Simply select a category from the drop-down box and click the Edit button to go to the Edit Category page. Here you can edit the title and description of the category, or delete the category. Note that deleting the category does not delete the content pages associated with that category. All pages in a deleted category are preserved, but no longer belong to any category (they belong to the None category!). Special Administrator You can create a special administrator with rights to only the Content module in the Edit Admins menu of the Administration Menu. Restricting Access Access to the Content module is done on a 'whole module' basis. The visitor either sees nothing or everything. You cannot configure individual categories or content pages to be viewed by certain user groups. Points and Prizes There are no activities in the Content module that contribute any points towards a user's point score.
Read more
  • 0
  • 1
  • 2954
article-image-organizing-your-content-effectively-using-joomla-15
Packt
23 Mar 2010
8 min read
Save for later

Organizing your Content Effectively using Joomla 1.5

Packt
23 Mar 2010
8 min read
Building on the example site It's time to make room for growth. Your client has a big pile of information on ugly art that they want to present to the public. You are asked to design a site framework that makes it easy to add more content, while at the same time keeps it easy for visitors to quickly find their way through the site. Can you do that? You most certainly can! Joomla! allows you to build sites of all sorts and sizes, whether they consist of just a few pages or thousands of them. If you plan ahead and start with a sound basic structure, you'll be rewarded with a site that's easy to maintain and extend. In this article, we'll review the site you've just built and look at the different ways the content can be structured—and rearranged, if need be. Grouping content: A crash course in site organization To lay the groundwork for your site, you won't use Joomla!. The back of a napkin will do fine. Draw up a site map to lay out the primary content chunks and their relationships. View your site from a user's perspective. What do you think your visitors will primarily look for, and how can you help them find things fast and easily? Designing a site map To create a site map, first collect all information you plan on having on your website and organize it into a simple and logical format. As site maps come, this is a very basic one. For the most part, it's just one level deep. Introducing Ugly Paintings and Mission are basic web pages (articles). Activities is a section that allows the visitor to browse two other categories. Contact Us is a contact form page. This structure was good enough for a basic website, but it won't do if SRUP wants to expand their site. Time for action – create a future proof site map Let's make some room for growth. Imagine your client's planning to add an indefinite amount of new content, so there's a need for additional content containers. They have come up with the following list of subjects they want to add to their site: News items A few pages to introduce the founding members of SRUP Reviews on ugly art Facts on ugly paintings (history, little known facts, and so on) What's the best way to organize things? Let's figure out which content fits which type of container. Step 1: You'll probably want to create a separate News section. News should be a top level item, a part of the site's main menu.     Step 2: The information on the SRUP founders fits in a new section 'About SRUP'.   Step 3: Both Reviews and Facts can be categories in a new general section on 'Ugly Paintings'. The existing article 'Introducing Ugly Paintings' could be moved here (or dropped).     What just happened? You've laid a solid foundation for your site—on paper. Before you actually start using Joomla! to create sections and categories, create a structure for the content that you have in mind. Basically, no matter how big or small your website is, you'll organize it just like the example you've just seen. You'll work from top to bottom, from the primary level to the lower levels, defining content groups and their relations. Bear in mind, though, that there will certainly be more than one way to organize your information. Choose an organization that makes sense to you and your visitors, and try to keep things lean and clean. A complex structure will make it harder to maintain the content, and eventually—when building menus—it will make it harder to design clear and simple navigation paths for your visitors. Tips on choosing sections It can be useful to choose sections based on the main intentions people have when they come to the site. What are they here for? Is it to Browse Products or to Join a Workshop? Common choices for sections are: Products, Catalog, Company, Portfolio, About Us, Jobs, News, and Downloads. Try not to have more than five to seven sections. Once you have more than that, readers won't be able to hold them all in their heads at once when they have to choose which one to browse. Transferring your site map to Joomla! Let's have a closer look at our new site map and identify the Joomla! elements. This—and any—Joomla! site is likely to consist of five types of content. The following are the content types in our SRUP site map:   Obviously, the top level item will be the home page. The main content groups we can identify as sections and categories. This small site has four sections, three of which contain two categories. Each of the categories hold actual content: this is what will end up in Joomla! as articles. In this site map, there is one article that doesn't really belong in any category: the Mission Statement page. Every site will have one or two of those independent articles. In Joomla!, you can add these as uncategorized articles. Finally, there's one item that represents a very different type of content. In the site map above, a grey background indicates an item containing special functionality. In this case this is a contact form. Other examples are guest books, order forms, photo galleries. Basically, that's all there is to a Joomla! site. When you've got your site outlined like this, you won't meet any surprises while building it. You can transform any amount of content and functionality into a website, step by step.   How do you turn a site map into a website? If you've got your site blueprint laid out, you probably want to start building! Now, what should be the first step? What's the best, and fastest, way to get from that site map on the back of your napkin to a real-life Joomla! site? In this book, we'll work in this order: Organize: Create content containers.You've seen that much of the site map we just created consists of content containers: sections and categories. In this article, we'll focus on these containers. We'll create all necessary containers for our example site. Add content: Fill the containers with articles.Next, we'll add articles to the sections and categories. Articles are the "classic content" that most web pages are made of. We should also check for articles that do not belong in any category. Instead of assigning them to a section and a category, we'll add them as Uncategorized content.. Put your contents on display: Create the home page and content overview pages.Next, you'll want to guide and invite visitors. You can achieve this using two special types of pages in the site map, the home page and Joomla!'s section/category overview pages ("secondary home pages"). Make everything findable: Create menus.The top level items in your site map will probably end up as menu items on the site. To open up your site to the world you'll create and customize menus helping visitors to easily navigate your content. And what about the special content stuff? You'll notice that in the above list we've summed up all sorts of "classic content", such as articles, home pages, overview pages, and menus linking it all. We haven't yet mentioned one essential part of the site map, the special goodies. On a dynamic website you can have more than just plain old articles. You can add picture galleries, forms, product catalogues, site maps, and much, much more. It's important to identify those special pages from the beginning, but you'll add them later using Joomla!'s components and extensions. That's why we'll first concentrate on building a rock-solid foundation; later we'll add all of the desired extras. Let's start with step one now, and get our site organized! Creating content containers: Sections and categories To create a section, navigate to Content | Section Manager | New. To make a new category, you'll use the Category Manager instead. Just add a title for your new section or category and click on Save. You've created a perfectly workable section or category with the default settings (or parameters as Joomla! likes to call them). Time for action – create a new section and a category Your client was happy with the initial site structure you designed, but now their website is evolving, there's a need for more content containers. Let's add a news section first: Navigate to Content | Section Manager and click on New. In the Section: [New] screen, fill out the Title field. In this example, type News: Leave the other values unchanged; click on Save. You're taken to the Section Manager. The News section is now shown in the section list. Now, add a category to the new section. We'll call this category General News: Navigate to Content | Category Manager and click on New. In the Title field, type General News. In the Section field, select News. Click on Save. You're done!
Read more
  • 0
  • 0
  • 1526

article-image-installation-drupal-and-ubercart-2x
Packt
23 Mar 2010
4 min read
Save for later

Installation of Drupal and Ubercart 2.x

Packt
23 Mar 2010
4 min read
You don't have to be an expert programmer or a system administrator in order to complete the following process. We'll first give you a brief explanation of the underlying technologies, and then we'll continue with a step-by-step guide. At the end of this article, you'll have the online store installed on your local or remote machine and you'll be ready to make all the required customizations to the frontend and the backend, depending on your needs. Minimum requirements for Ubercart installation In order to successfully install and use your online store, your system must meet the following requirements: Operating system: Drupal works fine in almost every operating system. Actually, you can transfer your Drupal installation from one operating system to another within minutes and no customization is required at all. All you have to do is to move the files and the database without altering any configuration files. For example, you can install Drupal on your local Windows or Mac computer, do all the customizations there, and then upload it to a Linux server to go live. Web server: The web server is the software that accepts HTTP requests from browsers and delivers web pages to the users of our site. The most popular web server is Apache and we'll use it for our installation. It's secure, extensible, fast, and easy to customize. If you're not an expert in another web server, there is no reason to think of any other solution, because most of the available information and support is about Apache. Database: The purpose of the database is to store, organize, manage, and retrieve all the data of our website in a structured way. When referring to data, we mean not only the content that you put in your pages, but also every piece of information that Drupal uses for all its functions. In this book, we're using MySQL as a database. Today, it's the #1 open source database, and it's used in millions of websites and applications, from small personal web pages to enterprise systems with millions of users.The MySQL database of a basic installation contains about 50 tables and every new installed module creates one or more new tables. If you check your database after the installation of Ubercart, you'll find that there are 100 tables in your database. These tables contain data such as pages, products, images, categories, orders, payments, caching information for your pages, theming information, comments from your visitors, menus, user information, and so on. PHP: PHP is a scripting language, ideal for web development. It began as a small personal project, but soon became a very popular scripting language. Drupal is written in PHP, so it's absolutely necessary and there is no alternative to it.Some PHP extensions are needed for our installation. We'll mention them briefly here, so you can consult your hosting provider or examine your local system to check that everything is fine. The easiest way to check your PHP parameters is to use phpinfo. It's a function that returns information about the PHP environment on your server. All you have to do is to create a blank file named phpinfo.php in your server and insert the following code using a text editor: <?php phpinfo (); ?> This is a small PHP script that runs the phpinfo function and displays the results on your screen. If you browse to phpinfo.php, you'll see a page with your PHP configuration. The basic PHP requirements are: PHP memory requirements: 1 6 MBs are enough for basic sites; however, 64 MBs are recommended for more complex installations. GD2 library: GD2 is an image manipulation library for PHP. Ubercart needs this library, so if we want to put images to our products, it has to be installed. Register Globals: This is actually a depreciated PHP feature, but some hosting providers with old systems still use it. It's a security risk, so it has to be disabled for Drupal to install. Safe mode: Drupal 6 doesn't support PHP's safe mode, because it causes problems to file uploads, so it also has to be turned off.
Read more
  • 0
  • 0
  • 1655

article-image-drupal-6-performance-optimization-using-db-maintenance-and-boost-part-1
Packt
23 Mar 2010
8 min read
Save for later

Drupal 6 Performance Optimization Using DB Maintenance and Boost: Part 1

Packt
23 Mar 2010
8 min read
These are not required modules, but rather are recommended modules to add to your Drupal performance arsenal. The way this article will work is that we'll outline the purpose of each module, install and configure it, and then use it on a specific topic, for example, within your site. This will give you some practice using contributed Drupal modules and also a look at the variety of performance based modules that are available from the Drupal project community. Using the DB Maintenance module The DB Maintenance module can be used to optimize your MySQL database tables. Depending on the type of database you are running, the module allows you to use a function called OPTIMIZE TABLE, which troubleshoots and then optimizes various errors in your MySQL tables. For MyISAM tables, the OPTIMIZE TABLE will repair your database tables if they have deleted rows. For BDB and InnoDB types of tables the function will rebuild the entire table. You can use this module in tandem with phpMyAdmin to determine if you do or do not need to optimize your database tables. The benefit of this module is that it allows you to keep your database optimized and defragmented, similar to keeping your computer hard drive optimized and defragmented so that it runs faster, and you can do all this from the Drupal administrative interface. The project page where you can download the module is here: http://drupal.org/project/db_maintenance. Download the module tar.gz and extract it to your desktop. Then, upload the files through FTP, or upload and extract using a cPanel utility if your host provides this. The module should go in your /sites/all/modules directory. Once you upload and extract the module folder, enable the module on your modules admin page and save your configuration. We'll use the version that's recommended for Drupal 6.x, which is 6.x-1.1. You can try out the beta version, but you should not run this beta version on a production level website unless you've tested it sufficiently in a sandbox environment. Once you save your module configuration, you'll notice that the module adds a link to its settings and configuration page under your main Site configuration section. Go to Site configuration | DB maintenance to access the configuration admin screen for the module. The DB maintenance screen will contain a checkbox at the top allowing you to log OPTIMIZE queries. If you check this box, your watchdog log entries module will log all table optimization entries and give you detailed information on the tables that were optimized. At the time of writing this article, the 1.1 version of the DB Maintenance module contained bugs that caused glitches with the method of adding this module's queries to the recent log entries or prevented this entirely. You may also experience these glitches. The module's developers are aware of the issues because they have been posted to the issue queue at http://drupal.org/ on the module project page. Let's go ahead and check this box. You can then select the frequency with which you would like to run the optimization. The choices are daily, Run during every cron, Hourly, Bi-Hourly, Daily, Bi-Daily, Weekly, Bi-Weekly, Monthly, and Bi-Monthly. You can also click on the Optimize now link to force the optimization to occur immediately without scheduling in advance. We'll click on this link for the purpose of this demo, but in future you may want to schedule the optimization. We'll then run a cron job through the Status report, or a module such as Poormanscron, and the tables will be optimized. Next, you can select the tables in your Drupal database that you want to optimize. A nice feature of this module is that it allows you to multi select database tables, only select a few tables, or just one table. This gives you the same flexibility and functionality as your phpMyAdmin tool, but you can run everything from within your Drupal interface. It's like a phpMyAdmin lite version right in your Drupal site. This is a preferred option for those developers who may not have immediate access to a client's phpMyAdmin or a host's database management utility. Choose a selection of tables that you want to optimize, or select all the tables. For this demo I'm going to optimize all of my content type tables, so I'll select all of those. I'll also optimize my block tables: blocksblocks_rolescontent_type_blogcontent_type_bookcontent_type_forumcontent_type_pagecontent_type_photocontent_type_pollcontent_type_storycontent_type_webform Once you've selected the tables you want to optimize, click on the Optimize now link. As with any module or optimization enhancement that you make to your Drupal site, it is good practice to run a full backup of your MySQL database before performing any maintenance, including optimizing tables using the DB Maintenance module. This way you will have a full backup of your data if you run into any issues that the module could potentially create. It's better to play it safe and perform the backup first. Once you click on the Optimize now link, you should receive a message notifying you that the Database tables are optimized. This concludes our discussion and walkthrough of using the DB Maintenance module. Let's now turn to the Boost module and use it to speed up our site page and content loads. Using the Boost module We' re going to turn our attention to the Boost module in this section. Boost is a contributed module that allows you to run incredibly advanced static page caching on your Drupal site. This caching mechanism will help to increase performance and scalability on your site, especially if it gets heavy traffic and anonymous page visits, and it is on a shared hosting environment. This is usually the first contributed performance-based module to turn to for help when you host your Drupal site on a shared server. Developers running Drupal sites on shared servers and running sites that serve predominantly anonymous Drupal users will definitely want to try out this module. It's also a fun module to use from a technical standpoint because you can see the results immediately, as you configure it. The Drupal project page for the module is here: http://drupal.org/project/boost. There is a wealth of detailed information about the module on this project page, including announcements about upcoming conference presentations that focus on the Boost module, testimonials, install instructions, and links to documentation and associated modules that you may want to run alongside Boost. It is very popular and has quite a following in the Drupal development community. I definitely recommend reading about this module and all of its install and configuration instructions in detail before attempting to use it. The install paragraph suggests reading through the module README.txt file before running the install for details on how the module works. There are also detailed instructions and documentation on the module here: http://drupal.org/node/545664. Note that the one requirement to use this module is that your Drupal site must have clean URLs configured and enabled. It's a good idea to make sure you are running clean URLs on your site before you start installing and configuring Boost. Additionally, there are some recommended modules that the developers encourage you to install in tandem with the Boost module. We will install two of these modules: Global Redirect and Transliteration. The Global Redirect module runs a number of checks on your website including the following: Checks the current URL for a Drupal path alias and does a 301 redirect to the URL if it is not being used. Checks the current URL for a trailing / and removes the slash if it's present in Drupal URLs. Checks if the current URL is the same as the site's front page and redirects to the front page if it locates a match. Checks to see if you are using clean URLs. If you do have clean URLs enabled, this module ensures URLs are accessed using the clean URL method rather than an unclean method (for example, ?q=user). Checks access to the URL. If a user does not have permissions to view the URL, then no redirects are allowed. This helps to protect private URL aliases. Checks to ensure the alias matches the URL it is aliasing. So, if you have a URL alias such as /about and this directs to node/23, then a user on your site can access the page using either of those URLs. The Transliteration module removes white space and non-ASCII characters in your URLs. For example, it will try and add underscores to fill white space in a URL. Installing and enabling these two modules will help remove glitches and errors in your site's path structure. If you haven't already, we'll also take the time now to install the Poormanscron module and set up and configure automatic cron runs instead of having to continue running cron manually. We'll return to installing and configuring Poormanscron later in this article, but just keep it on your radar for now. Let's go ahead and install the Boost module and take a closer look at some of its features.
Read more
  • 0
  • 0
  • 1508
article-image-drupal-6-performance-optimization-using-db-maintenance-and-boost-part-2
Packt
23 Mar 2010
5 min read
Save for later

Drupal 6 Performance Optimization Using DB Maintenance and Boost: Part 2

Packt
23 Mar 2010
5 min read
Testing your Boost configuration Now we're going to test out our Boost configuration and make sure everything is working with our initial basic settings and the .htaccess configuration that we're running. Log out of your website in your current browser or open up another web browser so that you can browse around your site as an anonymous user. The main thing we want to check on is that our static HTML type files (our Drupal pages or nodes) are being cached and stored in the cache directory we have specified in the module configuration. If we chose to use a GZIP compression, we will want to check to make sure the ZIP files are being generated and stored. Also, run your Status report and view your log entries to check to see if any errors related to the module configuration are being thrown. You should start noticing a performance boost on your site immediately, as you browse around your site. Start clicking around and opening different nodes on your site and admire the faster performance! You should notice it. If we check the cache directory on our site, we should notice that the Boost module has started writing HTML files to our cache directory. In the directory you should now see the following folders: /cache/normal/variantcube.com/fire/node Boost has automatically created a new folder called /node where it will store the cached HTML versions of the Drupal pages it loads. For example, if we look into our /node directory, we should see a bunch of HTML files that have been cached while we've browsed anonymously on our site. You can almost see this happen in real time if you browse to a page and then immediately refresh your remote server/ site window in your FTP client (while in the /node folder). I see the following files corresponding to their Drupal nodes: 201_.html202_.html203_.html206_.html208_.html These correspond to: node/201node/202node/203node/206node/208 Also, at the root of our /fire directory, we should see any non-node pages (for example, pages created using Drupal Views module). In our case, our main Photo gallery View page has been cached: photo_gallery.html. This page corresponds to our photo_gallery View page. You can immediately see the power and flexibility of this module by inspecting your cache directory. You should notice a performance increase on all of these cached pages because the pages that are loading are now your Boost-powered HTML pages. So, multiple clicking on one Drupal node should demonstrate how quickly your pages are now loading. The module has created another folder in your /fire/cache directory called perm. The /perm folder contains your CSS and JS files as they are cached. If you look in this folder, you'll see paths to the following folders: /cache/perm/variantcube.com/fire/files/css/cache/perm/variantcube.com/fire/files/js If you look in your CSS directory, you should see cached versions of your CSS files, and if you look in your /js directory, you should see a cached version of your JavaScript. Another method of checking the module is working correctly is to view source on your pages (by viewing source in your web browser) and see if the following code is being added to your HTML output: <!-- Page cached by Boost @ 2009-10-23 13:56:03, expires @ 2009-10-23 14:56:03 --> So the actual HTML source in the web browser will tell you that you are viewing a cached version of the page rather than a dynamically generated version of the page. It also tells you when this cached page version will expire—based on our configuration, basically one hour after it's been loaded depending on our Boost module settings. Everything appears to be working fine with our initial Boost installation and configuration. Sit back and behold the power of Boost! Boost and Poormanscron Checking our Status report will show us that we're running an incorrect version of Poormanscron. Boost is optimized to work with the latest dev or 2.0 branch of Poormanscron. So let's go ahead and install the latest version so that our cron runs will work correctly with Boost. Visit the Poormanscron project page and download the 6.x.-2.0-beta1 release and extract and upload it to our /sites/all/modules directory. Then run your Status report again to check to make sure the Boost warning has disappeared. You may need to run your update.php script, as this module update will make changes to your database schema. Run update.php and then refresh your Status report. In your Status report, you should now see the Boost row state: Boost Installed correctly, should be working if properly configured. Configuring Poormanscron The updated 2.x-beta1 version of Poormanscron is the precursor module to the eventual Drupal 7 core cron functionality. In Drupal 7, the functionality of the Poormanscron module will be part of the default core processes. For this reason the beta1 version does not give you a module configuration page. It will just run cron automatically, based on a setting on your Site information page. Go here to see that setting: Site configuration | Site information. Now you have an automatically run cron setting that you can select from. We'll use the default 1 hour cron run. This is a nice preview of some of the new built-in functionality of Drupal 7 core.
Read more
  • 0
  • 0
  • 796

article-image-story-management-php-nuke
Packt
23 Mar 2010
12 min read
Save for later

Story Management with PHP-Nuke

Packt
23 Mar 2010
12 min read
The Story Story In PHP-Nuke, a story is a general-purpose, piece of content. Maybe the story is an announcement, a press release or news item, or a piece of commentary or opinion, or maybe a tutorial article. The possibilities are almost endless! With PHP-Nuke driving your site, the stories that appear on your site are not restricted to ones written by you. Users of the site—either registered or unregistered visitors, or other administrators—can write and submit stories to your site. The process of a story appearing on the site is known as publishing the story. Of course this does not mean that your site is a free-for-all—stories submitted by users and others do not necessarily get published automatically—they are submitted for moderation by an administrator, and once approved, appear on your site. In this way, the content on your site grows itself through your community, but always (if you want) under your control. PHP-Nuke keeps track of such things as the author of the story, the date when the story first appeared on the site, and the number of times the story has been read, and also allows users to vote on the quality of the story. An impressive feature of PHP-Nuke stories is that users can comment on a posted story to build an open, topical discussion within your site. You will see community-contributed stories when you visit any typical PHP-Nuke site; for example, on phpnuke.org itself, PHP-Nuke users and developers submit stories describing their latest PHP-Nuke add-on, or drawing attention to the latest theme that they've designed. The 'story' engine in PHP-Nuke is provided by the News module. The total story functionality is actually spread across a number of modules, including Submit News, Stories Archive, Search, Topics, Your Account, and Surveys. We will explore all of these in this article. The Story Publication Process The path taken by a story from writing to publication depends upon who submits the story. The super user or an administrator with permissions for the News module can post a story through the administration area of the site. In this case, the publication process is simple, and the story appears on the site immediately, or can be scheduled for publication on a particular date. Since the super user and any other administrators with the appropriate privileges are trusted (they have full power over stories, so they had better be trustworthy), there is no need to moderate or approve the text in the story, and the story is ready to go. Registered and unregistered visitors can post stories through the Submit News module. When a story is submitted through this route, the publication process is lengthier. The visitor enters the story through a form in the Submit News module. The story administrator is notified that a new story has been submitted. The story administrator checks over the story, editing, rejecting (deleting), or approving it. The administrator is also able to add notes to the story. If the story is rejected, that is the end of the process, and the story is not published. If the story is approved, it is either published to the site immediately, or can be scheduled for publication on a particular date. Once the story is published to the site, the administrator can edit it further if needed. For a visitor, once they submit their story to the site they have no more control over the story. Finding and Interacting with Stories Stories on the site can be accessed in a number of ways, from a number of different places on the site. A limited number of stories can appear on the homepage, with older stories gradually moving down the list as newer stories are posted. Stories can be retrieved by date from the Stories Archive module. The text in the story is also searchable from the Search module, so that specific stories can be located easily. Stories are organized into topics, and by browsing the list of topics from the Topics module stories can be tracked down. Stories are not the end of content, they are actually the beginning. Comments can be posted about stories, and comments can be posted to these comments creating a discussion about the story. The quality of submitted comments can be assessed by users of the site and rated accordingly. The quality or value of the story itself can be voted on by users, links to related stories can be created, and you can view a special printer-friendly version of the story for printing, or even send the story to a friend. So many features... did I mention that you can also attach a poll to the story so that readers can participate in a survey related to the content of the story? So many features... Organizing Stories When you have even a reasonable number of stories on your PHP-Nuke site (and you will have—that's why you're reading this article series!), you will be in need of some organization for this content. PHP-Nuke provides two ways of organizing story content: Topics: what it's about Categories: what type of story it is Topics Topics define what a story is about. By organizing your stories into topics, stories about similar subjects will be grouped together for easy browsing and reading, and also to make it easier for people to contribute their stories to the right place. When you're reading through a number of dinosaur-related stories, the sudden appearance of a story about cars would be rather off-putting (unless it was actually about fossil fuels or dinosaurs eating/driving cars). PHP-Nuke does indeed offer organization of stories into topics, and before we can think of adding stories, we need to set up some topics for our stories. A topic has an associated image that is displayed on the site whenever you view a story that belongs to that topic, or whenever you are browsing the list of topics. The image overleaf shows a 'teaser' of a story displayed on our site; the topic image is shown to the right-hand side of the story: The Read More… link will take the visitor to the remainder of the story. Note that this arrangement of the story text and the topic image appearing to the right of the story is just the default layout due to the basic theme. When we come to look at creating our own themes, we will see how the topic image can be made to appear elsewhere relative to the story text. By default, there is a single topic called PHP-Nuke. This has its own image, which should only be used for the PHP-Nuke topic. Categories As topics define what a story is about, categories define the 'type' of story. A category could be something like a weblog entry, a security announcement, or a press release. There is one category defined by default, Article. This category has the following properties: You cannot change this category's name or delete it. Any story of type Article automatically appears on the homepage. Users can only submit stories of type Article. Compared to topics, categories do not have particularly extensive support in PHP-Nuke. Planning the Dinosaur Portal Topics and Categories Before we move on to looking at managing topics and categories, we'll quickly discuss the kind of topics and categories that we would like for organizing our stories on the Dinosaur Portal. These are not set in stone, and after we create them, we can edit or delete them, or even add new ones. First of all, there will probably be stories about the Dinosaur Portal itself that will contain general information about the site, such as new features that have been added to it, or warnings about planned site downtime (or apologies about unplanned site downtime!). We will also have stories about dinosaurs, fossils, and dinosaur hunting; these can be the other topics on the site. What types of story will we have? In addition to the standard article, we can have new theories, technologies, or discoveries, maybe even tutorials (for example, how to identify fossils, or how to avoid being eaten when dinosaur hunting). There will also be stories about Project Chimera, but we can't reveal what that is just yet. Thus a story about a controversial new dinosaur extinction theory could be given the 'dinosaur' topic, and the 'new theory' category. This isn't an exhaustive list, but it is enough to give an idea of the topic-category split. Topic Management Before we do anything else, we'll create our topics. For each topic, we'll add the images first. After we create our topics, we'll look at how to modify them, and the consequences of deleting topics. Before we get started creating our topics, we will add the topic images. To do this, you will need to copy all the files from the topics folder in the Ch06 folder of the code download to the images/topics/ folder in the root of your PHP-Nuke installation. You should have these files: thedinosaurportal.gif, dinosaurs.gif, fossils.gif, and dinosaurhunting.gif, in addition to files called index.html, phpnuke.gif, and AllTopics.gif, which were already present in the folder. The images/topics folder is the place where PHP-Nuke will look for the topic icons. When adding image files to the images/topics folder, ensure that only alphanumeric characters or the underscore are used in your filename, or else PHP-Nuke will fail to pick up the filename when displaying the list of topic images. Note also that the total length of the filename and its extension must not exceed twenty characters, or PHP-Nuke will truncate the name when it stores a record of the filename. In this case, your topic image will not be displayed, because PHP-Nuke has not stored the correct name of the file. Also, if your image has an extension of more than three characters (such as jpeg) then it will be missed by PHP-Nuke. The AllTopics.gif file in the images/topics folder does not correspond to a single topic, but is the image used when displaying the lists of topics. This file can be replaced by an image of your own. Time For Action—Creating New Topics Log in to your site as the administrator. From the Modules Administration menu, click on the Topics icon: You will come to the Topics Manager area. Scroll down to the Add a New Topic panel The first topic we create will be Dinosaur Hunting. Enter the text dinosaurhunting in the Topic Name field, enter Dinosaur Hunting into the Topic Text field, and select the file dinosaurhunting.gif from the Topic Image drop-down box: Click on the Add Topic button. When the screen refreshes, the newly created topic will be displayed in the Current Active Topics panel: This process can be repeated for our other topics: Topic Text   Topic Name   Topic Image   Fossils   fossils fossils.gif Dinosaurs   dinosaurs dinosaurs.gif What Just Happened? The Topics Manager, reached through the Topics icon in the administration menu, is the area from where we can add, edit, or delete topics. The Topics Manager has two panels, one showing the Current Active Topics, and the other being the Add a New Topic panel. A topic requires three pieces of data: A topic name, which is a short piece of text with no spaces. This is mostly used internally by PHP-Nuke. The topic name is usually the same as the topic text, but in lower case and with no spaces. The topic text, which is the title of the topic. The topic image, the name of which is selected from the list of files in the images/topics folder. You can use the same image for more than one topic if you choose. Once you have saved a topic, clicking on its image in the Current Active Topics panel takes you to the Edit Topic area, from where you can edit or delete your topic. You may have noted that we haven't created the Dinosaur Portal topic. We'll do that now by editing the existing default topic, since we would like this to be the default topic for the portal anyway. Time For Action—Editing Topics We will edit the default topic to get the Dinosaur Portal topic: In the Topic Manager area, click on the PHP-Nuke topic icon in the list of Current Active Topics. When the page loads, enter the details as shown below: Click on the Save Changes button to complete your editing. When the page reloads, you will need to click on the Topics icon again to return to the Topic Manager area, since you will be returned to the page for editing the topic. What Just Happened? We just edited the properties of an already existing topic. To get at a topic's properties, you click on its icon in the list of Current Active Topics in the Topic Manager area. The possible topic icons are again picked from the images/topics folder and displayed in a drop-down list for you to choose. Once you are done making changes to the topic, clicking on the Save Changes button updates the topic. Note that there is no cancel button, and if you decide to make no changes here, you can click on the Topics icon in the Modules Administration menu to return to the Topic Manager area, or use the back button on your browser. Deleting a Topic It is possible to delete topics by clicking on the Delete link next to the Save Changes button. However, deleting a topic will delete all the stories that belong to that topic. Fortunately, there is a confirmation screen before the topic is deleted: Since the Delete link is positioned so close to Save Changes, it's probably good that there is this screen. There is no turning back after you click on Yes on this screen. Your topic is gone, and so are all the stories, and any comments attached to those stories. Note that the image associated with the topic is not deleted, and it still remains on the server, and can be used for another topic if wished.
Read more
  • 0
  • 0
  • 2453