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

How-To Tutorials

7018 Articles
article-image-microsoft-lightswitch-querying-multiple-entities
Packt
16 Sep 2011
4 min read
Save for later

Microsoft LightSwitch: Querying Multiple Entities

Packt
16 Sep 2011
4 min read
  (For more resources on this topic, see here.)   Microsoft LightSwitch makes it easy to query multiple entities and with queries you can fine tune the results using multiple parameters. In the following, we will be considering the Orders and the Shippers tables from the Northwind database shown next: What we would like to achieve is to fashion a query in LightSwitch which finds orders later than a specified date (OrderDate) carried by a specified shipping company (CompanyName). In the previous example, we created a single parameter and here we extend it to two parameters, OrderDate and CompanyName. The following stored procedure in SQL Server 2008 would produce the rows that satisfy the above conditions: Use NorthwindGoCreate Procedure ByDateAndShprName @ordDate datetime, @shprName nvarchar(30)asSELECT Orders.OrderID, Orders.CustomerID, Orders.EmployeeID,Orders.OrderDate, Orders.RequiredDate, Orders.ShippedDate,Orders.ShipVia, Orders.Freight, Orders.ShipName, Orders.ShipAddress, Shippers.ShipperID,Shippers.CompanyName, Shippers.PhoneFROM Orders INNER JOIN Shippers ON Orders.ShipVia = Shippers.ShipperIDwhere Orders.OrderDate > @OrdDate and Shippers.CompanyName=@shprName The stored procedure ByDateAndShprName can be executed by providing the two parameters (variables), @OrdDate and @shprName, as shown below. Exec ByDateAndShprName '5/1/1998 12:00:00','United Package' The result returned by the previous command is shown next copied from the SQL Server Management Studio (only first few columns are shown): The same result can be achieved in LightSwitch using two parameters after attaching these two tables to the LightSwitch application. As the details of creating screens and queries have been described in detail, only some details specific to the present section are described. Note that the mm-dd-yyyy appears in the result reversed yyyy-mm-dd. Create a Microsoft LightSwitch application (VB or C#). Here project Using Combo6 was created. Attach a database using SQL Server 2008 Express and bring the two tables, Orders and Shippers, to create two entities, Order and Shipper, as shown in the next screenshot: Create a query as shown in the next image: Here the query is called ByDate. Note that the CompanyName in the Shippers table is distinct. The completed query with two parameters appears as shown: Create a new screen (click on Add Screen in the query designer shown in the previous screenshot) and choose the Editable Grid Screen template. Here the screen created is named EditableGridByDate. Click on Add Data Item… and add the query NorthwindData.ByDate. The designer changes as shown next: Click on OrderDate parameter on the left-hand side navigation of the screen and drag and drop it just below the Screen Command Bar as shown. In a similar manner, drag and drop the query parameter CompanyName below the OrderDate of the earlier step. This will display as two controls for two parameters on the screen. Hold with mouse, drag and drop ByDate below the CompanyName you added in the previous step. The completed screen design should appear as shown (some fields are not shown in the display): The previous image shows two parameters. The DataGrid rows show the rows returned by the query. As is, this screen would return no data if the parameters were not specified. The OrderDate defaults to Current Date. Click on F5 to display the screen as shown: Enter the date 5/1/1998 directly. Enter United Package in the CompanyName textbox and click on the Refresh button on the previous screen. The screen is displayed as shown here: The above screen is an editable screen and you should be able to add, delete, and edit the fields and they should update the fields in the backend database when you save the data. Also note that the LightSwitch application returned 11 rows of data while the stored procedure in SQL Server returned 10 rows. This may look weird but SQL Server date time refers to PM but Microsoft LightSwitch order date is datetime data type with AM. Entering PM instead of AM returns the correct number of rows.  
Read more
  • 0
  • 0
  • 2884

article-image-sap-netweaver-mdm-scenarios-and-fundamentals
Packt
16 Sep 2011
11 min read
Save for later

SAP NetWeaver: MDM Scenarios and Fundamentals

Packt
16 Sep 2011
11 min read
  (For more resources on SAP, see here.) Master Data Management Master Data Management seeks to ensure consistent and high-quality master data in a heterogeneous system environment. It includes determination and future avoidance of duplicate and inconsistent data, thus allowing reliable global reporting and operational efficiency of business execution. Benefits of Master Data Management MDM enables an organization to link all of its critical reference or master data shared by several disparate IT systems and groups under one single version of truth. This ensures that multiple inconsistent versions of the same master data are not used in different parts of an organization's operations. By providing front-line employees with more accurate and complete data, instead of inconsistent, incomplete, and often inaccurate data, organizations can realize many added benefits. The business analytical capability of an organization can be increased by utilizing MDM to provide consistent master data across all its operational applications. By achieving this, the master data that flows into a data warehousing system would also be consistent thus allowing the organization to leverage company-wide analytics and reporting. The benefits of MDM increase as the number and diversity of organizational departments, worker roles, and computing applications expand. The implementation of MDM is especially useful when companies merge as it can minimize confusion and optimize the efficiency of the new, larger organization. In addition, companies with a global footprint having an independent region-wise ERP implementation tend to consolidate with one ERP solution for all countries. In this scenario, MDM proves to be the necessary solution by unifying master data from each ERP system into a single unified master data such as Supplier, Material master, or Customer. MDM scenarios SAP NetWeaver MDM scenarios can be easily implemented by the customers to utilize the core functionality of SAP NetWeaver in a phase-wise manner. It includes streamlined IT scenarios as well as product-content management and global data synchronization capabilities. SAP NetWeaver MDM scenarios are broadly classified into the following two categories: IT scenarios Business scenarios IT scenarios IT scenarios are based on the lines of viewing the system comprising of various IT components and the flow of data between these entities. These scenarios can be applied to specific master data objects based on a model-driven approach. The following IT scenarios are listed within SAP NetWeaver MDM: Master Data Consolidation Master Data Harmonization Central Master Data Management Master Data Consolidation Consolidation involves matching, normalizing, cleansing, and storage of master data imported from heterogeneous client systems. SAP NetWeaver MDM offers out-of-the-box models covering globally relevant attributes for the following: Material Product Retail article Supplier Customer Business partner Employee This allows customers to also model additional content on an ad-hoc basis. Organizations can cleanse and consolidate master data on materials, retail articles, suppliers, customers, and employees in an interactive manner within heterogeneous environments. The cleansed and consolidated master data can then be consumed to perform company-wide analytics, for example, global spend analysis. The key capabilities of Master Data Consolidation include: Identification of identical or similar objects spread across the local systems Cleansing of master data objects on a need basis Providing ID mapping for unified, company-wide analytics, and reporting Components required for implementing Master Data Consolidation Masterdata consolidation utilizes the following SAP NetWeaver components: Process Integration (PI) Components of MDM such as: MDM Import Manager (required for map creation and for manual data import) MDM Import Server (required for automated master data import) MDM Data Manager (required for updating master data) MDM Syndication Server (required for automated master data export) MDM Syndicator (for manual master data export) Business Intelligence (BI) (only if data needs to be consumed for consolidated analytics such as global spend analysis) In the following diagram, we illustrate Master Data Consolidation: How this scenario integrates with other scenarios? MasterData Consolidation is the prerequisite for subsequent phases lying within the incremental approach followed by SAP NetWeaver MDM. Subsequent scenarios that follow Master Data Consolidation are Master Data Harmonization and Central Master Data Management. Master Data Harmonization Harmonization involves distribution of cleansed and consolidated high-quality master data within heterogeneous system landscapes. Organizations can make use of the out-of-the-box models offered by SAP NetWeaver MDM to cover globally relevant attributes for the following: Material Product Retail article Supplier Customer Business partner Employee Additional content can also be modeled by the customers on an ad-hoc basis. This scenario includes Master Data Consolidation to ensure high-quality master data within connected business systems in an interactive manner. An added benefit in this scenario is that it allows client-specific control on master data. Organizations can utilize the consolidated and harmonized master data to perform company-wide analytics, for example, global spend analysis. The key capabilities of Master Data Harmonization include: Streamlined processes for data load, consolidation, and distribution High-quality cleansed and de-duplicated master data within a heterogeneous system landscape Components required for implementing Master Data Harmonization MasterData Harmonization utilizes the following SAP NetWeaver components: Process Integration (PI) Components of MDM such as: MDM Import Manager (required for map creation and for manual data import) MDM Import Server (required for automated master data import) MDM Data Manager (required for updating master data) MDM Syndication Server (required for automated master data export) MDM Syndicator (for manual master data export) Business Intelligence (BI) (only if data needs to be consumed for consolidated analytics such as global spend analysis) In the following diagram, we illustrate Master Data Harmonization: How this scenario integrates with other scenarios In SAP NetWeaver's incremental approach, Master Data Harmonization is preceded by the Master Data Consolidation scenario. You can also leverage the consolidation and harmonization capabilities of Business Objects Data Services. Central Master Data Management Allows centralized maintenance and storage of master data with distribution mechanisms that ensure master data is delivered to remote systems that need it. Central Master Data Management puts into place corporate master data governance policies that ensures the overall master data quality of an organization. The differentiating aspect in this scenario with reference to Master Data Harmonization is that master data is created centrally using a rich client. Information is then delivered to target remote systems in an interactive manner. The key capabilities of Central Master Data Management include: Achieving Central Data ownership resulting in dramatic quality improvements Empowers companies to set their own standards for master data management Guarantees client-specific control on master data via local completion SAP NetWeaver MDM offers out-of-the-box models covering globally relevant attributes for the following: Material Product Retail article Supplier Customer Business partner Employee This allows customers to also model additional content on an ad-hoc basis. Components required for implementing Central Master Data Management Central Master Data Management utilizes the following SAP NetWeaver components: Process Integration (PI) Components of MDM such as: MDM Data Manager (required for updating master data) MDM Syndication Server (required for automated master data export) Business Intelligence (BI) (only if data needs to be consumed for consolidated analytics such as global spend analysis) In the following diagram, we illustrate Central Master Data Management: How this scenario integrates with other scenarios In SAP NetWeaver's incremental approach, Master Data Consolidation is a prerequisite for subsequent Central Master Data Management. Business scenarios In addition to IT scenario variants, SAP NetWeaver MDM also features business scenarios. This allows flexibility in adapting SAP NetWeaver Master Data Management to whatever business process flow the customer wants. The following business scenarios are described: Rich Product-Content Management Global Data Synchronization Customer Data Integration Rich Product-Content Management This scenario targets requirements of a centralized product-content management and multi-channel catalog publishing. It allows for importing and exporting product data, centrally managing content, and publishing disparate product data across the enterprise and between trading partners. Organizations can create custom print catalogs, web catalogs, or expose an MDM product repository to a business application (for example SAP SRM) through the Open Catalog Interface (OCI). Consequently, the capabilities of MDM are extended with business processes such as product introduction, cataloging, and publishing. The key capabilities of Rich Product-Content Management are as follows: High-performing load, aggregation, and search of product data Multidimensional search Flexible taxonomy Intelligent imaging and Web/print publishing APIs for seamless, multiplatform integration Scalability (up to millions of products) Organizations can utilize the following key benefits of implementing Rich Product-Content Management: Manage or exchange product data locally and globally Manage internal content Search electronic catalogs Print customized catalogs Syndicate product catalog content through multiple channels such as OCI, Web, and Print Presents role-based interfaces through a portal Process flow This business scenario includes the following processes: The following section discusses each of these processes in detail. Importing product data Start the upload of product master data (flat files) from the specified remote systems, or product information from suppliers (in Excel or TXT format) to MDM. This process has the following prerequisites: The Repository has been set up using the MDM Console and import maps have been created using the MDM Import Manager The inbound port has been defined using the MDM Console The MDM Import Server is running The inbound source data is staged in the inbound port Once the data is delivered to a specific inbound port, it is automatically picked up within a configurable time interval and queued up for import processing. The MDM Import Server maps and matches the imported data to the repository structure as per the import maps defined in the MDM Import Manager. Re-categorizing and enriching product data In this process, you search and merge identical records interactively using the MDM Data Manager. It provides different search patterns such as tree search, keyword search, free search, and so on. After de-duplication you can check if new data has been attached to the correct category and re-categorize it, if necessary. You can also enrich additional information in the MDM Data Manager and custom validations can be applied to check master data updates. Workflows can also be configured which are triggered to support the change processes. Support for adding images as additional information for repository items is available in the MDM Image Manager. Images can be imported into the repository and image variants (example thumbnails) can be created (using the MDM Console) for each image in addition to the original copy. These images are linked to the corresponding product items in the repository using the MDM Data Manager. Providing catalog content Using this process, you can choose to syndicate the product data, apart from print publishing such as Web publishing or exposing the MDM product repository, to a business application (such as, SAP SRM) through the Open Catalog Interface (OCI). The SRM-MDM web catalog provided by SAP contains the web interfaces developed by SAP to access the MDM catalog. The implementation would require a deployment into an additional NetWeaver component called SAP Enterprise Portal. In the case of web publishing, a custom Web Catalog can be developed using the APIs. As a prerequisite, a web application should have been created and deployed on a web server with an open connection to the MDM catalog. An MDM API can be used to perform search, read, and maintain the repository content. On the other hand, if the MDM product repository needs to be exposed to a business application, we can provide the content via the OCI. Using the OCI you can search for products and add the required items to a selection list. The list is then transferred to the shopping cart of the business application and the order is completed. Enabling print publishing Using this process, you can compose and set up a printed product catalog using the MDM Publisher. In order to do this you need to first create a family table using the MDM Console to enable the initial partitioning. As catalog printing is based on category-dependent pages and different product groups in a category have different layouts, further category partitioning can be defined in the MDM Data Manager. We can partition such categories using the field or attribute values to create product families. With the help of the MDM Publisher, you can assign default settings to create a common layout structure for the publication. We can then arrange a specific layout for the given product family such as eliminate redundancies, apply printed version display name, and structure tables. In order to start the publishing activities, a collection of families or non-family based records can be defined as a publication. The publication hierarchy, thus created, is not limited to the repository's taxonomy unlike the family hierarchy. You can freely add, delete, move, and split nodes to create your own structure for the catalog. Spread editor will enable you to concentrate specifically on page layout and design such as creating layout templates for publication. The next step involves using the DTP plug-in to send the publication data from MDM to a Desktop Publishing (DTP) application such as Adobe InDesign. Using the DTP application, some specialized format changes can be done and saved with the publication in MDM. This can be re-used with the next publishing run. Finally, an index for the complete publication is generated using the MDM Indexer.
Read more
  • 0
  • 0
  • 2725

article-image-starter-guides-inkscape
Packt
13 Sep 2011
1 min read
Save for later

Inkscape Starter

Packt
13 Sep 2011
1 min read
A short, simple guide with everything you need to get started The quickest way to become productive Learn about the main features and how to use them Get to know the community and where to get help
Read more
  • 0
  • 0
  • 1349

article-image-backtrack-5-advanced-wlan-attacks
Packt
13 Sep 2011
4 min read
Save for later

BackTrack 5: Advanced WLAN Attacks

Packt
13 Sep 2011
4 min read
  (For more resources on BackTrack, see here.) Man-in-the-Middle attack MITM attacks are probably one of most potent attacks on a WLAN system. There are different configurations that can be used to conduct the attack. We will use the most common one—the attacker is connected to the Internet using a wired LAN and is creating a fake access point on his client card. This access point broadcasts an SSID similar to a local hotspot in the vicinity. A user may accidently get connected to this fake access point and may continue to believe that he is connected to the legitimate access point. The attacker can now transparently forward all the user's traffic over the Internet using the bridge he has created between the wired and wireless interfaces. In the following lab exercise, we will simulate this attack. Time for action – Man-in-the-Middle attack Follow these instructions to get started: To create the Man-in-the-Middle attack setup, we will first c create a soft access point called mitm on the hacker laptop using airbase-ng. We run the command airbase-ng --essid mitm –c 11 mon0: It is important to note that airbase-ng when run, creates an interface at0 (tap interface). Think of this as the wired-side interface of our software-based access point mitm. Let us now create a bridge on the hacker laptop, consisting of the wired (eth0) and wireless interface (at0). The succession of commands used for this are—brctl addbr mitm-bridge, brctl addif mitm-bridge eth0, brctl addif mitmbridge at0, ifconfig eth0 0.0.0.0 up, ifconfig at0 0.0.0.0 up: We can assign an IP address to this bridge and check the connectivity with the gateway. Please note that we could do the same using DHCP as well. We can assign an IP address to the bridge interface with the command—ifconfig mitm-bridge 192.168.0.199 up. We can then try pinging the gateway 192.168.0.1 to ensure we are connected to the rest of the network: Let us now turn on IP Forwarding in the kernel so that routing and packet forwarding can happen correctly using echo > 1 /proc/sys/net/ipv4/ip_forward: Now let us connect a wireless client to our access point mitm. It would automatically get an IP address over DHCP (server running on the wired-side gateway). The client machine in this case receives the IP address 192.168.0.197. We can ping the wired side gateway 192.168.0.1 to verify connectivity: We see that the host responds to the ping requests as seen: We can also verify that the client is connected by looking at the airbase-ng terminal on the hacker machine: It is interesting to note here that because all the traffic is being relayed from the wireless interface to the wired-side, we have full control over the traffic. We can verify this by starting Wireshark and start sniffing on the at0 interface: (Move the mouse over the image to enlarge it.) Let us now ping the gateway 192.168.0.1 from the client machine. We can now see the packets in Wireshark (apply a display filter for ICMP), even though the packets are not destined for us. This is the power of Man-in-the-Middle attacks! (Move the mouse over the image to enlarge it.) What just happened? We have successfully created the setup for a wireless Man-In-The-Middle attack. We did this by creating a fake access point and bridging it with our Ethernet interface. This ensured that any wireless client connecting to the fake access point would "perceive" that it is connected to the Internet via the wired LAN. Have a go hero – Man-in-the-Middle over pure wireless In the previous exercise, we bridged the wireless interface with a wired one. As we noted earlier, this is one of the possible connection architectures for an MITM. There are other combinations possible as well. An interesting one would be to have two wireless interfaces, one creates the fake access point and the other interface is connected to the authorized access point. Both these interfaces are bridged. So, when a wireless client connects to our fake access point, it gets connected to the authorized access point through the attacker machine. Please note that this configuration would require the use of two wireless cards on the attacker laptop. Check if you can conduct this attack using the in-built card on your laptop along with the external one. This should be a good challenge!
Read more
  • 0
  • 0
  • 4748

article-image-request-flow-kohana-3
Packt
12 Sep 2011
12 min read
Save for later

Request Flow in Kohana 3

Packt
12 Sep 2011
12 min read
  (For more resources on this topic, see here.) The reader can benefit from the previous article on Routing in Kohana 3.   Hierarchy is King in Kohana Kohana is layered in more ways than one. First, it has a cascading files system. This means the framework loads files for each of it’s core parts in a hierarchical order, which is explained in more detail in just a bit. Next, Kohana allows for controllers to initiate requests, making the application workflow follow a hierarchical design pattern. These features are the foundation of HMVC, which essentially is a cascading filesystem, flexible routing and request handling, the ability to execute sub-requests combined with a standard MVC pattern. The framework manages locating and loading the right file by using a core method named Kohana::find_file(). This method searches the filesystem in a predetermined order to load the proper class first. The order the method searches in is (with default paths): Application path (/application) Modules (/modules) as ordered in bootstrap.php System path (/system) Cascading filesystem As the framework loads, it creates a merged filesystem based on the order of loading described above. One of the benefits of loading files this way is the ease to overload classes that would be loaded later in the flow. We never have to, nor should we, alter a file in the system directory. We can override the default behavior of any method by overloading it in the application directory. Another great advantage is the consistency this mechanism offers. We know the exact load order for every class in any application, making it much easier to create custom code and know exactly where it needs to live. This image shows an example application being merged into the final file structure that will be used when completing a request. We can see how some classes in the application layer are overriding files in the modules. This makes it easier to visualize how modules extend and enhance the framework by building on the system core. Our application then sits on top of the system and module files, and then can build and extend the functionality of the module and system layers. Kohana also makes it easy to load third-party libraries, referred to as vendor libraries, into the filesystem. Each of the three layers has five basic folders into which Kohana looks: Classes (/classes) contain all autoloaded class files. This directory includes our Controller, Models, and their supporting classes. Autoloading allows us to use classes without having to include them manually. Any classes inside this directory will automatically be searched and loaded when they are used. Config files (/config) are files containing arrays that can be parsed and loaded using the core method Kohana::config(). Some config files are required to configure and properly load modules, while others may be created by us to make our application easier to maintain, or to keep vendor libraries tidy by moving config data to the framework. Config files are the only files in the cascading filesystem that are not overloaded; all config files are merged with their parent files. Internationalization files (/i18n) make it much easier to create language files that work with our applications to deliver the proper content that best suits the language of our users. Messages (/messages) are much like configuration files, in that they are arrays that are loaded by a core Kohana method. Kohana:: message() parses and returns the messages for a specific array. This functionality is very useful when creating forms and actions for our applications. View files (/views) are the presentation layer of our applications, where view files and template files live.   Request flow in Kohana Now that we have seen how the framework merges files to create a set of files to load on request, it is a good place to see the flow of the files in Kohana. Remember that controllers can invoke requests, making a bit of a loop between controllers, models, and views, but the frameworks always runs in the same order, beginning with the index.php file. The index.php file sets the path to the application, modules, and system directories and saves them to as constants that are then defined for global use. These constants are APPPATH, MODPATH, and SYSPATH, and they hold the paths for the application, modules, and system paths respectively. After the error-reporting levels are set, Kohana looks to see if the install.php file exists. If the install file is not found, Kohana takes the next step in loading the framework by loading the core Kohana class. Next, the index file looks for the application’s Kohana class, first in the application directory, then in the system path. This is the first example of Kohana looking for our files before it looks for its own. The last thing the index file does is bootstrap our application, by requiring the bootstrap.php file and loading it. You probably remember having to configure the bootstrap file when we installed Kohana. This is the file in which we set our base URL and modules; however, it is a bit more important than just basic installation and configuration. The boostrap begins by setting a some basic environment settings, like the default timezone and locale. Next, it enables the autoloader, and defines the application environment. This tells the framework whether our application is in a production or development environment, allowing it to make decisions based on its environment-specific settings. Next, the default options are set and Kohana is initialized, with the Kohana::init() method being called. After Kohana’s initialization, it sets up logging, configuration reading, and then modules. Modules are loaded defined using an array, with the module name as the key, and the path to the module as the value. The modules load order is listed in this array, and are all subject to the same rules and conventions as core and application code. Each module is added to the cascading file system as described above, allowing files to override any that may be added later when the system files are merged. Modules can contain their own init files, named init.php, that act similar to the application bootstrap, adding routes specific to the modules for our application to use. The last thing the bootstrap does in a normal request flow is to set the routes for the application. Kohana ships with a default route that loads the index action in the welcome controller. The Route object’s set method accepts an array that defines the name, URI, and defaults for the parameters set for the URI. By setting default controllers, actions, and params, we can have dynamic URLs that have default values if none are passed. If no controller or action is passed in the URI on a vanilla Kohana install, the welcome controller will be loaded, and the index action invoked as outlined in the array passed to the Route::set() method in the boostrap. Once all the application routes are set via the Route::set() method and init.php files residing in modules, Request::instance() is invoked, setting the request loop into action. As the Request object processes the request, it looks through routes until it finds the right controller to load. The request object then instantiates the controller, passing the request to the controller for it to use. The Controller::before() method is then called, which acts much like a constructor. By being called first, the before() method allows any logic that need to be performed before a controller action is run to execute. Once the before method is complete, the object continues to load the requested functions, just like when a constructor is complete. The controller action, a method in the controller class, is then called, and once complete, it returns the request response. The action method is where the business logic for the request will reside. Once the action is complete, the Controller::after() method is called, much like the destructor of a standard PHP class. Because of the hierarchical structure of Kohana, any controller can initiate a new request, making it possible for other controllers to be loaded, invoking more controller actions, which generate request responses. Once all the requests have been fulfilled, Kohana renders the final request response. The Kohana request flow can seem like it is long and complex, but it can also be looked at as very clean and organized. By using a front controller design pattern, all requests are handled by just one file: index.php. Each and every request that is handled by our applications will begin with this one file. From there the application is bootstrapped, and then the controller designed to handle the specific request is found, executed, and displayed. Although, as we have seen, there is more that is happening, for most of our applications, this simple way of looking at the request flow will make it easy to create powerful web applications using Kohana.   Using the Request object The request flow in Kohana is interesting, and it is easy to see how it can be powerful on a high level, but the best way to understand HMVC and routing in Kohana is to look at some actual code, and see what the resulting outcome is for real world scenarios. Kohana’s Request object determines the proper controller to invoke, and acts as a wrapper for the response. If we look at the Template Controller that we are extending in our Application Controller for the case study site, we can follow the inheritance path back to Kohana’s template controller, and see the request response. One of the best ways to understand what is happening inside the framework is to drill down through the filesystem and look at the actual code. One of the great advantages of open sources frameworks is the ability to read the code that makes the library run. Opening the welcome controller located at application/classes/controller/welcome.php, we see the following class declaration: class Controller_Welcome extends Controller_Application The first thing we see in the base controller class is that it extends another Controller, and then we see the declaration of an object property named $request. This variable holds the Kohana_Request object, the class that created the original controller call. In the constructor, we can see that the Kohana_Request object is being type-hinted for the argument, and it is setting the $request object property on instantiation. All that is left in the base Controller class is the before() and after() methods with no functionality. We can then open our Application Controller, located at application/classes/controller/application.php. The class declaration in this controller looks like this: abstract class Controller_Application extends Controller_Template In this file, we can see the before() method loading the template view into the template variable, and in the after() method, we see the Request obeject ($this->request) having the response body set, ready to be rendered. This class, in turn, extends the Template Controller. The Template Controller is part of the Kohana system. Since we have not created any controllers in our application or modules the original template controller that ships with Kohana is being loaded. It is located at system/classes/controller/template.php. The class declaration in this controller looks like: abstract class Controller_Template extends Kohana_Controller_Template Here things take a twist, and for the first time, we are going to have to leave the /classes/controller/ structure to find an inherited class. The Kohana_Controller_Template class lives in system/classes/kohana/controller/template.php. The class is fairly short and simple, and it has this class declaration: abstract class Kohana_Controller_Template extends Controller This controller (system/classes/controller.php) is the base controller that all requested controller classes must extend. Examining this class will let us see the Request class enter the Controller loop and the template view get sent to the Request object as the response. Walking through the Welcome Controller’s heritage is a great way of seeing how the Request object loads a controller, and how the parent classes all contribute to the request flow in Kohana. It may seem like pointless complexity at first, however, the benefits of transparent extension are very powerful, and Kohana makes the mechanisms work all behind the scenes. But one question still remains: How is the request object aware of the controllers and routes? Athough dissecting Kohana’s Request Class could be a article unto itself, a lot can be answered by looking at the contstructor in the system/classes/kohana/request.php file. The constructor is given the URI, and then stores object properties that the object will later use to execute the request. The Request class does have a couple of key methods that can be very helpful. The first is Request::controller(), which returns the name of the controller for the request, and the other is Request::action(), which similarly returns the name of the action for the request. After loading the routes, the method then iterates through the routes, determines any matches for the URI, and begins setting the controller, action, and parameters for the route. If there are not matches for optional segments of the route, the defaults are stored in the object properties. When the Request object’s execute() method is called, the request is processed, and the response is returned. This happens by first processing the before() method, then the controller action being requested, then the after() method for the class, followed by any other requests until all have completed. The topic of initiating a request from within a controller has arisen a few times, and is the best way to illustrate the Hierarchical aspect of HMVC. Let’s take a look at this process by creating a controller method that initiates a new request, and see how it completes.  
Read more
  • 0
  • 0
  • 4149

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

Routing in Kohana 3

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

Storing Passwords Using FreeRADIUS Authentication

Packt
08 Sep 2011
6 min read
In the previous article we covered the Authentication Methods used while working with FreeRADIUS. This article by Dirk van der Walt, author of FreeRADIUS Beginner's Guide, teaches methods for storing passwords and how they work. Passwords do not need to be stored in clear text and it is better to store them in a hashed format. There are, however, limitations to the kind of authentication protocols that can be used when the passwords are stored as a hash which we will explore in this article. (For more resources on this subject, see here.) Storing passwords Username and password combinations have to be stored somewhere. The following list mentions some of the popular places: Text files: You should be familiar with this method by now. SQL databases: FreeRADIUS includes modules to interact with SQL databases. MySQL is very popular and widely used with FreeRADIUS. Directories: Microsoft's Active Directory or Novell's e-Directory are typical enterprise-size directories. OpenLDAP is a popular open source alternative. The users file and the SQL database that can be used by FreeRADIUS store the username and password as AVPs. When the value of this AVP is in clear text, it can be dangerous if the wrong person gets hold of it. Let's see how this risk can be minimized. Hash formats To reduce this risk, we can store the passwords in a hashed format. A hashed format of a password is like a digital fingerprint of that password's text value. There are many different ways to calculate this hash, for example MD5 or SHA1. The end result of a hash should be a one-way fixed-length encrypted string that uniquely represents the password. It should be impossible to retrieve the original password out of the hash. To make the hash even more secure and more immune to dictionary attacks we can add a salt to the function that generates the hash. A salt is randomly generated bits to be used in combination with the password as input to the one way hash function. With FreeRADIUS we store the salt along with the hash. It is therefore essential to have a random salt with each hash to make a rainbow table attack difficult. The pap module, which is used for PAP authentication, can use passwords stored in the following hash formats to authenticate users: Both MD5 and SSH1 hash functions can be used with a salt to make it more secure. Time for action – hashing our password We will replace the Cleartext-Password AVP in the users file with a more secure hashed password AVP in this section. There seems to be a general confusion on how the hashed password should be created and presented. We will help you clarify this issue in order to produce working hashes for each format. A valuable URL to assist us with the hashes is the OpenLDAP FAQ: http://www.openldap.org/faq/data/cache/419.html There are a few sections that show how to create different types of password hashes. We can adapt this for our own use in FreeRADIUS. Crypt-Password Crypt password hashes have their origins in Unix computing. Stronger hashing methods are preferred over crypt, although crypt is still widely used. The following Perl one-liner will produce a crypt password for passme with the salt value of 'salt': #> perl -e 'print(crypt("passme","salt")."n");' Use this output and change Alice's check entry in the users file from: "alice" Cleartext-Password := "passme" to: "alice" Crypt-Password := "sa85/iGj2UWlA" Restart the FreeRADIUS server in debug mode. Run the authentication request against it again. Ensure that pap now uses the crypt password by looking for the following line in the FreeRADIUS debug feedback: [pap] Using CRYPT password "sa85/iGj2UWlA" MD5-Password The MD5 hash is often used to check the integrity of a file. When downloading a Linux ISO image you are also typically supplied with the MD5 sum of the file. You can then confirm the integrity of the file by using the md5sum command. We can also generate an MD5 hash from a password. We will use Perl to generate and encode the MD5 hash in the correct format that is required by the pap module. The creation of this password hash involves external Perl modules, which you may have to install first before the script can be used. The following steps will show you how: Create a Perl script with the following contents; we'll name it 4088_04_md5.pl: #! /usr/bin/perl -wuse strict;use Digest::MD5;use MIME::Base64;unless($ARGV[0]){ print "Please supply a password to create a MD5 hash from.n"; exit;}my $ctx = Digest::MD5->new;$ctx->add($ARGV[0]);print encode_base64($ctx->digest,'')."n"; Make the 4088_04_md5.pl file executable: chmod 755 4088_04_md5.pl Get the MD5 password for passme: ./4088_04_md5.pl passme Use this output and update Alice's entry in the user's file to: "alice" MD5-Password := "ugGBYPwm4MwukpuOBx8FLQ==" Restart the FreeRADIUS server in debug mode. Run the authentication request against it again. Ensure that pap now uses the MD5 password by looking for the following line in the FreeRADIUS debug feedback: [pap] Using MD5 encryption. SMD5-Password This is an MD5 password with salt. The creation of this password hash involves external Perl modules, which you may have to install first before the script can be used. Create a Perl script with the following contents; we'll name it 4088_04_smd5.pl: #! /usr/bin/perl -wuse strict;use Digest::MD5;use MIME::Base64;unless(($ARGV[0])&&($ARGV[1])){ print "Please supply a password and salt to create a salted MD5 hash from.n"; exit;}my $ctx = Digest::MD5->new;$ctx->add($ARGV[0]);my $salt = $ARGV[1];$ctx->add($salt);print encode_base64($ctx->digest . $salt ,'')."n"; Make the 4088_04_smd5.pl file executable: chmod 755 4088_04_smd5.pl Get the SMD5 value for passme using a salt value of 'salt': ./4088_04_smd5.pl passme salt Remember that you should use a random value for the salt. We only used salt here for the demonstration. Use this output and update Alice's entry in the user's file to: "alice" SMD5-Password := "Vr6uPTrGykq4yKig67v5kHNhbHQ=" Restart the FreeRADIUS server in debug mode. Run the authentication request against it again. Ensure that pap now uses the SMD5 password by looking for the following line in the FreeRADIUS debug feedback. [pap] Using SMD5 encryption.
Read more
  • 0
  • 0
  • 38979

article-image-freeradius-working-authentication-methods
Packt
08 Sep 2011
6 min read
Save for later

FreeRADIUS: Working with Authentication Methods

Packt
08 Sep 2011
6 min read
Authentication is a process where we establish if someone is who he or she claims to be. The most common way is by a unique username and password. This article by Dirk van der Walt, author of FreeRADIUS Beginner's Guide, teaches authentication methods and how they work. Extensible Authentication Protocol (EAP) is covered later in a dedicated article. In this article we shall: Discuss PAP, CHAP, and MS-CHAP authentication protocols See when and how authentication is done in FreeRADIUS Explore ways to store passwords Look at other authentication methods (For more resources on this subject, see here.) Authentication protocols This section will give you background on three common authentication protocols. These protocols involve the supply of a username and password. The radtest program uses the Password Authentication Protocol (PAP) by default when testing authentication. PAP is not the only authentication protocol but probably the most generic and widely used. Authentication protocols you should know about are PAP, CHAP, and MS-CHAP. Each of these protocols involves a username and password. The next article on Extensible Authentication Protocol (EAP) protocol will introduce us to more authentication protocols. An authentication protocol is typically used on the data link layer that connects the client with the NAS. The network layer will only be established after the authentication is successful. The NAS acts as a broker to forward the requests from the user to the RADIUS server. The data link layer and network layer are layers inside the Open Systems Interconnect model (OSI model). The discussion of this model is almost guaranteed to be found in any book on networking:http://en.wikipedia.org/wiki/OSI_model PAP PAP was one of the first protocols used to facilitate the supply of a username and password when making point-to-point connections. With PAP the NAS takes the PAP ID and password and sends them in an Access-Request packet as the User-Name and User-Password. PAP is simpler compared to CHAP and MS-CHAP because the NAS simply hands the RADIUS server a username and password, which are then checked. This username and password come directly from the user through the NAS to the server in a single action. Although PAP transmits passwords in clear text, using it should not always be frowned upon. This password is only in clear text between the user and the NAS. The user's password will be encrypted when the NAS forwards the request to the RADIUS server. If PAP is used inside a secure tunnel it is as secure as the tunnel. This is similar to when your credit card details are tunnelled inside an HTTPS connection and delivered to a secure web server. HTTPS stands for Hypertext Transfer Protocol Secure and is a web standard that uses Secure Socket Layer/Transport Layer Security (SSL/TLS) to create a secure channel over an insecure network. Once this secure channel is established, we can transfer sensitive data, like credit card details, through it. HTTPS is used daily to secure many millions of transactions over the Internet. See the following schematic of a typical captive portal configuration. The following table shows the RADIUS AVPs involved in a PAP request: As you can see the value of User-Password is encrypted between the NAS and the RADIUS server. Transporting the user's password from the user to the NAS may be a security risk if it can be captured by a third party. CHAP CHAP stands for Challenge-Handshake Authentication Protocol and was designed as an improvement to PAP. It prevents you from transmitting a cleartext password. CHAP was created in the days when dial-up modems were popular and the concern about PAP's cleartext passwords was high. After a link is established to the NAS, the NAS generates a random challenge and sends it to the user. The user then responds to this challenge by returning a one-way hash calculated on an identifier (sent along with the challenge), the challenge, and the user's password. The user's response is then used by the NAS to create an Access-Request packet, which is sent to the RADIUS server. Depending on the reply from the RADIUS server, the NAS will return CHAP Success or CHAP Failure to the user. The NAS can also request at random intervals that the authentication process be repeated by sending a new challenge to the user. This is another reason why it is considered more secure than PAP. One major drawback of CHAP is that although the password is transmitted encrypted, the password source has to be in clear text for FreeRADIUS to perform password verification. The FreeRADIUS FAQ discuss the dangers of transmitting a cleartext password compared to storing all the passwords in clear text on the server. The following table shows the RADIUS AVPs involved in a CHAP request: MS-CHAP MS-CHAP is a challenge-handshake authentication protocol created by Microsoft. There are two versions, MS-CHAP version 1 and MS-CHAP version 2. The challenge sent by the NAS is identical in format to the standard CHAP challenge packet. This includes an identifier and arbitrary challenge. The response from the user is also identical in format to the standard CHAP response packet. The only difference is the format of the Value field. The Value field is sub-formatted to contain MS-CHAP-specific fields. One of the fields (NT-Response) contains the username and password in a very specific encrypted format. The reply from the user will be used by the NAS to create an Access-Request packet, which is sent to the RADIUS server. Depending on the reply from the RADIUS server, the NAS will return Success Packet or Failure Packet to the user. The RADIUS server is not involved with the sending out of the challenge. If you sniff the RADIUS traffic between an NAS and a RADIUS server you can confirm that there is only an Access-Request followed by an Access-Accept or Access-Reject. The sending out of a challenge to the user and receiving a response from her or him is between the NAS and the user. MS-CHAP also has some enhancements that are not part of CHAP, like the user's ability to change his or her password or inclusion of more descriptive error messages. The protocol is tightly integrated with the LAN Manager and NT Password hashes. FreeRADIUS will convert a user's cleartext password to an LM-Password and an NT-Password in order to determine if the password hash that came out of the MS-CHAP request is correct. Although there are known weaknesses with MS-CHAP, it remains widely used and very popular. Never say never. If your current requirement for the RADIUS deployment does not include the use of MS-CHAP, rather cater for the possibility that one day you may use it. The most popular EAP protocol makes use of MS-CHAP. EAP is crucial in Wi-Fi authentication. Because MS-CHAP is vendor specific, VSAs instead of AVPs are part of the Access-Request between the NAS and RADIUS server. This is used together with the User-Name AVP. Now that we know more about the authentication protocols, let's see how FreeRADIUS handles them.
Read more
  • 0
  • 0
  • 20016

article-image-getting-started-freeradius
Packt
07 Sep 2011
6 min read
Save for later

Getting Started with FreeRADIUS

Packt
07 Sep 2011
6 min read
After FreeRADIUS has been installed it needs to be configured for our requirements. This article by Dirk van der Walt, author of FreeRADIUS Beginner's Guide, will help you to get familiar with FreeRADIUS. It assumes that you already know the basics of the RADIUS protocol. In this article we shall: Perform a basic configuration of FreeRADIUS and test it Discover ways of getting help Learn the recommended way to configure and test FreeRADIUS See how everything fits together with FreeRADIUS (For more resources on this subject, see here.) Before you startThis article assumes that you have a clean installation of FreeRADIUS. You will need root access to edit FreeRADIUS configuration files for the basic configuration and testing. A simple setup We start this article by creating a simple setup of FreeRADIUS with the following: The localhost defined as an NAS device (RADIUS client) Alice defined as a test user After we have defined the client and the test user, we will use the radtest program to fill the role of a RADIUS client and test the authentication of Alice. Time for action – configuring FreeRADIUS FreeRADIUS is set up by modifying configuration files. The location of these files depends on how FreeRADIUS was installed: If you have installed the standard FreeRADIUS packages that are provided with the distribution, it will be under /etc/raddb on CentOS and SLES. On Ubuntu it will be under /etc/freeradius. If you have built and installed FreeRADIUS from source using the distribution's package management system it will also be under /etc/raddb on CentOS and SLEs. On Ubuntu it will be under /etc/freeradius. If you have compiled and installed FreeRADIUS using configure, make, make install it will be under /usr/local/etc/raddb. The following instructions assume that the FreeRADIUS configuration directory is your current working directory: Ensure that you are root in order to be able to edit the configuration files. FreeRADIUS includes a default client called localhost. This client can be used by RADIUS client programs on the localhost to help with troubleshooting and testing. Confirm that the following entry exists in the clients.conf file: client localhost { ipaddr = 127.0.0.1 secret = testing123 require_message_authenticator = no nastype = other} Define Alice as a FreeRADIUS test user. Add the following lines at the top of the users file. Make sure the second and third lines are indented by a single tab character: "alice" Cleartext-Password := "passme" Framed-IP-Address = 192.168.1.65, Reply-Message = "Hello, %{User-Name}" Start the FreeRADIUS server in debug mode. Make sure that there is no other instance running by shutting it down through the startup script. We assume Ubuntu in this case. $> sudo su#> /etc/init.d/freeradius stop#> freeradius -X You can also use the more brutal method of kill -9 $(pidof freeradius) or killall freeradius on Ubuntu and kill -9 $(pidof radius) or killall radiusd on CentOS and SLES if the startup script does not stop FreeRADIUS. Ensure FreeRADIUS has started correctly by confirming that the last line on your screen says the following: Ready to process requests. If this did not happen, read through the output of the FreeRADIUS server started in debug mode to see what problem was identified and a possible location thereof. Authenticate Alice using the following command: $> radtest alice passme 127.0.0.1 100 testing123 The debug output of FreeRADIUS will show how the Access-Request packet arrives and how the FreeRADIUS server responds to this request. Radtest will also show the response of the FreeRADIUS server: Sending Access-Request of id 17 to 127.0.0.1 port 1812 User-Name = "alice" User-Password = "passme" NAS-IP-Address = 127.0.1.1 NAS-Port = 100rad_recv: Access-Accept packet from host 127.0.0.1 port 1812,id=147, length=40 Framed-IP-Address = 192.168.1.65 Reply-Message = "Hello, alice" What just happened? We have created a test user on the FreeRADIUS server. We have also used the radtest command as a client to the FreeRADIUS server to test authentication. Let's elaborate on some interesting and important points. Configuring FreeRADIUS Configuration of the FreeRADIUS server is logically divided into different files. These files are modified to configure a certain function, component, or module of FreeRADIUS. There is, however, a main configuration file that sources the various sub-files. This file is called radiusd.conf. The default configuration is suitable for most installations. Very few changes are required to make FreeRADIUS useful in your environment. Clients Although there are many files inside the FreeRADIUS server configuration directory, only a few require further changes. The clients.conf file is used to define clients to the FreeRADIUS server. Before an NAS can use the FreeRADIUS server it has to be defined as a client on the FreeRADIUS server. Let's look at some points about client definitions. Sections A client is defined by a client section. FreeRADIUS uses sections to group and define various things. A section starts with a keyword indicating the section name. This is followed by enclosing brackets. Inside the enclosing brackets are various settings specific to that section. Sections can also be nested. Sometimes the section's keyword is followed by a single word to differentiate between sections of the same type. This allows us to have different client entries in clients.conf. Each client has a short name to distinguish it from the others. The clients.conf file is not the only file where client sections can be defined although it is the usual and most logical place. The following image shows nested client definitions inside a server section: (Move the mouse over the image to enlarge.) Client identification The FreeRADIUS server identifies a client by its IP Address. If an unknown client sends a request to the server, the request will be silently ignored. Shared secret The client and server also require to have a shared secret, which will be used to encrypt and decrypt certain AVPs. The value of the User-Password AVP is encrypted using this shared secret. When the shared secret differs between the client and server, FreeRADIUS server will detect it and warn you when running in debug mode: Failed to authenticate the user. WARNING: Unprintable characters in the password. Double-check the shared secret on the server and the NAS! Message-Authenticator When defining a client you can enforce the presence of the Message-Authenticator AVP in all the requests. Since we will be using the radtest program, which does not include it, we disable it for localhost by setting require_message_authenticator to no. Nastype The nastype is set to other. The value of nastype will determine how the checkrad Perl script will behave. Checkrad is used to determine if a user is already using resources on an NAS. Since localhost does not have this function or need we will define it as other. Common errors If the server is down or the packets from radtest cannot reach the server because of a firewall between them, radtest will try three times and then give up with the following message: radclient: no response from server for ID 133 socket 3 If you run radtest as a normal user it may complain about not having access to the FreeRADIUS dictionary file. This is required for normal operations. The way to solve this is either to change the permissions on the reported file or to run radtest as root.
Read more
  • 0
  • 0
  • 11984

Packt
07 Sep 2011
8 min read
Save for later

Unity 3: Building a Rocket Launcher

Packt
07 Sep 2011
8 min read
  (For more resources on this subject, see here.) Mission briefing We will create a character that carries a rocket launcher and is able to shoot it as well as creating the camera view looking back from the character shoulder (third-person camera view). Then, we will add the character controller script to control our character, and the player will have to hold the Aim button to be able to shoot the rocket, similar to the Resident Evil 4 or 5 styles. What does it do? We will start with applying the built-in CharacterMotor, FPSInputController, and MouseLook scripts from the built-in FPS character controller. Then, we will add the character model and start creating a new script by adapting part of the code in the FPSInputController script. Then, we will be able to control the animation for our character to shoot, walk, run, and remain idle. Next, we will create a rocket prefab and the rocket launcher script to fire our rocket. We will use and adapt the built-in explosion and fire trial particle in Unity, and attach them to our rocket prefab. We will also create a new smoke particle, which will appear from the barrel of the rocket launcher when the player clicks Shoot. Then, we will create the scope target for aiming. We will also create the launcher and smoke GameObject, which are the start position of the rocket and the smoke particle. Finally, we will add the rocket GUITexture object and script to track the number of bullets we have let, at player each shot. We will also add the Reload but on to refill our bullet when the character is out of the bullet. Why Is It Awesome? When we complete this article, we will be able to create the third-person shooter style camera view and controller, which is very popular in many games today. We will also be able to create a rocket launcher weapon and particle by using the prefab technique. Finally, we will be able to create an outline text with the GUITexture object for tracking the number of bullets left. Your Hotshot Objectives In this article, we will use a third-person controller script to control our character and combine it with the built-in first-person controller prefab style to create our third-person shooter script to fire a rocket from the rocket launcher. Here is what we will do: Setting up the character with the first-person controller prefab Creating the New3PSController and MouseLook_JS scripts Create a rocket launcher and a scope target Create the rockets and particles Create the rocket bullet UI Mission Checklist First, we need the chapter 5 project package, which will include the character model with a gun from the Unity FPS tutorial website, and all the necessary assets for this article. So, let's browse to http://www.packtpub.com/support?nid=8267 and download Chapter5.zip package. Unzip it and we will see Chapter5.unitypackage, and we are ready. Setting up the character with the first-person controller prefab In the first section of this article, we will make all the necessary settings before we create our character on the scene. We will set up the imported assets and make sure that all the assets are imported in the proper way and are ready to use by using the Import Package in the Project view inside Unity. Then, we will set the light, level, camera, and put our character in the scene with the first-person controller prefab. We will import the Chapter5.unitypackage package to Unity, which contains the Chapter5 folder. Inside this folder, we will see five subfolders, which are Fonts, Level, Robot Artwork, Rocket, and UI. The Fonts folder will contain the Font file, which will be used by the GUI. The Level folder will contain the simple level prefab, its textures, and materials. Robot Artwork is the folder that includes the character FBX model, materials, and textures, which can be taken from the Unity FPS tutorial. The Rocket folder contains the rocket and rocket launcher FBX models, materials, and textures, which can be taken from the Unity FPS tutorial. Finally, the UI folder includes all the images, which we will use to create the GUI. Prepare for Lift Off In this section, we will begin by importing the chapter 5 Unity package, checking all the assets, setting up the level, and adding the character to the scene with the FPS controller script. First, let's create a new project and name it RocketLauncher, and this time we will include the built-in Character Controller package and Particles package by checking the Character Controller.unityPackage and Particles.unityPackage checkboxes in the Project Wizard. Then, we will click on the Create Project but on, as shown in the following screenshot: Next, import the assets package by going to Assets | Import Package | Custom Package.... Choose Chapter5.unityPackage, which we just downloaded, and then click on the Import but on in the pop-up window link, as shown in the following screenshot: Wait until it's done, and you will see the Chapter5 folder in the Window view. Make sure that we have all have folders, which are Fonts, Level, Robot Artwork, Rocket, and UI, inside this folder. Now, let's create something. Engage Thrusters In this section, we will set up the scene, camera view, and place our character in the scene: First, let's begin with creating the directional light by going to GameObject | Create Other | Directional Light, and go to its Inspector view to set the rotation X to 30 and the position (X: 0, Y: 0, Z: 0). Then, add the level to our scene by clicking on the Chapter5 folder in the Project view. In the Level folder, you will see the Level Prefab; drag it to the Hierarchy view and you will see the level in our scene. Next, remove the Main Camera from the Hierarchy view because we will use the camera from the built-in First Person Controller prefab. So, right-click on the Main Camera on the Hierarchy view and choose Delete to remove it. Then, add the built-in First Person Controller prefab to the Hierarchy view by going to the Standard Assets folder. Under the Character Controllers folder, you will see the First Person Controller prefab; drag it to the Hierarchy view. In the Hierarchy view, click on the arrow in the front of the First Person Controller object to see its hierarchy, similar to the one shown in the following screenshot: Then, we go back to the Project view. In the Chapter5 folder inside Robot Artwork, drag the robot.fbx object (as shown in the following screenshot) on top of the Main Camera inside the First Person Controller object in the Hierarchy. This will cause the editor to show the window that tells us this action will break the prefab, so we just click on the Continue but on to break it. It means that this game object will not be linked to the original prefab. Next, remove the Graphics object above the Main Camera. Right-click on it and choose Delete. Now we will see something similar to the following screenshot: We have put the robot object as a child of the camera because we want our character to rotate with the camera. This will make our character always appear in front of the camera view, which is similar to the third-person view. This setup is different from the original FPS prefab because in the first person view, we will not see the character in the camera view, so there is no point in calculating the rotation of the character Now, click on the First Person Controller object in the Hierarchy view to bring up the Inspector view, and set up the Transform Position of X: 0, Y: 1.16, Z: 0|. Then, go to the Character Controller, and set all values as follows: Character Controller (Script) Height: 2.25 Center X: -0.8, Y: 0.75, Z: 1.4 Move down one step by clicking on Main Camera in the Hierarchy view and go to its Inspector view to set the value of Transform and Mouse Look as follows: Transform Position X: 0, Y: 1.6, Z: 0 Mouse Look (Script) Sensitivity Y: 5 Minimum Y: -15 We will leave all the other parameters as default and use the default values. Then, we will go down one more step to set the Transform of the robot by clicking on it to bring up its Inspector view, and set the following: Now, we are done with this step. In the next step, we will adjust and add some code to control the animation and movement of our character the FPSInputController script. If the user presses it, we want the character to stop moving and play the shooting animation to prepare the character to be able to fire. We also set the maximum and minimum of the camera rotation on the Y-axis, which limits the camera to rotate up and down only. Then, we set the motor.inputMoveDirection to Vector3. zero because we don't want our character to move while he/she is executing the shooting action. On the other hand, if the user doesn't press E, we check for the user input. If the user presses the right arrow or let arrow, we change the speed to run speed; if not we set it to walk speed. Then, we applied the movement speed to motor. movement.maxForwardSpeed, motor.movement.maxSidewaysSpeed, and motor.movement.maxBackwardsSpeed.
Read more
  • 0
  • 0
  • 14183
article-image-how-add-static-material-course-moodle
Packt
06 Sep 2011
7 min read
Save for later

How to Add Static Material to a Course in Moodle

Packt
06 Sep 2011
7 min read
  (For more resources on Moodle, see here.)   Kinds of static course material that can be added Static course material is added from the Add a resource drop-down menu. Using this menu, you can create: Web pages Links to anything on the Web Files A label that displays any text or image Multimedia   Adding links On your Moodle site, you can show content from anywhere on the Web by using a link. You can also link to files that you've uploaded into your course. By default, this content appears in a frame within your course. You can also choose to display it in a new window. When using content from outside sites, you need to consider the legality and reliability of using the link. Is it legal to display the material on your Moodle site? Will the material still be there when your course is running? In this example, I've linked to an online resource from the BBC, which is a fairly reliable source: Remember that the bottom of the window displays Window Settings, so you can choose to display this resource in its own window. You can also set the size of the window. You may want to make it appear in a smaller window, so that it does not completely obscure the window of your Moodle site. This will make it clearer to the student that he or she has opened a new window. To add a link to a resource on the Web: Log in to your course as a Teacher or Site Administrator. In the upper-right corner of the page, if you see a button that reads, Turn editing on, click on this button. If it reads Turn editing off, then you do not need to click on this button. (You will also find this button in the Settings menu on the leftmost side of the page.) From the Add a resource... drop-down menu, select URL. Moodle displays the Adding a new URL page. Enter a Name for the link. This is the name that people will see on the home page of your course. Enter a Description for the link. When the student sees the course's home page, they will see the Name and not the Description. However, whenever this resource is selected from the Navigation bar, the Description will be displayed. Here is a link as it appears on the home page of a course: Here is the same link, as it appears when selected from the Navigation bar: In the External URL field, enter the Web address for this link. From the Display drop-down menu, select the method that you want Moodle to use when displaying the linked page. Embed will insert the linked page into a Moodle page. Your students will see the Navigation bar, any blocks that you have added to the course and navigation links across the top of the page, just like when they view any other page in Moodle. The center of the page will be occupied by the linked page. Open will take the student away from your site, and open the linked page in the window that was occupied by Moodle. In pop-up will launch a new window, containing the linked page on top of the Moodle page. Automatic will make Moodle choose the best method for displaying the linked page. The checkboxes for Display URL name and Display URL description will affect the display of the page, only if Embed is chosen as the display method. If selected, the Name of the link will be displayed above the embedded page, and the Description will be displayed below the embedded page. Under Options, the ShowAdvanced button will display fields that allow you to set the size of the popup window. If you don't select In pop-up as the display method, these fields have no effect. Under Parameters, you can add parameters to the link. In a Web link, a parameter would add information about the course or student to the link. If you have Web programming experience, you might take advantage of this feature. For more about passing parameters in URLs, see http://en.wikipedia.org/wiki/Query_string. Under Common Module Settings, the Visible setting determines if this resource is visible to students. Teachers and site Administrators can always see the resource. Setting this to Hide will completely hide the resource. Teachers can hide some resources and activities at the beginning of a course, and reveal them as the course progresses. Show/Hide versus Restrict availability If you want a resource to be visible, but not available, then use the Restrict Availability settings further down on the page. Those settings enable you to have a resource's name and its description appear, but still make the resource unavailable. You might want to do this for resources that will be used later in a course, when you don't want the student to work ahead of the syllabus. The ID number field allows you to enter an identifier for this resource, which will appear in the Gradebook. If you export grades from the Gradebook and then import them into an external database, you might want the course ID number here to match the ID number that you use in that database. The Restrict Availability settings allow you to set two kinds of conditions that will control whether this resource is available to the student. The Accessible from and Accessible until settings enable you to set dates for when this resource will be available. The Grade condition setting allows you to specify the grade that a student must achieve in another Activity in this course, before being able to access this Resource. The setting for Before activity is available determines if the Resource will be visible while it is unavailable. If it is visible but unavailable, Moodle will display the conditions needed to make it available (achieve a grade, wait for a date, and so on.). Click on one of the Save buttons at the bottom of the page to save your work.   Adding pages Under the Add a resource drop-down menu, select Page to add a Web page to a course. A link to the page that you create will appear on the course's home page. Moodle's HTML editor When you add a Page to your course, Moodle displays a Web page editor. This editor is based on an open source web page editor called TinyMCE. You can use this editor to compose a web page for your course. This page can contain almost anything that a web page outside of Moodle can contain. Pasting text into a Moodle page Many times, we prefer to write text in our favorite word processor instead of writing it in Moodle. Or we may find text that we can legally copy and paste into a Moodle page, somewhere else. Moodle's text editor does allow you to do this. To paste text into a page, you can just use the appropriate keyboard shortcut. Try Ctrl + V for Windows PCs and Apple + V for Macintoshes. If you use this method, the format of the text will be preserved. To paste plain text, without the format of the original text, click on the Paste as Plain Text icon, as shown below: When you paste text from a Microsoft Word document into a web page, it usually includes a lot of non-standard HTML code. This code doesn't work well in all browsers, and makes it more difficult to edit the HTML code in your page. Many advanced web page editors, such as AdobeDreamWeaver, have the ability to clean up Word HTML code. Moodle's web page editor can also clean up Word HTML code. When pasting text that was copied from Word, use the Paste from Word icon, as shown in the image below. This will strip out most of Word's non-standard HTML code.  
Read more
  • 0
  • 0
  • 5097

article-image-nhibernate-3-creating-sample-application
Packt
06 Sep 2011
8 min read
Save for later

NHibernate 3: Creating a Sample Application

Packt
06 Sep 2011
8 min read
  (For more resources on NHibernate, see here.)   Prepare our development environment We assume that you have a computer at hand which has Windows Vista, Windows 7, Windows Server 2003 or Windows Server 2008 installed. If you are using an Apple computer, then you can install, for example, Windows 7 as a virtual machine. First, install Microsoft Visual Studio 2010 Professional, Microsoft Visual C# 2010 Express or Microsoft Visual Basic 2010 Express on your system. The Express editions of Visual Studio can be downloaded from http://www.microsoft.com/express/windows. Note that NHibernate 3.x can also be used with the 2008 editions of Microsoft Visual Studio, but not with any older versions. NHibernate 3.x is based on the .NET framework version 3.5, and thus only works with IDEs that support this or a higher version of the .NET framework. Additionally, note that if you don't want to use Visual Studio, then there are at least two other free OSS options available to you: MonoDevelop is an IDE primarily designed for C# and other .NET languages. MonoDevelop makes it easy for developers to port .NET applications created with Visual Studio to Linux and to maintain a single code base for all platforms. MonoDevelop 2.4 or higher can be downloaded from http://monodevelop.com/download. SharpDevelop is a free IDE for C#, VB.NET, and Boo projects on Microsoft's .NET platform. It is open source. SharpDevelop 3.2 or higher can be downloaded from http://sharpdevelop.net/OpenSource/SD/Default.aspx. Furthermore, note that NHibernate also works on Mono: http://www.mono-project.com. Next, we need a relational database to play with. NHibernate supports all major relational databases like Oracle, MS SQL Server, MySQL, and so on. We will use MS SQL Server as our Relational Database Management System (RDBMS). Microsoft SQL Server is the most used RDBMS in conjunction with NHibernate and, in general, with .NET projects. The SQL Server driver for NHibernate is one of the most tested drivers in NHibernate's suite of unit tests, and when specific new features come out, it is likely that they will be first supported by this driver. Install the free Microsoft SQL Server 2008 R2 Express on your system if you have not already done so during the install of Visual Studio. You can download the express edition of MS SQL Server from here http://www.microsoft.com/express/Database/. For our samples, it really doesn't matter which version you download: the 32-bit or the 64-bit version. Just take the one that matches best with the bitness of your operating system. Make sure that you install SQL Server with the default instance name of SQL Express. Make sure you also download and install the free SQL Server Management Studio Express (SSMS) from the following link: http://www.microsoft.com/download/en/details.aspx?id=22985 Now, we are ready to tackle NHibernate. We can download NHibernate 3.1.0 GA from Source Forge http://sourceforge.net/projects/nhibernate/. The download consists of a single ZIP file containing the following content, as shown in the screenshot: The binaries that are always needed when developing an NHibernate based application can be found in the Required_Bins folder. Opening this folder, we find the files as shown in the following screenshot: Note that if you are downloading version 3.1 or newer of NHibernate, you will no longer find the two DLLs, Antlr3.Runtime.dll and Remotion.Data.Linq.dll, in the ZIP file that were present in version 3.0. The reason is that they have been IL merged into the NHibernate.dll. If we want to use lazy loading with NHibernate (and we surely will), then we also have to use some additional files which can be found in the Required_For_LazyLoading folder. Lazy loading is a technique that is used to load certain parts of the data only when really needed, which is when the code accesses it. There are three different options at hand. We want to choose Castle. The corresponding folder contains these files, as shown in the following screenshot: As we are also using Fluent NHibernate, we want to download the corresponding binaries too. Go grab the binaries from the Fluent NHibernate website and copy them to the appropriate location on your system. In either case, there is no installer available or needed. We just have to copy a bunch of files to a folder we define. Please download Fluent NHibernate, which also contains the binaries for NHibernate, from here (http://fluentnhibernate.org/downloads), as shown in the following screenshot. Make sure you download the binaries for NHibernate 3.1 and not an earlier version. Save the ZIP file you just downloaded to a location where you can easily find it for later usage. The ZIP file contains the files shown in the following screenshot: The only additional files regarding the direct NHibernate download are the FluentNHibernate.* files. On the other hand, we do not have the XSD schema files (nhibernate-configuration.xsd and nhibernate-mapping.xsd) included in this package and we'll want to copy those from the NHibernate package when implementing our sample.   Defining a model After we have successfully downloaded the necessary NHibernate and Fluent NHibernate files, we are ready to start implementing our first application using NHibernate. Let's first model the problem domain we want to create the application for. The domain for which we want to build our application is a product inventory system. With the application, we want to be able to manage a list of products for a small grocery store. The products shall be grouped by category. A category consists of a name and a short description. The product on the other hand has a name, a short description, a category, a unit price, a reorder level, and a flag to determine whether it is discontinued or not. To uniquely identify each category and product, they each have an ID. If we draw a class diagram of the model just described, then it would look similar to the following screenshot: Unfortunately, the class designer used to create the preceding diagram is only available in the professional version of Visual Studio and not in the free Express editions.   Time for action – Creating the product inventory model Let's implement the model for our simple product inventory system. First, we want to define a location on our system, where we will put all our code that we create. Create a folder called NH3BeginnersGuide on your file system. Inside this new folder, create another folder called lib. This is the place where we will put all the assemblies needed to develop an application using NHibernate and Fluent NHibernate. Locate the ZIP file containing the Fluent NHibernate files that you downloaded in the first section of this article. Extract all files to the lib folder created in the preceding step. Open Visual Studio and create a new project. Choose WPF Application as the project template. Call the project Chapter2. Make sure that the solution you create will be saved in the folder NH3BeginnersGuide you created in the preceding step. When using VS 2008 Pro, you can do this when creating the new project. If, on the other hand, you use the Express edition of Visual Studio, then you choose the location when you first save your project. (Move the mouse over the image to enlarge.) Add a new class to the project and call it Category. To this class, add a virtual (auto-) property called Id, which is of the int type. Also, add two other virtual properties of the string type, called Name and Description. The code should look similar to the following code snippet: namespace Chapter2{ public class Category { public virtual int Id { get; set; } public virtual string Name { get; set; } public virtual string Description { get; set; } }} Downloading the example code You can download the example code files here. Add another class to the project and call it Product. To this class, add the properties, as shown in the following code snippet. The type of the respective property is given in parenthesis: Id (int), Name (string), Description (string), Category (Category), UnitPrice (decimal), ReorderLevel (int), and Discontinued (bool). The resulting code should look similar to the following code snippet: namespace Chapter2{ public class Product { public virtual int Id { get; set; } public virtual string Name { get; set; } public virtual string Description { get; set; } public virtual Category Category { get; set; } public virtual decimal UnitPrice { get; set; } public virtual int ReorderLevel { get; set; } public virtual bool Discontinued { get; set; } }} What just happened? We have implemented the two classes Category and Product, which define our simple domain model. Each attribute of the entity is implemented as a virtual property of the class. To limit the amount of code necessary to define the entities, we use auto properties. Note that the properties are all declared as virtual. This is needed as NHibernate uses lazy loading by default.  
Read more
  • 0
  • 0
  • 4616

article-image-html5-games-development-using-local-storage-store-game-data
Packt
05 Sep 2011
8 min read
Save for later

HTML5 Games Development: Using Local Storage to Store Game Data

Packt
05 Sep 2011
8 min read
  (For more resources on this subject, see here.)   The following screenshot shows the final result we will create through this article. So, let's get on with it: Storing data by using HTML5 local storage Imagine now we have published our CSS3 memory matching game (Code Download-Ch:3) and players are trying their best to perform well in the game. We want to show the players whether they played better or worse than the last time. We will save the latest score and inform players whether they are better or not this time by comparing the scores. They may feel proud when performing better. This may make them addicted and they may keep trying to get higher scores. Creating a game over dialog Before actually saving anything in the local storage, we need a game over screen. Imagine now we are playing the CSS3 memory matching game that we built and we successfully match and remove all cards. Once we finish, a game over screen pops up and shows the time we utilized to complete the game. Time for action – Creating a game over dialog with the elapsed played time Open the CSS3 matching game folder as our working directory. Download a background image from the following URL (we will use it as the background of the pop up): http://gamedesign.cc/html5games/popup_bg.jpg Place the image in the images folder. Open index.html into any text editor. We will need a font for the game over pop up. Add the following font embedding CSS into the head section: <link href="http://fonts.googleapis.com/css?family=Orbitron:400,700" rel="stylesheet" type="text/css" > Before the game section, we add a div named timer to show the elapsed playing time. In addition, we add a new popup section containing the HTML markup of the pop-up dialog: <div id="timer"> Elapsed time: <span id="elapsed-time">00:00</span></div><section id="game"> <div id="cards"> <div class="card"> <div class="face front"></div> <div class="face back"></div> </div> <!-- .card --> </div> <!-- #cards --></section> <!-- #game --><section id="popup" class="hide"> <div id="popup-bg"> </div> <div id="popup-box"> <div id="popup-box-content"> <h1>You Won!</h1> <p>Your Score:</p> <p><span class='score'>13</span></p> </div> </div></section> We will now move on to the style sheet. As it is just for styling and not related to our logic yet, we can simply copy the matchgame.css file from matching_game_with_game_over in the code example bundle (Ch:3). It is time to edit the game logic part. Open the html5games.matchgame.js file in an editor. In the jQuery ready function, we need a variable to store the elapsed time of the game. Then, we create a timer to count the game every second as follows: $(function(){ ...// reset the elapsed time to 0.matchingGame.elapsedTime = 0; // start the timer matchingGame.timer = setInterval(countTimer, 1000);} Next, add a countTimer function which will be executed every second. It displays the elapsed seconds in the minute and second format: function countTimer(){ matchingGame.elapsedTime++; // calculate the minutes and seconds from elapsed time var minute = Math.floor(matchingGame.elapsedTime / 60); var second = matchingGame.elapsedTime % 60; // add padding 0 if minute and second is less then 10 if (minute < 10) minute = "0" + minute; if (second < 10) second = "0" + second; // display the elapsed time $("#elapsed-time").html(minute+":"+second);} In the removeTookCards function which we wrote earlier, add the following highlighted code that executes the game over logic after removing all cards: function removeTookCards(){$(".card-removed").remove(); // check if all cards are removed and show game over if ($(".card").length == 0) { gameover(); } } At last, we create the following gameover function. It stops the counting timer, displays the elapsed time in the game over pop up, and finally shows the pop up: function gameover(){ // stop the timer clearInterval(matchingGame.timer); // set the score in the game over popup $(".score").html($("#elapsed-time").html()); // show the game over popup $("#popup").removeClass("hide");} Now, save all files and open the game in a browser. Try finishing the memory matching game and the game over screen will pop up, as shown in the following screenshot: What just happened? We have used the CSS3 transition animation to show the game over pop up. We benchmark the score by using the time a player utilized to finish the game. Saving scores in the browser Imagine now we are going to display how well the player played the last time. The game over screen includes the elapsed time as the last score alongside the current game score. Players can then see how well they do this time compared to last time. Time for action – Saving the game score First, we need to add a few markups in the popup section to display the last score. Add the following HTML in the popup section in index.html: <p> <small>Last Score: <span class='last-score'>20</span> </small></p> Then, we open the html5games.matchgame.js to modify some game logic in the gameover function. Add the following highlighted code in the gameover function. It loads the saved score from local storage and displays it as the score last time. Then, save the current score in the local storage: function gameover(){ // stop the timer clearInterval(matchingGame.timer); // display the elapsed time in the game over popup $(".score").html($("#elapsed-time")); // load the saved last score from local storage var lastElapsedTime = localStorage.getItem ("last-elapsed-time"); // convert the elapsed seconds into minute:second format // calculate the minutes and seconds from elapsed time var minute = Math.floor(lastElapsedTime / 60); var second = lastElapsedTime % 60; // add padding 0 if minute and second is less then 10 if (minute < 10) minute = "0" + minute; if (second < 10) second = "0" + second; // display the last elapsed time in game over popup $(".last-score").html(minute+":"+second); // save the score into local storage localStorage.setItem ("last-elapsed-time", matchingGame.elapsedTime); // show the game over popup $("#popup").removeClass("hide");} It is now time to save all files and test the game in the browser. When you finish the game for the first time, the last score should be 00:00. Then, try to finish the game for the second time. The game over pop up will show the elapsed time you played the last time. The following screenshot shows the game over screen with the current and last score: What just happened? We just built a basic scoring system that compares a player's score with his/her last score. Storing and loading data with local storage We can store data by using the setItem function from the localStorage object. The following table shows the usage of the function: localStorage.setItem(key, value); In our example, we save the game elapsed time as the score with the following code by using the key last-elapsed-item: localStorage.setItem("last-elapsed-time", matchingGame.elapsedTime); Complementary to setItem, we get the stored data by using the getItem function in the following way: localStorage.getItem(key); The function returns the stored value of the given key. It returns null when trying to get a non-existent key. This can be used to check whether we have stored any data for a specific key. The local storage saves the string value The local storage stores data in a key-value pair. The key and value are both strings. If we save numbers, Boolean, or any type other than string, then it will convert the value into a string while saving. Usually, problems occur when we load a saved value from the local storage. The loaded value is a string regardless of the type we are saving. We need to explicitly parse the value into the correct type before using it. For example, if we save a floating number into the local storage, we need to use the parseFloat function when loading it. The following code snippet shows how we can use parseFloat to retrieve a stored floating number: var score = 13.234;localStorage.setItem("game-score",score);// result: stored "13.234".var gameScore = localStorage.getItem("game-score");// result: get "13.234" into gameScore;gameScore = parseFloat(gameScore);// result: 13.234 floating value In the preceding code snippet, the manipulation may be incorrect if we forget to convert the gameScore from string to float. For instance, if we add the gameScore by 1 without the parseFloat function, the result will be 13.2341 instead of 14.234. So, be sure to convert the value from local storage to its correct type. Size limitation of local storageThere is a size limitation on the data stored through localStorage for each domain. This size limitation may be slightly different in different browsers. Normally, the size limitation is 5 MB. If the limit is exceeded, then the browser throws a QUOTA_EXCEEDED_ERR exception when setting a key-value into localStorage. Treating the local storage object as an associated array Besides using the setItem and getItem functions, we can treat the localStorage object as an associated array and access the stored entries by using square brackets. For instance, we can replace the following code with the latter version: Using the setItem and getItem: localStorage.setItem("last-elapsed-time", elapsedTime);var lastElapsedTime = localStorage.getItem("last-elapsed-time"); Access localStorage as an array as follows: localStorage["last-elapsed-time"] = elapsedTime;var lastElapsedTime = localStorage["last-elapsed-time"];
Read more
  • 0
  • 0
  • 10666
article-image-jquery-ui-18-accordion-widget
Packt
05 Sep 2011
9 min read
Save for later

jQuery UI 1.8: The Accordion Widget

Packt
05 Sep 2011
9 min read
  (For more resources on jQuery, see here.)   Each container has a heading element associated with it that is used to open the container and display the content. When you click on a heading, its content will slide into view (with an animation) below it. The currently visible content is hidden, while the new content is shown whenever we click on an accordion heading. The accordion widget is a robust and highly configurable widget that allows you to save space on your web pages, by displaying only a single panel of content at any time. The following screenshot shows an example of an accordion widget: It's easy for our visitors to use and easy for us to implement. It has a range of configurable options that can be used to customize its appearance and behavior, and exposes a series of methods that allow you to control it programmatically. It also comes with a rich set of interaction events that we can use to hook into key interactions between our visitors and the widget. The height of the accordion's container element will be set automatically, so that there is room to show the tallest content panel in addition to the headers. Also, by default, the size of the widget will remain fixed, so that it won't push other elements on the page around it out of the way, when content panels open or close.   Accordion's structure Let's take a moment to familiarize ourselves with the underlying markup that an accordion is made of. Within the outer container is a series of links. These links are the headings within the accordion and each heading will have a corresponding content panel that opens when the header is clicked. It's worth remembering that only one content panel can be open at a time when using the accordion widget. In a blank page in your text editor, create the following page: <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <link rel="stylesheet" href="css/smoothness/jquery-ui-1.8.9.custom.css"> <title>Accordion </title> </head> <body> <div id="myAccordion"> <h2> <a href="#">Header 1 </a> </h2> <div>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean sollicitudin. Sed interdum pulvinar justo. Nam iaculis volutpat ligula. Integer vitae felis quis diam laoreet ullamcorper. </div> <h2> <a href="#">Header 2 </a> </h2> <div>Etiam tincidunt est vitae est. Ut posuere, mauris at sodales rutrum, turpis tellus fermentum metus, ut bibendum velit enim eu lectus. Suspendisse potenti. </div> <h2> <a href="#">Header 3 </a> </h2> <div>Donec at dolor ac metus pharetra aliquam. Suspendisse purus. Fusce tempor ultrices libero. Sed quis nunc. Pellentesque tincidunt viverra felis. Integer elit mauris, egestas ultricies, gravida vitae, feugiat a, tellus. </div> </div> <script src="development-bundle/jquery-1.3.2.js"> </script> <script src="development-bundle/ui/ui.core.js"> </script> <script src="development-bundle/ui/ui.accordion.js"> </script> <script> $(function() { $("#myAccordion").accordion(); }); </script> </body> </html> Save the file as accordion1.html in the jqueryui folder, and try it out in a browser. The widget should appear as it did in the screenshot at the start of the article, fully skinned and ready for action. The following list shows the required dependencies of the widget: jquery.ui.all.css jquery-x.x.x.js jquery.ui.core.js jquery.ui.accordion.js Each widget also has its own source file, and may depend on other components as well. For example, we could include some effect files to use non-standard animations on the opening accordion panels. The order in which these files appear is important. The jQuery library must always appear first, followed by the jquery.ui.core.js file. After these files, any other files that the widget depends upon, should appear before the widget's own script file. The library components will not function as expected if files are not loaded in the correct order. The underlying markup required for the accordion is flexible, and the widget can be constructed from a variety of different structures. In this example, the accordion headings are formed from links wrapped in <h2> elements, and the content panels are simple <div> elements. For the accordion to function correctly, each content panel should appear directly after its corresponding header. All of the elements for the widget are enclosed within a container <div> that is targeted with the accordion() widget method. After the required script dependencies from the library, we use a custom <script> block to transform the underlying markup into the accordion. To initialize the widget, we use a simple id selector $("#myAccordion"), to specify the element that contains the markup for the widget, and then chain the accordion() widget method after the selector to create the accordion. In this example, we used an empty fragment (#) as the value of the href attribute in our tab heading elements, such as: <h2><a href="#">Header 1</a></h2> You should note that any URL supplied for accordion headers will not be followed, when the header is clicked in the default implementation. Similar to the tabs widget, the underlying markup that is transformed into the accordion has a series of classnames added to it, when the widget is initialized. A number of different elements that make up the widget are given role and aria- attributes. ARIA stands for Accessible Rich Internet Applications and is a W3C recommendation for ensuring that rich-internet applications remain accessible to assisted technologies. The accordion panels that are initially hidden from view are given the attribute aria-expanded="false" to ensure that screen readers don't discard or cannot access content that is hidden using display:none. This makes the accordion widget highly accessible.   Styling the accordion ThemeRoller is the recommended tool for choosing or creating the theme of the accordion widget, but there may be times when we want to considerably change the look and style of the widget beyond what is possible with ThemeRoller. In that case, we can just style our own accordion. In a new page in your text editor add the following code: #myAccordion { width:400px; border:1px solid #636363; padding-bottom:1px; } .ui-accordion-header { border:1px solid #fff; font-family:Georgia; background:#e2e2e2 none; } .ui-widget-content { font-size:70%; border:none; } .ui-corner-bottom { -moz-border-radius:4px 4px 0 0; -webkit-border-radius:4px 4px 0 0; border-radius:4px 4px 0 0; } .ui-corner-all { -moz-border-radius:0; -webkit-border-radius:0; border-radius:0; } .ui-accordion .ui-accordion-header { margin:0 0 -1px; } #myAccordion .ui-state-active, #myAccordion .ui-widget-content .ui-state-active { background:#fff; } .ui-state-hover, .ui-widget-content .ui-state-hover { background:#d2d2d2; } Save this file as accordionTheme.css in the css folder, and link to it after the jQuery UI style sheet in the <head> of accordion1.html: <link rel="stylesheet" href="css/accordionTheme.css"> Save the new file as accordion2.html in the jqueryui folder and view it in a browser. It should appear something like this: As you can see from this screenshot, we've disabled the built-in rounded corners that are added by the theme file and have set alternative fonts, background colors, and border colors. We haven't changed the widget much, but we haven't used many style rules. It would be easy to continue overriding rules in this way to build a much more complex custom theme.   Configuring an accordion The accordion has a range of configurable options that allow us to change the default behavior of the widget. The following table lists the available options, their default values, and gives a brief description of their usage: Option Default value Used to... active first child (the first panel is open) Set the active heading on page load. animated slide Animate the opening of content panels. autoHeight true Automatically set height according to the biggest drawer. clearStyle false Clear the height and overflow styles after a panel opens. collapsible false Allow all of the content panels to be closed at the same time. disabled false Disable the widget. event click Specify the event on headers that trigger drawers to open. fillSpace false Allow the accordion to fill the height of its container instead of sizing itself according to the content within it. header > li >:first-child,>:not(li):even Specify the selector for header elements. Although it looks complex, this is a standard jQuery selector that simply targets the first-child within every odd <li> element. icons 'header': 'ui-icon-triangle-1-e', 'headerSelected': 'ui-icon-triangle-1-s' Set the icons for the header elements and the selected state. navigation false Enable navigation mode for accordion. navigationFilter location.href Change the function used to obtain the ID of the content panel that should be open when the widget is initialized. Changing the trigger event Most of the options are self-explanatory, and the values they accept are usually Booleans, strings, or element selectors. Let's put some of them to use, so that we can explore their functionality. Change the final <script> element in accordion2.html so that it appears as follows: <script> (function($) { var accOpts = { event:"mouseover" } $("#myAccordion").accordion(accOpts); })(jQuery); </script> Save these changes as accordion3.html. First, we create a new object literal called accOpts that contains the key event and the value mouseover, which is the event we wish to use to trigger the opening of an accordion panel. We pass this object to the accordion() method as an argument and it overrides the default option of the widget, which is click. The mouseover event is commonly used as an alternative trigger event. Other events can also be used, for example, we can set keydown as the event, but in order for this to work, the accordion panel that we wish to open, must already be focused. You should note that you can also set options using an inline object within the widget method, without creating a separate object. Using the following code would be equally as effective, and would often be the preferred way of coding: <script> (function($) { $("#myAccordion").accordion({ event:"mouseover" }); })(jQuery); </script>  
Read more
  • 0
  • 0
  • 3137

article-image-yii-11-using-zii-components
Packt
05 Sep 2011
10 min read
Save for later

Yii 1.1: Using Zii Components

Packt
05 Sep 2011
10 min read
  (For more resources on this subject, see here.) Introduction Yii have a useful library called Zii. It's bundled with framework and includes some classes aimed to make the developer's life easier. Its most handy components are grids and lists which allow you to build data in both the admin and user parts of a website in a very fast and efficient way. In this article you'll learn how to use and adjust these components to fit your needs. Also you'll learn about data providers. They are part of the core framework, not Zii, but since they are used extensively with grids and lists, we'll review them here. We'll use Sakila sample database version 0.8 available from official MySQL website: http://dev.mysql.com/doc/sakila/en/sakila.html. Using data providers Data providers are used to encapsulate common data model operations such as sorting, pagination and querying. They are used with grids and lists extensively. Because both widgets and providers are standardized, you can display the same data using different widgets and you can get data for a widget from various providers. Switching providers and widgets is relatively transparent. Currently there are CActiveDataProvider, CArrayDataProvider, and CSqlDataProvider implemented to get data from ActiveRecord models, arrays, and SQL queries respectively. Let's try all these providers to fill a grid with data. Getting ready Create a new application using yiic webapp as described in the official guide. Download the Sakila database from http://dev.mysql.com/doc/sakila/en/sakila.html and execute the downloaded SQLs: first schema then data. Configure the DB connection in protected/config/main.php. Use Gii to create a model for the film table. How to do it... Let's start with a view for a grid controller. Create protected/views/grid/index.php: <?php $this->widget('zii.widgets.grid.CGridView', array('dataProvider' => $dataProvider,))?> Then create a protected/controllers/GridController.php: <?phpclass GridController extends Controller{ public function actionAR() { $dataProvider = new CActiveDataProvider('Film', array( 'pagination'=>array( 'pageSize'=>10, ), 'sort'=>array( 'defaultOrder'=> array('title'=>false), ) )); $this->render('index', array( 'dataProvider' => $dataProvider, )); } public function actionArray() { $yiiDevelopers = array( array( 'name'=>'Qiang Xue', 'id'=>'2', 'forumName'=>'qiang', 'memberSince'=>'Jan 2008', 'location'=>'Washington DC, USA', 'duty'=>'founder and project lead', 'active'=>true, ), array( 'name'=>'Wei Zhuo', 'id'=>'3', 'forumName'=>'wei', 'memberSince'=>'Jan 2008', 'location'=>'Sydney, Australia', 'duty'=>'project site maintenance and development', 'active'=>true, ), array( 'name'=>'Sebastián Thierer', 'id'=>'54', 'forumName'=>'sebas', 'memberSince'=>'Sep 2009', 'location'=>'Argentina', 'duty'=>'component development', 'active'=>true, ), array( 'name'=>'Alexander Makarov', 'id'=>'415', 'forumName'=>'samdark', 'memberSince'=>'Mar 2010', 'location'=>'Russia', 'duty'=>'core framework development', 'active'=>true, ), array( 'name'=>'Maurizio Domba', 'id'=>'2650', 'forumName'=>'mdomba', 'memberSince'=>'Aug 2010', 'location'=>'Croatia', 'duty'=>'core framework development', 'active'=>true, ), array( 'name'=>'Y!!', 'id'=>'1644', 'forumName'=>'Y!!', 'memberSince'=>'Aug 2010', 'location'=>'Germany', 'duty'=>'core framework development', 'active'=>true, ), array( 'name'=>'Jeffrey Winesett', 'id'=>'15', 'forumName'=>'jefftulsa', 'memberSince'=>'Sep 2010', 'location'=>'Austin, TX, USA', 'duty'=>'documentation and marketing', 'active'=>true, ), array( 'name'=>'Jonah Turnquist', 'id'=>'127', 'forumName'=>'jonah', 'memberSince'=>'Sep 2009 - Aug 2010', 'location'=>'California, US', 'duty'=>'component development', 'active'=>false, ), array( 'name'=>'István Beregszászi', 'id'=>'1286', 'forumName'=>'pestaa', 'memberSince'=>'Sep 2009 - Mar 2010', 'location'=>'Hungary', 'duty'=>'core framework development', 'active'=>false, ), ); $dataProvider = new CArrayDataProvider( $yiiDevelopers, array( 'sort'=>array( 'attributes'=>array('name', 'id', 'active'), 'defaultOrder'=>array('active' => true, 'name' => false), ), 'pagination'=>array( 'pageSize'=>10, ), )); $this->render('index', array( 'dataProvider' => $dataProvider, )); } public function actionSQL() { $count=Yii::app()->db->createCommand('SELECT COUNT(*) FROM film')->queryScalar(); $sql='SELECT * FROM film'; $dataProvider=new CSqlDataProvider($sql, array( 'keyField'=>'film_id', 'totalItemCount'=>$count, 'sort'=>array( 'attributes'=>array('title'), 'defaultOrder'=>array('title' => false), ), 'pagination'=>array( 'pageSize'=>10, ), )); $this->render('index', array( 'dataProvider' => $dataProvider, )); }} Now run grid/aR, grid/array and grid/sql actions and try using the grids. How it works... The view is pretty simple and stays the same for all data providers. We are calling the grid widget and passing the data provider instance to it. Let's review actions one by one starting with actionAR: $dataProvider = new CActiveDataProvider('Film', array( 'pagination'=>array( 'pageSize'=>10, ), 'sort'=>array( 'defaultOrder'=>array('title'=>false), ))); CActiveDataProvider works with active record models. Model class is passed as a first argument of class constructor. Second argument is an array that defines class public properties. In the code above, we are setting pagination to 10 items per page and default sorting by title. Note that instead of using a string we are using an array where keys are column names and values are true or false. true means order is DESC while false means that order is ASC. Defining the default order this way allows Yii to render a triangle showing sorting direction in the column header. In actionArray we are using CArrayDataProvider that can consume any array. $dataProvider = new CArrayDataProvider($yiiDevelopers, array( 'sort'=>array( 'attributes'=>array('name', 'id', 'active'), 'defaultOrder'=>array('active' => true, 'name' => false), ), 'pagination'=>array( 'pageSize'=>10, ),)); First argument accepts an associative array where keys are column names and values are corresponding values. Second argument accepts an array with the same options as in CActiveDataProvider case. In actionSQL, we are using CSqlDataProvider that consumes the SQL query and modifies it automatically allowing pagination. First argument accepts a string with SQL and a second argument with data provider parameters. This time we need to supply calculateTotalItemCount with total count of records manually. For this purpose we need to execute the extra SQL query manually. Also we need to define keyField since the primary key of this table is not id but film_id. To sum up, all data providers are accepting the following properties: pagination CPagination object or an array of initial values for new instance of CPagination. sort CSort object or an array of initial values for new instance of CSort. totalItemCount We need to set this only if the provider, such as CsqlDataProvider, does not implement the calculateTotalItemCount method. There's more... You can use data providers without any special widgets. Replace protected/views/grid/ index.php content with the following: <?php foreach($dataProvider->data as $film):?> <?php echo $film->title?><?php endforeach?> <?php $this->widget('CLinkPager',array( 'pages'=>$dataProvider->pagination))?> Further reading To learn more about data providers refer to the following API pages:   http://www.yiiframework.com/doc/api/CDataProvider http://www.yiiframework.com/doc/api/CActiveDataProvider http://www.yiiframework.com/doc/api/CArrayDataProvider http://www.yiiframework.com/doc/api/CSqlDataProvider http://www.yiiframework.com/doc/api/CSort http://www.yiiframework.com/doc/api/CPagination Using grids Zii grids are very useful to quickly create efficient application admin pages or any pages you need to manage data on. Let's use Gii to generate a grid, see how it works, and how we can customize it. Getting ready Carry out the following steps: Create a new application using yiic webapp as described in the official guide. Download the Sakila database from http://dev.mysql.com/doc/sakila/en/sakila.html. Execute the downloaded SQLs: first schema then data. Configure the DB connection in protected/config/main.php. Use Gii to create models for customer, address, and city tables. How to do it... Open Gii, select Crud Generator, and enter Customer into the Model Class field. Press Preview and then Generate. Gii will generate a controller in protected/controllers/CustomerController.php and a group of views under protected/views/customer/. Run customer controller and go to Manage Customer link. After logging in you should see the grid generated: How it works... Let's start with the admin action of customer controller: public function actionAdmin(){ $model=new Customer('search'); $model->unsetAttributes(); // clear any default values if(isset($_GET['Customer'])) $model->attributes=$_GET['Customer']; $this->render('admin',array( 'model'=>$model, ));} Customer model is created with search scenario, all attribute values are cleaned up, and then filled up with data from $_GET. On the first request $_GET is empty but when you are changing the page, or filtering by first name attribute using the input field below the column name, the following GET parameters are passed to the same action via an AJAX request: Customer[address_id] =Customer[customer_id] =Customer[email] =Customer[first_name] = alexCustomer[last_name] =Customer[store_id] =Customer_page = 2ajax = customer-grid Since scenario is search, the corresponding validation rules from Customer::rules are applied. For the search scenario, Gii generates a safe rule that allows to mass assigning for all fields: array('customer_id, store_id, first_name, last_name, email, address_id, active, create_date, last_update', 'safe','on'=>'search'), Then model is passed to a view protected/views/customer/admin.php. It renders advanced search form and then passes the model to the grid widget: <?php $this->widget('zii.widgets.grid.CGridView', array( 'id'=>'customer-grid', 'dataProvider'=>$model->search(), 'filter'=>$model, 'columns'=>array( 'customer_id', 'store_id', 'first_name', 'last_name', 'email', 'address_id', /* 'active', 'create_date', 'last_update', */ array( 'class'=>'CButtonColumn', ), ),)); ?> Columns used in the grid are passed to columns. When just a name is passed, the corresponding field from data provider is used. Also we can use custom column represented by a class specified. In this case we are using CButtonColumn that renders view, update and delete buttons that are linked to the same named actions and are passing row ID to them so action can be done to a model representing specific row from database. filter property accepts a model filled with data. If it's set, a grid will display multiple text fields at the top that the user can fill to filter the grid. The dataProvider property takes an instance of data provider. In our case it's returned by the model's search method : public function search(){ // Warning: Please modify the following code to remove attributes that // should not be searched. $criteria=new CDbCriteria; $criteria->compare('customer_id',$this->customer_id); $criteria->compare('store_id',$this->store_id); $criteria->compare('first_name',$this->first_name,true); $criteria->compare('last_name',$this->last_name,true); $criteria->compare('email',$this->email,true); $criteria->compare('address_id',$this->address_id); $criteria->compare('active',$this->active); $criteria->compare('create_date',$this->create_date,true); $criteria->compare('last_update',$this->last_update,true); return new CActiveDataProvider(get_class($this), array( 'criteria'=>$criteria, ));} This method is called after the model was filled with $_GET data from the filtering fields so we can use field values to form the criteria for the data provider. In this case all numeric values are compared exactly while string values are compared using partial match.
Read more
  • 0
  • 0
  • 3685
Modal Close icon
Modal Close icon