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-oracle-business-intelligence-getting-business-information-data
Packt
13 Oct 2010
11 min read
Save for later

Oracle Business Intelligence : getting business information from data

Packt
13 Oct 2010
11 min read
Most businesses today use Business Intelligence (BI), the process of obtaining business information from available data, to control their affairs. If you're new to Business Intelligence, then this definition may leave you with the following questions: What is data? What is the information obtained from it? What is the difference between data and the information obtained from it? You may be confused even more if you learn that data represents groups of information related to an object or a set of objects. Depending on your needs, though, such groups of information may or may not be immediately useful, and often require additional processing such as filtering, formatting, and/or calculating to take on a meaning. For example, information about your customers may be organized in a way that is stored in several database tables related to each other. For security purposes, some pieces of information stored in this way may be encoded, or just represented in binary, and therefore not immediately readable. It's fairly obvious that some processing must be applied before you can make use of such information. So, data can be thought of as the lowest level of abstraction from which meaningful information is derived. But what is information anyway? Well, a piece of information normally represents an answer to a certain question. For example, you want to know how many new customers have registered on your site this year. An answer to this question can be obtained with a certain query issued against the table containing customer registration dates, giving you the information you asked for. Data, information, and Business Intelligence Although the terms data and information refer to similar things, they aren't really interchangeable as there is some difference in their meaning and spirit. Talking about data, as a rule, involves its structure, format, storage, as well as ways in which you can access and manipulate it. In contrast, when talking about information, you mean food for your decision-making process. So, data can be viewed as low-level information structures, where the internal representation matters. Therefore, the ways in which you can extract useful information from data entirely depend on the structure and storage of that data. The following diagram gives a conceptual view of delivering information from different data sets: As you can see from the figure, information can be derived from different data sources, and by different means. Once it's derived, though, it doesn't matter where it has come from, letting its consumers concentrate on the business aspects rather than on the specifics of the internal structure. For example, you might derive some pieces of data from the Web, using the Oracle Database's XQuery feature, and then process it as native database data. To produce meaningful information from your data, you will most likely need to perform several processing steps, load new data, and summarize the data. This is why the Business Intelligence layer usually sits on top of many data sources, consolidating information from various business systems and heterogeneous platforms. The following figure gives a graphical depiction of a Business Intelligence system. In particular, it shows you that the Business Intelligence layer consumes information derived from various sources and heterogeneous platforms. It is intuitively clear that the ability to solve problems is greatly enhanced if you can effectively handle all the information you're getting. On the other hand, extracting information from data coming in from different sources may become a nightmare if you try to do it on your own, with only the help of miscellaneous tools. Business Intelligence comes to the rescue here, ensuring that the extraction, transformation, and consolidation of data from disparate sources becomes totally transparent to you. For example, when using a Business Intelligence application for reporting, you may never figure out exactly what happens behind the scenes when you instruct the system to prepare another report. The information you need for such a report may be collected from many different sources, hiding the complexities associated with handling heterogeneous data. But, without Business Intelligence, that would be a whole different story, of course. Imagine for a moment that you have to issue several queries against different systems, using different tools, and you then have to consolidate the results somehow—all just to answer a single business question such as: what are the top three customers for the preceding quarter? As you have no doubt realized, the software at the Business Intelligence layer is used to provide a business-centric view of data, eliminating as much of the technology-specific logic as possible. What this means in practice is that information consumers working at the Business Intelligence layer may not even know that, say, customer records are stored in a Lightweight Directory Access Protocol (LDAP) database, but purchase orders are kept in a relational database. The kind of business questions you may need to answer As you just learned, Business Intelligence is here to consolidate information from disparate sources so that you need not concern yourself with it. Okay, but why might you need to gather and process heterogeneous data? The answer is clear. You might need it in order to answer analytical questions that allow you to understand and run your business better. In the following two sections, you'll look at some common questions that Business Intelligence can help you answer. Then, you'll see how you can ask those questions with the help of Business Intelligence tools. Answering basic business questions The set of questions you may need your Business Intelligence system to answer will vary depending on your business and, of course, your corresponding functions. However, to give you a taste of what Business Intelligence can do for you, let's firrst look at some questions that are commonly brought up by business users: What is the average salary throughout the entire organization? Which customers produce the most revenue? What is the amount of revenue each salesman brought in over the preceding quarter? What is the profitability of each product? If you run your business online, you may be also interested in hit counting and traffic analysis questions, such as the following: How much traffic does a certain account generate over a month? What pages in your site are most visited? What are the profits made online? Looking at the business analysis requests presented here, a set of questions related to your own business may flash into your mind. Answering probing analytical questions In the preceding section, you looked at some common questions a business analyst is usually interested in asking. But bowing to the reality, you may have to answer more probing questions in your decision-making process, in order to determine changes in the business and find ways to improve it. Here are some probing analytical questions you might need to find answers to: How do sales for this quarter compare to sales for the preceding quarter? What factors impact our sales? Which products are sold better together? What are ten top-selling products in this region? What are the factors influencing the likelihood of purchase? As you can see, each of these questions reflects a certain business problem. Looking through the previous list, though, you might notice that some of the questions shown here can be hard to formulate with the tools available in a computer application environment. There's nothing to be done here; computers like specific questions. Unlike humans, machines can give you exactly what you ask for, not what you actually mean. So, even an advanced Business Intelligence application will require you to be as specific as possible when it comes to putting a question to it. It's fairly clear that the question about finding the factors impacting sales needs to be rephrased to become understandable for a Business Intelligence application. How you would rephrase it depends on the specifics of your business, of course. Often, it's good practice to break apart a problem into simpler questions. For example, the first question on the above list—the one about comparing quarter sales—might be logically divided into the following two questions: What are the sales figures for this quarter? What are the sales figures for the last quarter? Once you get these questions answered, you can compare the results, thus answering the original, more generically phrased question. It can also provide one definition or variation for drill down. In the above example, it's fairly obvious what specific questions can be derived from the generic question. There may be probing questions, though, whose derived questions are not so obvious. For example, consider the following question: What motivates a customer to buy? This could perhaps be broken down into the following questions: Where did visitors come from? Which pages did they visit before reaching the product page? Of course, the above list does not seem to be complete—some other questions might be added. Asking business questions using data-access tools As you might guess, although all these questions sound simple when formulated in plain English, they are more difficult to describe when using data-access tools. If you're somewhat familiar with SQL, you might notice that most of the analytical questions discussed here cannot be easily expressed with the help of SQL statements, even if the underlying data is relational. For example, the problem of finding the top three salespersons for a year may require you to write a multi-line SQL request including several sub-queries. Here is what such a query might look like: SELECT emp.ename salesperson, top_emp_orders.sales sales FROM (SELECT all_orders.sales_empno empno, all_orders.total_sales FROM (SELECT sales_empno, SUM(ord_total) total_sales, RANK() OVER (ORDER BY SUM(ord_total) DESC) sal_rank FROM orders WHERE EXTRACT(YEAR FROM ord_dt) = 2009 GROUP BY sales_empno )all_orders WHERE all_orders.sal_rank<=3 )top_emp_orders, employees emp WHERE top_emp_orders.empno = emp.empno ORDER BY sales DESC; This might produce something like this: If you're not an SQL guru of course, writing the above query and then debugging it could easily take a couple of hours. Determining profitability by customer, for example, might take you another couple of hours to write a proper SQL query. In other words, business questions are often somewhat tricky (if possible at all) to implement with SQL. All this does not mean that SQL is not used in the area of Business Intelligence. Quite the contrary, SQL is still indispensable here. In fact, SQL has a lot to offer when it comes to data analysis. As you just saw, though, composing complex queries assumes solid SQL skills. Thankfully, most Business Intelligence tools use SQL behind the scenes totally transparently to users. Now let's look at a simple example illustrating how you can get an analytical question answered with a Business Intelligence tool—Oracle BI Discoverer Plus in this particular example. Suppose you simply want to calculate the average salary sum over the organization. This example could use the records from the hr.employees demonstration table. Creating a worksheet representing the records of a database table in the Discoverer Plus focuses on issues related to analyzing data, and creating reports with the tools available through the Oracle Business Intelligence suite. For now, look at the following screenshot to see what such a worksheet might look like: As you can see in the previous screenshot, a Discoverer Plus worksheet is similar to one in MS Excel. As in Excel, there are toolbars and menus offering a lot of options for manipulating and analyzing data presented on the worksheet. In addition, Discoverer Plus offers Item Navigator, which enables you to add data to (or remove it from) the worksheet. The data structure you can see in Item Navigator is retrieved from the database. When we return to our example, answering the question: "what is the average salary across the organization?"Similarly, in Excel, it is as simple as selecting the Salary SUM column on the worksheet, choosing an appropriate menu, and setting some parameters in the dialog shown next. After you click the OK button in this dialog box, the calculated average will be added to the worksheet in the position specified. So, the Total dialog shown in the following screenshot provides an efficient means for automating the process of creating a total on a specified data column: As you can see, this approach doesn't require you to write an SQL query on your own. Instead, Discoverer Plus will do it for you implicitly, thus allowing you to concentrate on business issues rather than data access issues. This previous example should have given you a taste of what Business Intelligence can do for you.
Read more
  • 0
  • 0
  • 1938

article-image-menus-toolbars-and-buttons-ext-js-32
Packt
13 Oct 2010
8 min read
Save for later

Menus, Toolbars, and Buttons in Ext JS 3.2

Packt
13 Oct 2010
8 min read
  Learning Ext JS 3.2 Build dynamic, desktop-style user interfaces for your data-driven web applications using Ext JS Learn to build consistent, attractive web interfaces with the framework components Integrate your existing data and web services with Ext JS data support Enhance your JavaScript skills by using Ext's DOM and AJAX helpers Extend Ext JS through custom components An interactive tutorial packed with loads of example code and illustrative screenshots         What's on the menu? We will begin by introducing the Menu class which will be used in all following examples. We are going to demonstrate usage of the Menu class as both a static component within a page, and as a popup. Both menus will be configured with the same options by using a technique where we define a variable called menuItems to reference an array which specifies the menu's items, and use it in both cases. The Menu class inherits from Container, so any menu options are child Components specified in the items config. It also inherits the usual Component config options such as renderTo, and the width option. The static menu will be rendered to the document body, and in order for it to be rendered as a visible, static element in the document, we configure it with floating: false. So the configuration we end up with is as follows: new Ext.menu.Menu({ renderTo: document.body, width: 150, floating: false, items: menuItems }); The popup menu needs no extra configuring aside from its items. We do need to decide when and where to display it. In this case we will add a contextmenu (right click) event listener to the document, and show the menu at the mouse event's position: var contextMenu = new Ext.menu.Menu({ items: menuItems }); Ext.getDoc().on({ contextmenu: function(eventObj) { contextMenu.showAt(eventObj.getXY()); }, stopEvent: true }); When we run this example, the static menu will be visible. When we right click on the document, the result should be the two menus shown below. Notice how only the second, popup menu has a shadow to indicate that it floats above the document. The menu's items The menuItems variable references an array which should be familiar by now. Just like the items config of a FormPanel, it's a list of child Components or config objects. In a menu, a config object with no xtype creates a MenuItem Component. The MenuItem class accepts the following config options in addition to those it inherits: icon: The URL of an image to display as an icon iconCls: A CSS class name which allows a stylesheet to specify a background image to use as an icon text: The text to display handler: A function to call when the item is clicked menu: A Menu object, or Menu configuration object or an array of menu items to display as a submenu when the item is clicked Because a menu inherits from Container, it can accept other Components as child items. If some complex, menu option dependent input is required, a menu may be configured with a panel as a child item. The menu config of "Menu Option 2" we're creating next contains a FormPanel as its sole child item: { text: 'Menu Option 2', iconCls: 'flag-green', menu: { plain: true, items: { xtype: 'form', border: false, bodyStyle: 'background:transparent;padding:5px', labelWidth: 70, width: 300, defaults: { anchor: '100%' }, items: [{ xtype: 'combo', editable: false, fieldLabel: 'Select', triggerAction: 'all', store: [ [0, 'One or...'], [1 ,'The other']], value: 0, getListParent: function() { return this.el.up('div.x-menu'); } }, { xtype: 'textfield', fieldLabel: 'Title' }], fbar: [{ text: 'Submit' }] } } } The configurations in the above object will mostly be familiar by now. There is one extra config we use for the menu which contains the FormPanel. plain: Specify as true so that the menu does not have to show the incised line for separating icons from text The panel within the menu has the following configs: border: Specify as false to produce a panel with no borders. bodyStyle: A CSS style string to apply to the document body. We want to make it transparent to allow the menu to show, and we apply padding. The ComboBox must render its dropdown list to the menu's element so that clicking on the list does not trigger the menu to hide: GetListParent: This is a function which a ComboBox may be configured with. It must return the HTML element to render the dropdown list into. By default a ComboBox renders its dropdown into the document. We call the up function of the Ext.Element class to find the ancestor node of the combo's element which is a DIV which has the CSS class "x-menu". The FormPanel as a child of a menu will display like this: A toolbar for every occasion An Ext JS Panel, and every Ext JS Component which inherits from the Panel class (This includes Window, TreePanel, and GridPanel) can be configured to render and manage a toolbar docked above, or below the panel's body—or both if really necessary. These are referred to as the top and bottom toolbars, or tbar and bbar for short. Panels and subclasses thereof may also be configured with a footer bar which renders buttons right at the bottom of the panel—below any bottom toolbar. The Toolbar class is also an Ext JS Component in its own way, and may when necessary be used on its own, or as a child Component of any Container. Our second example renders a toolbar standalone into the body of the document. We will use all the main button types to illustrate their usage before moving on to add handlers to react to user interaction. The toolbar will contain the following child components: A basic button A button configured with a menu which is displayed when the button is clicked A SplitButton which will display a menu only when its arrow glyph is clicked A CycleButton which on click, cycles between three different options A pair of mutually exclusive toggle buttons of which only one may be in a "pressed" state at once Ext.onReady(function(){ new Ext.Toolbar({ renderTo: Ext.getBody(), items: [{ xtype: 'button', text: 'Button' },{ xtype: 'button', text: 'Menu Button', menu: [{ text: 'Better' },{ text: 'Good' },{ text: 'Best' }] },{ xtype: 'splitbutton', text: 'Split Button', menu: [{ text: 'Item One' },{ text: 'Item Two' },{ text: 'Item Three' }] }, { xtype: 'cycle', showText: true, minWidth: 100, prependText: 'Quality: ', items: [{ text: 'High', checked: true }, { text: 'Medium' }, { text: 'Low' }] }, { text: 'Horizontal', toggleGroup: 'orientation-selector' }, { text: 'Vertical', toggleGroup: 'orientation-selector' }] }); }); As usual, everything is inside our onReady event handler. The items config holds our toolbar's entire child Components—I say child Components and not buttons because as we now know, the toolbar can accept many different types of Ext JS Components including entire forms or just form fields—which we will be implementing later on in this article. The result of the above code looks like this: The default xtype for each element in the items config is button. We can leave out the xtype config element if button is the type we want, but I like to include it just for clarity. Button configuration In addition to inherited config options, a button accepts the following configurations which we will be using in the following examples for this article: icon: The URL of an image to display as an icon iconCls: A CSS class name which allows a stylesheet to specify a background image to use as an icon text: The text to display handler: A function to call when the button is clicked menu: A Menu object, or Menu configuration object, or an array of menu items to display as a submenu when the button is clicked enableToggle: Specify as true to make a single button toggleable between pressed and unpressed state toggleGroup: A mnemonic string identifying a group of buttons of which only one may be in a "pressed" state at one time toggleHandler: A function to be called when a button's "pressed" state is changed A basic button Creating a button is fairly straightforward; the main config option is the text that is displayed on the button. We can also add an icon to be used alongside the text if we want to. A handler function is called when the button is clicked. Here is the most basic configuration of a button: { xtype: 'button', text: 'Button', handler: functionReference } The following screenshot shows what happens when the mouse is hovered over the Button button: Button with a menu A button may be configured to act as a trigger for showing a dropdown menu. If configured with a menu option, clicking the button displays a menu below the button. The alignment of the menu is configurable, but defaults to being shown below the button. Each option within the menu may itself be configured with a menu option allowing a familiar cascading menu system to be built very easily. The following is a config for a button which displays a dropdown menu upon click: { xtype: 'button', text: 'Button', menu: [{ text: 'Better' },{ text: 'Good' },{ text: 'Best' }] } The following screenshot shows what happens when the Menu Button is clicked on, and the mouse is hovered over the Best option:
Read more
  • 0
  • 0
  • 6148

article-image-aspnet-site-performance-reducing-long-wait-times
Packt
12 Oct 2010
8 min read
Save for later

ASP.NET site performance: reducing long wait times

Packt
12 Oct 2010
8 min read
Measuring wait times We can use a number of ways to find out which external requests are most frequent and how long the site has to wait for a response: Run the code in the debugger with breakpoints around each external request. This will give you a quick hint of which external request is the likely culprit. However, you wouldn't do this in a production environment, as it only gives you information for a few requests. Use the Trace class (in the namespace System.Diagnostics) to trace how long each request takes. This will give you a lot of detailed information. However, the overhead incurred by processing all the trace messages may be too high to use in a production environment, and you would have to somehow aggregate the trace data to find which requests are the most frequent and take the longest. Build performance counters into your code that record the frequency of each request and the average wait time. These counters are light-weight, and hence, can be used in a production environment. Also, you can readily access them via perfmon, along with the counters provided by ASP.NET, SQL Server, and so on that you have already come across. The remainder of this section focuses on performance counters. Also, performance counters are a convenient way to keep an eye on off-box requests on a day-to-day basis instead of as a one-off. Windows offers you 28 types of performance counters to choose from. Some of these are esoteric, others extremely useful. For example, you can measure the rate per second that a request is made, and the average time in milliseconds that the site waits for a response. Adding your own custom counters is easy, and you can see their real-time values in perfmon, along with that of the built-in counters. The runtime overhead of counters is minimal. You have already come across some of the hundreds of counters published by ASP.NET, SQL Server, and Windows itself. Even if you add a lot of counters, CPU overhead would be well under one percent. This section describes only three commonly used counters: simple number, rate per second, and time. A list of all types of counters with examples of their use is available at http://msdn.microsoft.com/en-us/library/system.diagnostics.performancecountertype.aspx?ppud=4. To use the counters, you need to follow these three steps: Create custom counters. Update them in your code. See their values in perfmon. Creating custom counters In this example, we'll put counters on a page that simply waits for one second to simulate waiting for an external resource. Windows allows you to group counters into categories. We'll create a new category "Test Counters" for the new counters. Counter NameCounter TypeDescriptionNbr Page HitsNumberOfItems6464 bit counter, counting the total number of hits on the page since the website started.Hits/secondRateOfCountsPerSecond32Hits per secondAverage WaitAverageTimer32Time taken by the resource. Inspite of the name, it is used here to simply measure an interval, not an average.Average Wait Base*AverageBaseUtility counter required by Average Wait. *The text says there are three counters, but the table lists four. Why? The last counter, Average Wait Base, doesn't provide information on its own, but helps to compute the value of counter Average Wait. Later on, we'll see how this works. There are two ways to create the "Test Counters" category and the counters themselves: Using Visual Studio: This is relatively quick, but if you want to apply the same counters to for example your development and production environments, you'll have to enter the counters separately in each environment Programmatically: Because this involves writing code, it takes a bit longer upfront, but makes it easier to apply the same counters to multiple environments and to place the counters under source control Creating counters with Visual Studio To create the counters in Visual Studio: Make sure you have administrative privileges or are a member of the Performance Monitor Users group. Open Visual Studio. Click on the Server Explorer tab. Expand Servers. Expand your machine. Right-click on Performance Counters and choose Create New Category. Enter Test Counters in the Category Name field. Click on the New button for each of the four counters to add, as listed in the table you saw earlier. Be sure to add the Average Wait Base counter right after Average Wait, to properly associate the two counters. Click on OK when you're done. This technique is easy. However, you'll need to remember to add the same counters to the production machine when you release new code with new custom counters. Writing a program to create the counters is more work initially, but gives you easier maintenance in the long run. Let's see how to do this. Creating counters programmatically From a maintenance point of view, it would be best to create the counters when the web application starts, in the Global.asax file. However, you would then have to make the account under which the application pool runs part of the Performance Monitor Users group. An alternative is to create the counters in a separate console program. An administrator can then run the program to create the counters on the server. Here is the code. using System; using System.Diagnostics; namespace CreateCounters { class Program { static void Main(string[] args) { To create a group of counters, you create each one in turn, and add them to a CounterCreationDataCollection object: CounterCreationDataCollection ccdc = new CounterCreationDataCollection(); Create the first counter, Nbr Page Hits. Give it a short help message and the counter type. Now, add it to the CounterCreationDataCollection object: CounterCreationData ccd = new CounterCreationData ("Nbr Page Hits", "Total number of page hits", PerformanceCounterType.NumberOfItems64); ccdc.Add(ccd); Add the second, third, and fourth counters along the same lines: ccd = new CounterCreationData("Hits / second", "Total number of page hits / sec", PerformanceCounterType.RateOfCountsPerSecond32); ccdc.Add(ccd); ccd = new CounterCreationData("Average Wait", "Average wait in seconds", PerformanceCounterType.AverageTimer32); ccdc.Add(ccd); ccd = new CounterCreationData("Average Wait Base", "", PerformanceCounterType.AverageBase); ccdc.Add(ccd); Now, it's time to take the CounterCreationDataCollection object and make it into a category. Because you'll get an exception when you try to create a category that already exists if there already is a category with the same name, delete it now. Because you can't add new counters to an existing category, there is no simple work-around for this: if (PerformanceCounterCategory.Exists("Test Counters")) { PerformanceCounterCategory.Delete("Test Counters"); } Finally, create the Test Counters category. Give it a short help message, and make it a single instance. You can also make a category multi-instance, which allows you to split the category into instances. Also, pass in the CounterCreationDataCollection object with all the counters. This creates the complete category with all your counters in one go, as shown in the following code: PerformanceCounterCategory.Create("Test Counters", "Counters for test site",PerformanceCounterCategoryType. SingleInstance,ccdc); } } } Now that you know how to create the counters, let's see how to update them in your code Updating counters in your code To keep things simple, this example uses the counters in a page that simply waits for a second to simulate waiting for an external resource: using System; using System.Diagnostics; public partial class _Default : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { First, increment the nbrPageHits counter. To do this, create a PerformanceCounter object, attaching it to the nbrPageHits counter in the Test Counters category. Then, increment the PerformanceCounter object: PerformanceCounter nbrPageHitsCounter = new PerformanceCounter("Test Counters", "Nbr Page Hits", false); nbrPageHitsCounter.Increment(); Now, do the same with the Hits/second counter. Because you set its type to RateOfCountsPerSecond32 when you generated it in the console program, the counter will automatically give you a rate per second when viewed in perfmon: PerformanceCounter nbrPageHitsPerSecCounter = new PerformanceCounter("Test Counters", "Hits / second", false); nbrPageHitsPerSecCounter.Increment(); To measure how long the actual operation takes, create a Stopwatch object, and start it: Stopwatch sw = new Stopwatch(); sw.Start(); Execute the simulated operation: // Simulate actual operation System.Threading.Thread.Sleep(1000); Stop the stopwatch: sw.Stop(); Update the Average Wait counter and the associated Average Wait Base counter to record the elapsed time in the stopwatch. PerformanceCounter waitTimeCounter = new PerformanceCounter("Test Counters", "Average Wait", false); waitTimeCounter.IncrementBy(sw.ElapsedTicks); PerformanceCounter waitTimeBaseCounter = new PerformanceCounter("Test Counters", "Average Wait Base", false); waitTimeBaseCounter.Increment(); } } Now that we've seen how to create and use the most commonly used counters, it's time to retrieve their values. Viewing custom counters in perfmon Accessing your custom counters goes the following way: On the server, run perfmon from the command prompt. To open the command prompt on Vista, click on Start | All Programs | Accessories | Command Prompt. This opens the monitor window. Expand Monitoring Tools and click on Performance Monitor. Click on the green "plus" sign. In the Add Counters dialog, scroll down to your new Test Counters category. Expand that category and add your new counters. Click on OK. To see the counters in action, run a load test. If you use WCAT, you could use files runwcat_testcounters.bat and testcounters_scenario.ubr from the downloaded code bundle.
Read more
  • 0
  • 2
  • 8350

article-image-importing-structure-and-data-phpmyadmin-33x-effective-mysql-management
Packt
12 Oct 2010
11 min read
Save for later

Importing Structure and Data in phpMyAdmin 3.3.x for MySQL Management

Packt
12 Oct 2010
11 min read
In general, an exported file can be imported either to the same database it came from or to any other database; the XML format is an exception to this and a workaround is given in the XML section later in this chapter. Also, a file generated from an older phpMyAdmin version should have no problem being imported by the current version, but the difference between the MySQL version at the time of export and the one at the time of import might play a bigger role regarding compatibility. It's difficult to evaluate how future MySQL releases will change the language's syntax, which could result in import challenges. The import feature can be accessed from several panels: The Import menu available from the homepage, the Database view, or the Table view The Import files menu offered inside the Query window An import file may contain the DELIMITER keyword. This enables phpMyAdmin to mimic the mysql command-line interpreter. The DELIMITER separator is used to delineate the part of the file containing a stored procedure, as these procedures can themselves contain semicolons. The default values for the Import interface are defned in $cfg['Import']. Before examining the actual import dialog, let's discuss some limits issues. Limits for the transfer When we import, the source file is usually on our client machine and therefore must travel to the server via HTTP. This transfer takes time and uses resources that may be limited in the web server's PHP configuration. Instead of using HTTP, we can upload our file to the server by using a protocol such as FTP, as described in the Reading files from a web server upload directory section. This method circumvents the web server's PHP upload limits. Time limits First, let's consider the time limit. In config.inc.php, the $cfg['ExecTimeLimit'] configuration directive assigns, by default, a maximum execution time of 300 seconds (five minutes) for any phpMyAdmin script, including the scripts that process data after the file has been uploaded. A value of 0 removes the limit, and in theory, gives us infinite time to complete the import operation. If the PHP server is running in safe mode, modifying $cfg['ExecTimeLimit'] will have no effect. This is because the limits set in php.ini or the user-related web server configuration file, (such as .htaccess or the virtual host configuration files) take precedence over this parameter. Of course, the time it effectively takes depends on two key factors: Web server load MySQL server load The time taken by the file, as it travels between the client and the server does not count as execution time because the PHP script only starts to execute after the file has been received on the server. Therefore, the $cfg['ExecTimeLimit'] parameter has an impact only on the time used to process data (like decompression or sending it to the MySQL server). Other limits The system administrator can use the php.ini file or the web server's virtual host configuration file to control uploads on the server. The upload_max_filesize parameter specifies the upper limit or maximum file size that can be uploaded via HTTP. This one is obvious, but another less obvious parameter is post_max_size. As HTTP uploading is done via the POST method, this parameter may limit our transfers. For more details about the POST method, please refer to http://en.wikipedia.org/wiki/Http#Request_methods. The memory_limit parameter is provided to prevent web server child processes from grabbing too much of the server's memory—phpMyAdmin runs inside a child process. Thus, the handling of normal file uploads, especially compressed dumps, can be compromised by giving this parameter a small value. Here, no preferred value can be recommended; the value depends on the size of uploaded data we want to handle and on the size of the physical memory. The memory limit can also be tuned via the $cfg['MemoryLimit'] parameter in config.inc.php, as seen in Chapter 6, Exporting Structure and Data (Backup). Finally, file uploads must be allowed by setting file_uploads to On; otherwise, phpMyAdmin won't even show the Location of the textfile dialog. It would be useless to display this dialog as the connection would be refused later by the PHP component of the web server. Handling big export files If the file is too big, there are ways in which we can resolve the situation. If the original data is still accessible via phpMyAdmin, we could use phpMyAdmin to generate smaller CSV export files, choosing the Dump n rows starting at record # n dialog. If this were not possible, we could use a spreadsheet program or a text editor to split the file into smaller sections. Another possibility is to use the upload directory mechanism, which accesses the directory defined in $cfg['UploadDir']. In recent phpMyAdmin versions, the Partial import feature can also solve this file size problem. By selecting the Allow interrupt... checkbox, the import process will interrupt itself if it detects that it's close to the time limit. We can also specify a number of queries to skip from the start, in case we successfully import a number of rows and wish to continue from that point. Uploading into a temporary directory On a server, a PHP security feature called open_basedir (which limits the files that can be opened by PHP to the specified directory tree) can impede the upload mechanism. In this case, or if uploads are problematic for any other reason, the $cfg['TempDir'] parameter can be set with the value of a temporary directory. This is probably a subdirectory of phpMyAdmin's main directory, into which the web server is allowed to put the uploaded file. Importing SQL files Any file containing MySQL statements can be imported via this mechanism. This format is more commonly used for backup/restore purposes. The relevant dialog is available in the Database view or the Table view, via the Import subpage, or in the Query window. There is no relation between the currently-selected table (here author) and the actual contents of the SQL file that will be importeAll of the contents of the SQL file will be imported, and it's those contents that determine which tables or databases are affected. However, if the imported file does not contain any SQL statementsto select a database, all statements in the imported file will be executed on the currently selected database. Let's try an import exercise. First, we make sure that we have a current SQL export of the book table (as explained in Chapter 6, Exporting Structure and Data (Backup)). This export file must contain the structure and the data. Then we drop the book table—yes, really! We could also simply rename it. (See Chapter 9, Performing Table and Database Operations, for the procedure.) Now it's time to import the file back. We should be on the Import subpage, where we can see the Location of the text file dialog. We just have to hit the Browse button and choose our file. phpMyAdmin is able to detect which compression method (if any) has been applied to the file. Depending on the phpMyAdmin version, and the extensions that are available in the PHP component of the web server, there is variation in the format that the program can decompress. However, to import successfully, phpMyAdmin must be informed of the character set of the file to be imported. The default value is utf8. However, if we know that the import file was created with another character set, we should specify it here. A SQL compatibility mode selector is available at import time. This mode should be adjusted to match the actual data that we are about to import, according to the type of the server where the data was previously exported. Another option, Do not use AUTO_INCREMENT for zero values, is selected by default. If we have a value of zero in a primary key and we want it to stay zero instead of being auto-incremented, we should use this option. To start the import, we click on Go. The import procedure continues and we receive a message: Import has been successfully finished, 2 queries executed. We can browse our newly-created tables to confirm the success of the import operation. The file could be imported for testing in a different database or even on another MySQL server. Importing CSV files In this section, we will examine how to import CSV files. There are two possible methods—CSV and CSV using LOAD DATA. The first method is implemented internally by phpMyAdmin and is the recommended one for its simplicity. With the second method, phpMyAdmin receives the file to be loaded and passes it to MySQL. In theory, this method should be faster. However, it has more requirements due to MySQL itself (see the Requirements subsection of the CSV using LOAD DATA section). Differences between SQL and CSV formats There are some differences between the SQL and CSV formats. The CSV file format contains data only, so we must already have an existing table in place. This table does not need to have the same structure as the original table (from which the data comes); the Column names dialog enables us to choose which columns are affected in the target table. Because the table must exist prior to the import, the CSV import dialog is available only from the Import subpage in the Table view, and not in the Database view. Exporting a test file Before trying an import, let's generate an author.csv export file from the author table. We use the default values in the CSV export options. We can then Empty the author table—we should avoid dropping this table because we still need the table structure. CSV From the author table menu, we select Import and then CSV: We can influence the behavior of the import in a number of ways. By default, importing does not modify existing data (based on primary or unique keys). However, the Replace table data with file option instructs phpMyAdmin to use the REPLACE statement instead of the INSERT statement, so that existing rows are replaced with the imported data. Using Ignore duplicate rows, INSERT IGNORE statements are generated. These cause MySQL to ignore any duplicate key problems during insertion. A duplicate key from the import file does not replace existing data, and the procedure continues for the next line of CSV data. We can also specify the character that terminates each field, the character that encloses data, and the character that escapes the enclosing character. Usually, this is. For example, for a double quote enclosing character, if the data field contains a double quote, it must be expressed as "some data " some other data". For Lines terminated by, recent versions of phpMyAdmin offer the auto choice, which should be tried first as it detects the end-of-line character automatically. We can also specify manually which characters terminate the lines. The usual choice is n for UNIX-based systems, rn for DOS or Windows systems, and r for Mac-based system (up to Mac OS 9). If in doubt, we can use a hexadecimal file editor on our client computer (not part of phpMyAdmin) to examine the exact codes. By default, phpMyAdmin expects a CSV file with the same number of fields and the same field order as the target table. However, this can be changed by entering a comma-separated list of column names in Column names, respecting the source file format. For example, let's say our source file contains only the author ID and the author name information: "1","John Smith" "2","Maria Sunshine" We'd have to put id, name in Column names in order to match the source file. When we click on Go, the import is executed and we receive a confirmation. We might also see the actual INSERT queries generated if the total size of the file is not too big. Import has been successfully finished, 2 queries executed. INSERT INTO `author` VALUES ('1', 'John Smith', '+01 445 789-1234')# 1 row(s) affected. INSERT INTO `author` VALUES ('2', 'Maria Sunshine', '333-3333')# 1 row(s) affected.
Read more
  • 0
  • 0
  • 6548

article-image-performing-table-and-database-operations-phpmyadmin-33x-effective-mysql-management
Packt
12 Oct 2010
4 min read
Save for later

Performing Table and Database Operations in phpMyAdmin 3.3.x for Effective MySQL Management

Packt
12 Oct 2010
4 min read
  Mastering phpMyAdmin 3.3.x for Effective MySQL Management A complete guide to get started with phpMyAdmin 3.3 and master its features The best introduction to phpMyAdmin available Written by the project leader of phpMyAdmin, and improved over several editions A step-by-step tutorial for manipulating data with phpMyAdmin Learn to do things with your MySQL database and phpMyAdmin that you didn't know were possible!        Introduction Various links that enable table operations have been put together on the Operations subpage of the Table view. Here is an overview of this subpage: Maintaining a table During its lifetime, a table repeatedly gets modified and is therefore continually growing and shrinking. In addition, outages may occur on the server, leaving some tables in a damaged state. Using the Operations subpage, we can perform various operations, which are listed next. However, not every operation is available for every storage engine: Check table: Scans all rows to verify that deleted links are correct. A checksum is also calculated to verify the integrity of the keys. If everything is alright, we will obtain a message stating OK or Table is already up to date; if any other message shows up, it's time to repair this table (see the third bullet). Analyze table: Analyzes and stores the key distribution; this will be used on subsequent JOIN operations to determine the order in which the tables should be joined. This operation should be performed periodically (in case data has changed in the table), in order to improve JOIN efficiency. Repair table: Repairs any corrupted data for tables in the MyISAM and ARCHIVE engines. Note that a table might be so corrupted that we cannot even go into Table view for it! In such a case, refer to the Multi-table operations section for the procedure to repair it. Optimize table: This is useful when the table contains overheads. After massive deletions of rows or length changes for VARCHAR fields, lost bytes remain in the table. phpMyAdmin warns us in various places (for example, in the Structure view) if it feels the table should be optimized. This operation reclaims unused space in the table. In the case of MySQL 5.x, the relevant tables that can be optimized use the MyISAM, InnoDB, and ARCHIVE engines. Flush table: This must be done when there have been many connection errors and the MySQL server blocks further connections. Flushing will clear some internal caches and allow normal operations to resume. Defragment table: Random insertions or deletions in an InnoDB table fragment its index. The table should be periodically defragmented for faster data retrieval. This operation causes MySQL to rebuild the table, and only applies to InnoDB. The operations are based on the available underlying MySQL queries—phpMyAdmin only calls those queries. Changing table attributes Table attributes are the various properties of a table. This section discusses the settings for some of them. Table storage engine The first attribute that we can change is called Storage Engine. This controls the whole behavior of the table—its location (on-disk or in-memory), the index structure, and whether it supports transactions and foreign keys. The drop-down list varies depending on the storage engines supported by our MySQL server. Changing a table's storage engine may be a long operation if the number of rows is large. Table comments This allows us to enter comments for the table: These comments will be shown at appropriate places—for example, in the navigation panel, next to the table name in the Table view, and in the export file. Here is what the navigation panel looks like when the $cfg['ShowTooltip'] parameter is set to its default value of TRUE: The default value (FALSE) of $cfg['ShowTooltipAliasDB'] and $cfg['ShowTooltipAliasTB'] produces the behavior we saw earlier—the true database and table names are displayed in the navigation panel and in the Database view for the Structure subpage. Comments appear when the cursor is moved over a table name. If one of these parameters is set to TRUE, the corresponding item (database names for DB and table names for TB) will be shown as a tooltip instead of the names. This time, the mouseover box shows the true name for the item. This is convenient when the real table names are not meaningful. There is another possibility for $cfg['ShowTooltipAliasTB']—the 'nested' value. Here is what happens if we use this feature: The true table name is displayed in the navigation panel The table comment (for example project__) is interpreted as the project name and is displayed as it is
Read more
  • 0
  • 0
  • 6690

article-image-installing-phpmyadmin
Packt
12 Oct 2010
10 min read
Save for later

Installing phpMyAdmin

Packt
12 Oct 2010
10 min read
  Mastering phpMyAdmin 3.3.x for Effective MySQL Management Intoduction It's time to install the product and configure it minimally for first-time use. Our reason for installing phpMyAdmin could be one of the following: Our host provider did not install a central copy Our provider installed it, but the version installed is not current We are working directly on our enterprise's web server Required information Some host providers offer an integrated web panel where we can manage accounts, including MySQL accounts, and also a file manager that can be used to upload web content. Depending on this, the mechanism that we use to transfer phpMyAdmin source files to our webspace may vary. We will need some specific information (listed below) before starting the installation: The web server's name or address: Here, we will assume it to be www.mydomain.com Our web server's account information (username, password): This information will be used for either FTP or SFTP transfer, SSH login, or web control panel login. The MySQL server's name or IP address: If this information is not available, a good alternative choice is localhost, which means that the MySQL server is located on the same machine as the web server. We will assume this to be localhost. Our MySQL server's account information (username, password). System requirements The up-to-date requirements for a specific phpMyAdmin version are always stated in the accompanying Documentation.html file. For phpMyAdmin 3.3, the minimum PHP version required is PHP 5.2 with session support and the Standard PHP Library (SPL). Moreover, the web server must have access to a MySQL server (version 5.0 or later)—either locally or on a remote machine. It is strongly recommended that the PHP mcrypt extension be present for improved performance in cookie authentication mode. In fact, on a 64-bit server, this extension is required. On the browser side, cookie support must be activated, whatever authentication mode we use. Downloading the files There are various files available in the Download section of http://www.phpmyadmin.net. There might be more than one version offered here, and it is always a good idea to download the latest stable version. We only need to download one file, which works regardless of the platform (browser, web server, MySQL, or PHP version). For version 3.3, there are two groups of files—english and all-languages. If we need only the English interface, we can download a file whose name contains "english"—for example, phpMyAdmin-3.3.2-english.zip. On the other hand, if we have the need for at least one other language, choosing all-languages would be appropriate. If we are using a server supporting only PHP4—for which the PHP team has discontinued support since December 31, 2007—the latest stable version of phpMyAdmin is not a good choice for download. I recommend using version 2.11.x, which is the latest branch that supports PHP4. The files offered have various extensions: .zip, .tar.bz2, .tar.gz, .7z. Download a file having an extension for which you have the corresponding extractor. In the Windows world, .zip is the most universal file format, although the files are bigger than .gz or .bz2 files (which are common in the Linux/Unix world). The .7z extension denotes a 7-Zip file, which is a format that achieves a higher compression ratio than the other formats offered—an extractor is available at http://www.7-zip.org. In the following examples, we will assume that the chosen file was phpMyAdmin-3.3.2-all-languages.zip. After clicking on the appropriate file, the nearest mirror site will be chosen by Sourceforge.net. The file will start to download, and we can save it on our computer. Installing on different platforms The next step depends on the platform you are using. The following sections detail the procedures for some common platforms. You may proceed directly to the relevant section. Installing on a remote server using a Windows machine Using the File explorer, we double-click the phpMyAdmin-3.3.2-all-languages.zip file that we just downloaded on the Windows machine. A file extractor will start, showing us all of the scripts and directories inside a main phpMyAdmin-3.3.2-all-languages directory. Use whatever mechanism your file extractor offers to save all the files, including subdirectories, to some location on your workstation. Here, we have chosen C:. Therefore, a C:phpMyAdmin-3.3.2-all-languages directory has been created for extraction. Now, it's time to transfer the entire directory structure C:phpMyAdmin-3.3.2-alllanguages to the web server in our webspace. We use our favorite SFTP or FTP software, or the web control panel, for the transfer. The exact directory under which we transfer phpMyAdmin may vary. It could be our public_html directory or another directory to which we usually transfer web documents. For further instructions about the exact directory to be used, or the best way to transfer the directory structure, we can consult our host provider's help desk. After the transfer is complete, these files can be removed from our Windows machine as they are no longer needed. Installing on a local Linux server Let's say we chose phpMyAdmin-3.3.2-all-languages.tar.gz and downloaded it directly to some directory on the Linux server. We move it to our web server's document root directory (for example, /var/www/html) or to one of its subdirectories (for example, /var/www/html/utilities). We then extract it by issuing the following shell command or by using any graphical file extractor that our window manager offers: tar -xzvf phpMyAdmin-3.3.2-all-languages.tar.gz We must ensure that the permissions and ownership of the directory and files are appropriate for our web server. The web server user or group must be able to read them. Installing on local Windows servers (Apache, IIS) The procedure here is similar to that described in the Installation on a remote server using a Windows machine section, except that the target directory will be under our DocumentRoot (for Apache) or our wwwroot (for IIS). Of course, we do not need to transfer anything after modifications are made to config.inc.php (described in the next section), as the directory is already on the webspace. Apache is usually run as a service. Hence, we have to ensure that the user under whom the service is running has normal read privileges to access our newly-created directory. The same principle applies to IIS, which uses the IUSR_machinename user. This user must have read access to the directory. You can adjust permissions in the Security/permissions tab of the directory's properties. Configuring phpMyAdmin Here, we will learn how to prepare and use the configuration file containing the parameters to connect to MySQL, and which can be customized as per our requirements. Before configuring, we can rename the directory phpMyAdmin-3.3.2-all-languages to something like phpMyAdmin or just something easier to remember. This way, we and our users can visit an easily-remembered URL to start phpMyAdmin. On most servers, the directory part of URLs is case-sensitive, so we should communicate the exact URL to our users. We can also use a symbolic link if our server supports this feature. The config.inc.php file This file contains valid PHP code that defines the majority of the parameters (expressed by PHP variables) that we can change in order to tune phpMyAdmin to our own needs. There are also normal PHP comments in it, and we can comment our changes. Be careful not to add any blank lines at the beginning or end of the file; doing so would hamper the execution of phpMyAdmin. Note that phpMyAdmin looks for this file in the first level directory—the same one where index.php is located. In versions before 2.8.0, a generic config.inc.php file was included in the downloaded kit. Since 2.8.0, this file is no longer present in the directory structure. Since version 2.9.0, a config.sample.inc.php file is included, and this can be copied and renamed to config.inc.php to act as a starting point. However, it is recommended that you use the web-based setup script instead, for a more comfortable configuration interface. There is another file—layout.inc.php—that contains some configuration information. Because phpMyAdmin offers theme management, this file contains the theme-specific colors and settings. There is one layout.inc.php file per theme, located in themes/themename, for example, themes/original. Avoiding false error messages about permissions on config.inc.php In its normal behavior, phpMyAdmin verifies that the permissions on this file do not allow everyone to modify it. This means that the file should not be writable to the world. Also, it displays a warning if the permissions are not correct. However, in some situations (for example, an NTFS file system mounted on a non-Windows server), the permission detection fails. In these cases, you should set the followingparameter to false: $cfg['CheckConfigurationPermissions'] = false; The following sections explain various methods for adding or changing a parameter in the config.inc.php file. Configuration principles phpMyAdmin's behavior, given that no configuration file is present, has changed in version 3.1.0. In versions 3.0 and earlier, the application used its default settings as defined in libraries/config.default.php and tried to connect to a MySQL server on localhost—the same machine where the web server is running—with user as root and no password. This is the default set-up produced by most MySQL installation procedures, even though it is not really secure. Therefore, if our freshly installed MySQL server were still to have the default root account, we would have logged on automatically and would have seen a warning given by phpMyAdmin about such lack of security. If the notion of a MySQL root user eludes you, now might be the time to browse http://dev.mysql.com/doc/refman/5.1/en/privilege-system.html, in order to learn the basics about MySQL's privilege system. Since version 3.1.0, the development team has wanted to promote a more flexible login panel. This is why, with the lack of a configuration file, phpMyAdmin displays the cookie-based login panel by default We can verify this fact by visiting http://www.mydomain.com/phpMyAdmin and substituting the appropriate values for the domain part and the directory part. If we are able to log in, it means that there is a MySQL server running on the same host as the web server (localhost) and we've just made a connection to it. However, not having created a configuration file means that we would not be able to manage other hosts via our installation of phpMyAdmin. Moreover, many advanced phpMyAdmin features (for example, query bookmarks, full relational support, column transformation, and so on) would not be activated. The cookie-based authentication method uses Blowfish encryption for storing credentials in browser cookies. If no configuration file exists, a Blowfish secret key is generated and stored in session data, which can open the door to security issues. This is why the following warning message is displayed: The configuration file now needs a secret passphrase (blowfish_secret). At this point, we have some choices: Use phpMyAdmin without a configuration file Use the web-based setup script to generate a config.inc.php file Create a config.inc.php file manually These options are presented in the following sections. We should note that even if we use the web-based setup script, we should familiarize ourselves with the config.inc.php file format, because the setup script does not cover all of the possible configuration options.
Read more
  • 0
  • 0
  • 4061
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-introducing-coldfusion-components
Packt
12 Oct 2010
15 min read
Save for later

Introducing ColdFusion Components

Packt
12 Oct 2010
15 min read
Object-Oriented Programming in ColdFusion Break free from procedural programming and learn how to optimize your applications and enhance your skills using objects and design patterns Fast-paced easy-to-follow guide introducing object-oriented programming for ColdFusion developers Enhance your applications by building structured applications utilizing basic design patterns and object-oriented principles Streamline your code base with reusable, modular objects Packed with example code and useful snippets        For those with any experience with ColdFusion, components should be relatively commonplace. Object-Oriented Programming (OOP) relies heavily on the use of ColdFusion components, so before proceeding onto the ins and outs of OOP, let's re-familiarize ourselves with components within ColdFusion. ColdFusion Components use the same ColdFusion Markup Language (CFML) as 'standard' ColdFusion pages. The core difference is the file extension—components must be saved with a .cfc file extension as opposed to the .cfm file extensions for template pages. The basic structure of a ColdFusion Component is: The component (the page within which you create the code to hold data or perform functions) The methods available to run within the CFC, also known as functions In simple terms, CFCs themselves form a framework within ColdFusion, allowing you to write structured, clear, and organized code. They make application development easier to manage, control, and maintain. ColdFusion Components use the same CFML as 'standard' ColdFusion pages. The core difference is the file extension. Why use CFCs? It is not unusual for applications to grow and seem overly complex. Pages containing detailed information, such as business logic, data access and manipulation, data validation, and layout/presentation logic, can become untidy and hard to manage. Creating and developing applications using CFCs enables you to separate the code logic from the design and presentation, and build an application based around, if not using, traditional Model View Controller (MVC) framework methodologies. Utilizing CFCs and creating a clear structured format for your code will help reduce the complexity of logic within your pages and improve the application speed. Having a clearly structured, well organized code base will make it easier to develop as an individual and share resources within a team. This is the instant benefit of CFC development. A well-written CFC will allow you to reuse your functions, or methods, across your entire application, helping to reduce the risk of code duplication. It will keep your component libraries and code base to a more easily manageable size, preventing it from becoming convoluted and difficult to follow. ColdFusion components are an incredibly powerful and valuable means of creating efficient code. They allow you to: Share properties and variables between other methods and functions Share and interact with functions contained within other CFCs Inherit the properties and methods of a base component Overwrite methods and functions within other components CFCs also give you the ability to clearly document and comment your code, letting you and other developers know what each function and property should do, what it should be expecting to receive to do the job and what output it will give you. ColdFusion components are able to read themselves and display this data to you, using a form of introspection. Although CFCs are an effective tool for code reuse, this is not to say they should be used for every reusable function within your application. They are not a complete replacement for custom tags and user-defined functions. When you load a CFC (instantiate the component), this uses up more processing time than it would to call a custom tag or a User-Defined Function (UDF) into use. Once a CFC has been instantiated, however, calling a method or function within the component will take approximately the same time as it would to call a UDF. It is important, therefore, that CFCs should not necessarily be used as a complete replacement for any UDFs or custom tags that you have in your application. Any code you write can, of course, be optimized, and changes can be made as you learn new things, but UDFs and custom tags perform perfectly well. Using them as they are will help to keep any processing overheads on your application to a minimum. Grouping your functions You may have already written custom tags and user-defined functions that allow similar functionality and reusability, for example, a series of UDFs that interact with a shopping cart. By grouping your functions within specific components according to their use and purpose, you can successfully keep your code library organized and more efficient. You can also further clean your code library by compiling or grouping multiple related components into a package, clearly named and stored in a directory within your application. Organizing your components A typical method for organizing your CFC library is to create a directory structure based on your company or domain name, followed by a directory whose name references the purpose of the included components, for example, 'com.coldfumonkeh.projecttracker' in the webroot of your application. Within this directory, you would then create a directory for each group (or package), of components, with a name reflecting or matching the component name and purpose. Use your ColdFusion Components to create a component structure, or a library, that contains grouped methods and functions, particularly if the methods share properties or data. The ColdFusion component tags You can use these following tags to create a ColdFusion Component. TagPurposecfcomponentThe core CFC tag that defines the component structure. All other content in the component is wrapped within this tag.cffunctionCreates a method (function) within the component.cfargumentCreates a parameter, otherwise known as an argument, to be sent to the function.cfpropertyCan be used to define and document the properties within your component. Can also be used to define variables within a CFC that is used as a web service. These previously mentioned tags are written within the .cfc file that defines the ColdFusion component. In the world of object-oriented programming, you will commonly hear or see reference to the word 'Class'. A class is essentially a blueprint that is used to instantiate an object, and typically contains methods and instance variables. When discussing a Class in the context of ColdFusion development, we are basically referencing a ColdFusion component, so when you see or read about classes, remember it is essentially an alias for a CFC. Our first component To get started, in this example, we will create a component and functions to output the message "Hello world". Create a new file called greetings.cfc and save it within your ColdFusion webroot. The following is a component base tag; add this code into the new CFC to define the component: <cfcomponent displayName="greetings"> </cfcomponent> Listing 1.1 – component base tags As you can see, the name attribute within the CFC matches the name of the file. The cfcomponent tags form the base structure of our ColdFusion Component. No other code can be placed outside of these tags, as it will simply display an error. It may be helpful to think of the cfcomponent tag as the wrapping paper on a parcel. It forms the outer shell of the package, holding everything else nicely in place. Defining a method We have now created the component, but at the moment it does not actually do anything. It has no function to run. We need to add a method into the CFC to create a function to call and use within our application. The following code is a basic function definition; place it between the opening and closing cfcomponent tags: <cffunction name="sayHello"> <!--- the CFML code for the method will go here ---> </cffunction> Listing 1.2 – basic function definition You have now added a method to the CFC. The cffunction tags are nested within the cfcomponent tags. We now need to add some CFML code within the cffunction tags to create our method and perform the operation. Let's create a variable within the function that will be our display message. The following code is for declaring a string variable; place it inside the cffunction tags: <cffunction name="sayHello"> <cfset var strHelloMessage = 'Hello World!' /> </cffunction> Listing 1.3 – declaring a string variable We have created a string variable containing the text to display to the browser. Returning the data To return the data we need to add an extra tag into the method. This is possible by using the cfreturn tag, which returns results from a component method. The cfreturn tag has one required attribute that is the expression or value you wish to return. Add the following code to your CFC so our method will return the welcome message and the completed component will look like this: <cfcomponent displayName="greetings"> <cffunction name="sayHello"> <cfset var strHelloMessage = 'Hello World!' /> <cfreturn strHelloMessage /> </cffunction> </cfcomponent> Listing 1.4 – returning data from the function ColdFusion 9 scripted components Since the release of ColdFusion 9, developers now have the ability to also write ColdFusion components in complete script syntax instead of pure tag form. To write the previous component in this format, the code would look as follows: component displayname="greetings" { function sayHello(){ // the CFML code for the method will go here var strHelloMessage='Hello World'; return strHelloMessage; } } Listing 1.5 – component declaration in the script syntax Although written using cfscript syntax, there is no requirement to wrap the code within <cfscript> tags, instead we can write it directly within the .cfc page. We do not even need to contain the code within cfcomponent tags, as the entire content of the component will be compiled as cfscript if left as plain text without tags. Creating your object There it is, a simple ColdFusion Component. The method is created using the cffunction tags, wrapped up nicely within the cfcomponent tags, and the value returned using the cfreturn tag. Now that we have written the function, how do we call it? In this example, we will call the component and run the method by using the createObject() function. Create a new file called hello.cfm and add the following code to the template: <cfset objGreeting = createObject('component', 'greetings') /> <cfoutput>#objGreeting.sayHello()#</cfoutput> Listing 1.6 – creating the component object In the previous code, we have created an instance of the greetings CFC, which we can reference by using the objGreeting variable. We have then accessed the sayHello() method within the component, surrounded by cfoutput tags, to display the returned data. Save the file and view it within your browser. You should now see the welcome message that we created within the method. Restricting your functions to scopes Imagine we are sending some data through to a login page in our application within the URL scope; the first and last name of a particular person. On the page, we want to join the two values and combine them into one string to form the individual's full name. We could write the code directly on the page, as follows: <cfoutput> Hello, #URL.firstName# #URL.lastName# </cfoutput> Listing 1.7 – displaying URL variables as a string Although this works, you can revise the code and transform it into a ColdFusion function to concatenate the two values into the required single string and return that value: <cffunction name="getName"> <cfset var strFullName = URL.firstName & ' ' & URL.lastName /> <cfreturn strFullName /> </cffunction> Listing 1.8 – concatenate variables into string You can then call this function within your .cfm page to output the resulting string from the function: <cfoutput> #getName()# </cfoutput> However, within this code you have restricted yourself to using only the specific URL scope. What if the first name and last name values were in the FORM scope, or pulled from a query? This block of code is useful only for values within the form scope. Using arguments within your methods To allow us to be able to pass in any parameters into the getName() function, we need to use the cfargument tag to send data into the method. By changing the function in the following code example, the method will create the concatenated string and produce the same results from two parameters or arguments that you choose to pass in. <cffunction name="getName"> <cfargument name="firstName" type="string" /> <cfargument name="lastName" type="string" /> <cfset var strFullName = arguments.firstName & ' ' & arguments.lastName /> <cfreturn strFullName /> </cffunction> Listing 1.10 – using arguments within your function The cfargument tag creates a parameter definition within the component method, and allows you to send in arguments for inclusion into the functions. The Arguments scope The Arguments scope only exists in a method. The scope contains any variables that you have passed into that method, and you can access the variables within the Arguments scope in the following ways: using structure notation - Arguments.variablename or Arguments["variablename"] using array notation - Arguments[1] The Arguments scope does not persist between calls to available CFC methods, meaning that you cannot access a value within the Arguments scope in one function from inside a different function. Redefine the function parameters By defining two arguments and sending in the values for the first and last names, you have created an unrestricted function that is not tied to a specific scope or set of hardcoded values. You can instead choose what values to pass into it on your calling page: <cfoutput> #getName('Gary', 'Brown')# </cfoutput> Listing 1.11a – sending parameters into our function Now that we have removed any restrictions to the values we pass in, and taken away any references to hardcoded variables, we can reuse this function, sending in whichever values or variables we choose to. For example, we could use variables from the FORM scope, URL scope, or query items to concatenate the string: <cfoutput> #getName(form.firstName, form.lastName)# </cfoutput> Listing 1.11b – sending parameters into our function Let's take our getName() method and add it into the greeting.cfc file. By doing so, we are grouping two methods that have a similarity in purpose into one component. This is good programming practice and will aid in creating manageable and clearly organized code. Our greeting.cfc should now look like this: <cfcomponent name="greetings"> <cffunction name="sayHello"> <cfset var strHelloMessage = 'Hello World!' /> <cfreturn strHelloMessage /> </cffunction> <cffunction name="getName"> <cfargument name="firstName" type="string" /> <cfargument name="lastName" type="string" /> <cfset var strFullName = arguments.firstName & ' ' & arguments.lastName /> <cfreturn strFullName /> </cffunction> </cfcomponent> Listing 1.12 – revised greeting.cfc Combining your methods As we have seen, you can easily access the methods within a defined CFC and output the data in a .cfm template page. You can also easily access the functionality of one method in a CFC from another method. This is particularly useful when your component definition contains grouped functions that may have a relationship based upon their common purpose. To show this, let's create a new method that will use the results from both of our existing functions within the greetings.cfc file. Instead of displaying a generic "Hello World" message, we will incorporate the returned data from the getName() method and display a personalized greeting. Create a new method within the CFC, called personalGreeting. <cffunction name="personalGreeting"> <cfargument name="firstName" type="string" /> <cfargument name="lastName" type="string" /> <cfscript> strHello = sayHello(); strFullName = getName(firstName=arguments.firstName, lastName=arguments.lastName); strHelloMessage = strHello & ' My name is ' & strFullName; </cfscript> <cfreturn strHelloMessage /> </cffunction> Listing 1.13 – personalGreeting method Within this method, we are calling our two previously defined methods. The returned value from the sayHello() method is being stored as a string variable, "strHello". We then retrieve the returned value from the getName() method and store this in a string variable "strFullName". As we have written the getName() function to accept two arguments to form the concatenated name string, we also need to add the same two arguments to the personalGreeting() method , as done in the previous code. They will then be passed through to the getName() method in exactly the same way as if we were calling that function directly. Using the two variables that now hold the returned data, we create our strHelloMessage variable, which joins the two values, and is then returned from the method using the cfreturn tag. In this method, we used CFScript instead of CFML and cfset tags, which were used in our previous functions. There is no hard and fast rule for this. You can use whichever coding method you find the most comfortable. Let's call this method on our hello.cfm template page, using the following code: <!--- instatiate the component ---> <cfset objGreeting = createObject('component', 'greetings') /> <!--- access the method and assign results to a string ---> <cfset strPersonalGreeting = objGreeting.personalGreeting( firstName="Gary", lastName="Brown") /> <cfoutput>#strPersonalGreeting#</cfoutput> Listing 1.14 – calling the personalGreeting method We are sending in the same arguments that we were passing through to the original getName() method, in the same way. This time we are passing these through using the newly created personalGreeting() method. You should now see a personalized greeting message displayed in your browser:
Read more
  • 0
  • 0
  • 3288

article-image-creating-photo-gallery-expressionengine-2
Packt
11 Oct 2010
12 min read
Save for later

Creating a Photo Gallery with ExpressionEngine 2

Packt
11 Oct 2010
12 min read
  Building Websites with ExpressionEngine 2 A step-by-step guide to ExpressionEngine: the web-publishing system used by top designers and web professionals everywhere Learn all the key concepts and terminology of ExpressionEngine: channels, templates, snippets, and more Use RSS to make your content available in news readers including Google Reader, Outlook, and Thunderbird Manage your ExpressionEngine website, including backups, restores, and version updates Written in an easy-to-follow step-by-step style, with plenty of examples and exercises         Read more about this book      (For more resources on ExpressionEngine, see here.) Designing your photo gallery There are many different ways you can approach creating a photo gallery in ExpressionEngine. At the most basic level, you have a choice between each channel entry containing only one photo (and a description) or each channel entry containing a set of photos. If you allow only one photo per entry, you can use categories to organize the photos into galleries (and you can even include the same photo in more than one gallery). If you allow multiple photos per channel entry, each entry represents a photo gallery by itself.   One way to accommodate multiple photos per entry is to create as many custom fields as the photos you think you will have in a gallery. For example, if you know each gallery will have a maximum of 20 photos, then you could create 20 custom fields for the photos and 20 custom fields for the descriptions. This solution works, but is not the most flexible (that is, to add 21 photos to a gallery, you would have to modify your custom fields and your templates). An alternative approach to accommodate multiple photos per entry without creating an abundance of custom fields is to use a third party add-on such as Matrix by Pixel & Tonic (http://pixelandtonic.com/matrix). This add-on allows for tabular data in channel entries—you define the column headings (such as the photo and the description) and then add a row in the table for each photo. In each channel entry, you can create as many rows as you need. For example, you can create one entry with 12 photos and another entry with 25 photos. Rather than creating lots of custom fields, or using a third party add-on, this article will show you a simple and elegant way to create a photo gallery using the one photo per entry design and then will use categories to organize the photos into galleries. Before you create your photo gallery channel, you first need to define where your photos will be stored. File manager The file manager is where you can upload new photos or crop, resize, rotate, or delete the images you have already uploaded, all from within the ExpressionEngine control panel. For this photo gallery, you will create a new upload destination—this is the directory on your server where ExpressionEngine will store your photos. The first step in creating a new upload destination is to create the new directory on your server. Create a new directory called photos in /images. If you are following along on an actual web server, ensure that the new directory has 777 permissions (usually right-clicking on the directory in your FTP client will allow you to set permissions).If, instead of creating a new sub-directory inside the "/images" directory, you prefer to create a new top-level directory and you are using the ".htaccess" exclude method to remove the "index.php" from ExpressionEngine URLs, then be sure to add the new directory to your ".htaccess" file. Next, you need to tell ExpressionEngine where this directory is. Inside the control panel, select Content and then File Manager. On the left-hand side of the screen, you will see the directory or directories where you can currently upload files to (if any), along with the files currently in each directory. In the toolbar on the right-hand side, underneath File Tools, select Create New Upload Destination. Enter a descriptive name of Photo Gallery. The Server Path and URL may be pre-filled, however, you should make sure it points to the actual directory you just created (/images/photos). If you are following along in a localhost environment, the URL would be http://localhost/images/photos. Leave Allowed File Types as Images only. All the fields that begin with maximum can be left blank. These fields allow you to restrict the size, height, and width of photos. If you do enter values in here, and then later try to upload a file that exceeds these limits, you will see an error message such as The file you are attempting to upload is larger than the permitted size. Set the Image Properties, Image Pre Formatting, and Image Post Formatting to be blank. These fields allow you to enter code that appears inside, before, and after the img tag. However, you will format your img tag as needed inside your template. The File Properties, File Pre, and Post Formatting can be ignored for now as they only apply to non-image files that you upload (and you have specified that you are only allowing images in your photo gallery). If desired, you can allow certain member groups to upload files. The member groups you see listed (if any) will depend on the member groups you have. Set all the member groups to Yes except Members, which should be set as No. Click Submit and your new upload destination will be ready to go. Go back to the file manager and you can see the new photo gallery upload destination with no files. Creating your photo gallery channel Now that you have created a place to store your photos, you can create your photo gallery channel. You will follow the same basic steps—creating custom fields and categories, creating your channel, publishing some entries, and then building your templates. Creating your custom fields Since you are going to have one photo per channel entry, you have a lot of flexibility to create as many custom fields for each photo as you see fit—for example, you could have fields to capture the location of the photograph, the subject of the photo, the type of camera that was used, the name of the photographer, and so forth. However, to keep things simple, you will only create two custom fields right now—one for the photo itself and one for the description. From the main menu of the control panel, select Admin, Channel Administration, and then Custom Fields. Select Create a New Channel Field Group and call the new group photos. Click Submit. Next to the new group, select Add/Edit Custom Fields and then select Create a New Custom Field. The field type will be File. The field label will be Photo and the field name will be photos_photo (the first part representing the field group name). In the field instructions, indicate that photos in the photo gallery should be no more than 600x800 pixels (so that they fit on a typical computer screen without scrolling).You could also prevent photos that are bigger than 600x800 pixels from being uploaded by specifying the maximum width and height in the File Upload Preferences for the photo gallery upload destination. You have not done this here because it would prevent you from being able to upload a larger photo and then re-sizing it using file manager. The field should be required, but not searchable, and should be shown by default. The field display order should be 1 and the file type should be Image. Click Submit. Click Create a New Custom Field again. This time, the field type should be Textarea, the field label Caption, and the field name photos_caption. The field instructions can be left blank. Answer Yes to it being a required field, being searchable and being shown by default. The Field Display Order should be 2. The number of rows can be left as 6 and the default text formatting should be set to Auto <br /> (this will prevent unwanted whitespace in your captions due to extra paragraph tags being added, but will also allow multi-line captions). Say No to allowing an override on the Publish page. The text direction can also be left as left-to-right. Finally, say Yes to Formatting Buttons, Spellcheck, and Write mode. Say No to Smileys, Glossary, and the File Chooser. Click Submit to create the new field. Now that you have your custom fields, you can define your categories. Creating your categories As discussed at the beginning of this article, you are going to use categories to distinguish between photo galleries. To start with, you are going to create two photo galleries—one for vacation photos and one for local photos. You can always come back and add more galleries later. Still in the control panel, select Admin, Channel Administration, and then Categories. Select Create a New Category Group and name it Photo Categories. Select Allow All HTML in the category field formatting and check the boxes to allow other member groups to edit (or delete) categories as appropriate. (If you see a message saying that there are no member groups allowed to edit/delete categories, this is fine too). Click Submit. Back on the Category Management screen, select Add/Edit Categories for the Photo Categories category group. Click Create a New Category. The first category will be called Local Photos. The Category URL will default to local_photos. Type in a category description (you will later display this on your website), leave the Category Image URL blank, leave the Category Parent as None, and click Submit. Select Create a New Category again. This time call the new category Vacation Photos, with a URL of vacation_photos. Type in a category description such as A selection of vacation photos taken by Ed & Eg. Leave the category image URL blank and the category parent as None. Click Submit. Now that you have your category group and custom field group defined, you can go ahead and create your channel. Creating your channel The actual creating of your channel is very straightforward. Select Admin | Channel Administration | Channels. Select Create a New Channel. Call the new channel Photos with a short name of photos. Do not duplicate an existing channel's preferences. Select Yes to Edit Group Preferences and select Photo Categories for the category group, Statuses for the status group, and photos for the field group. Select No to creating new templates and then click Submit. Your channel is created! Now you can start creating some content and displaying the photos on your website. Uploading your first photos There are three ways to upload photos to your website. Your first option is to go to File Manager (under the Content menu) and select File Upload on the right-hand toolbar. Alternatively, you can go to publish an entry in the Photos channel, click on Add File, and upload a file. Both of these options are convenient since they use the built-in ExpressionEngine file manager to upload your file—you never have to leave the control panel. However, you can only upload one photo at a time and you may run into issues if you try and upload very large photos (greater than 2 MB). The third option for uploading photos is to do so directly, using FTP, just as you would upload any files to your website. Since this requires another tool, it is less convenient than uploading a single photo from within ExpressionEngine, but if you are uploading lots of photos, then using FTP is a lot faster to do. This is the method we will use here. The built-in file manager also allows you to crop, resize, and rotate images (although you can take advantage of these tools even if you do not use file manager to upload the files).   Download the example photos (local1.jpg through local8.jpg and vacation1.jpg through vacation8.jpg) from either the Packtpub support page at http://www.packtpub.com/support or from http://www.leonardmurphy.com/book2/chapter8. (Or you can substitute your own photos). Copy or FTP the photos into the /images/photos directory that you created earlier in the article. Back in the ExpressionEngine control panel, select Content | Publish and then select the Photos channel. Type in a title of Fireworks and a caption Fireworks exploding with a bang. Then select Add File. The first screen to appear in the Upload File screen. Since you have already uploaded the files, you can simply select the photo gallery option in the left-hand menu.If no photos appear under the photo gallery, or the files appear but no thumbnails appear, try logging out of the control panel and logging back in. (This helps to refresh ExpressionEngine so it recognizes the new files—the first time you access the files after uploading via FTP, ExpressionEngine has to create the thumbnails). Select local1.jpg. On the Categories tab, select Local Photos. Then click Submit. Now, repeat the same steps to create entries for the rest of the photos, using appropriate captions that describe the photos. Be sure to select a category for each photo. There are 16 example photos (eight local and eight vacation photos). Having several example photos in each category will demonstrate how the photo gallery works better.
Read more
  • 0
  • 0
  • 5222

article-image-securing-dynamics-nav-applications
Packt
08 Oct 2010
6 min read
Save for later

Securing Dynamics NAV Applications

Packt
08 Oct 2010
6 min read
  Microsoft Dynamics NAV Administration A quick guide to install, configure, deploy, and administer Dynamics NAV with ease Install, configure, deploy and administer Dynamics NAV with ease Install Dynamics NAV Classic Client (Dynamics NAV C/SIDE), Dynamics NAV Role Tailored Client (RTC), and Dynamics NAV Classic Database Server on your computer to manage enterprise data Connect Dynamics NAV clients to the Database Server in the earlier versions and also the latest Dynamics NAV 2009 version A step-by-step guide filled with examples to help you to accomplish administrative tasks such as securing and maintaining databases using Dynamics NAV Read more about this book (For more resources on PHP & MySQL, see here.) Securing the network is indispensible to any organization's IT security. Firewalls and implementing user security policies go a long way in securing the network. A few highlights of network/hardware security that we will not cover in detail in this article are as follows: Implementing Dynamics NAV on a secure internal company network. Following Microsoft recommendations for software and hardware requirements including operating system considerations and hardware considerations. Defining user access policies and windows network access policies; these may be extendible to the Dynamics NAV security system as well. These topics can be found in detail in Microsoft operating system documentation and other network-related documentation. Security with SQL Server installation The SQL security system is very robust and comprises the following two main components: Access to the server: This is the layer of security that involves granting access to the server using logins to authenticate the users and provide them secure connection to the server. Access to the database: This refers to the security defined by roles and permissions for appropriate database access to the users. Dynamics NAV security models There are two distinctive but not-so-different security models that build the security system for Dynamics NAV. They are mainly differentiated by how they synchronize the Dynamics NAV security system with the SQL Server security system and Windows security system. In the following table, we highlight the key differences between the two security models—Standard and Enhanced. Switching between Enhanced and Standard security models To change the security model from Enhanced to Standard or vice versa, we will have to alter the database, change the Security Model option (Advanced tab). We need to make sure that the database is made as "single user only" (by checking on the Single User check mark on the Alter Database window). It is also required to synchronize all logins after the Security Model is changed. Why synchronize? Synchronization is the process for the Dynamics NAV security system to match the SQL Server security system. This does not happen automatically and must be done manually after performing the following options: Applying a change to the objects in the database Changing the security model Making changes to the users, roles, and permissions in Dynamics NAV Restoring a backup Upgrading or converting the database and/or the client executables Synchronizing one or multiple users To synchronize one or multiple users go to the Windows Login option under Tools | Security . Highlight the login(s) that need to be synchronized. Go to Tools | Security | Synchronize Single Login or Synchronize All Logins. Users, logins, and passwords Dynamics NAV application provides two types of authentication methods to log in to the database as explained next. Creating database logins These logins use database server (SQL or Classic) authentication to provide access to the application. We can create Database Logins as follows: To create a database login in a Dynamics NAV Classic database server go to Database Logins from Tools | Security | Database Logins. Press F3 to create a new User ID and Name for the Database Logins. If we are using the SQL Server as the database for Dynamics NAV installation, we have to make sure that the database logins' User ID that we are using here also exists as a user on the SQL Server. If we are using the Dynamics NAV Classic database server, we will have an additional column to specify the Password for the User ID. The first user that we create should be the SUPER user (the user with super access to everything in the application). SUPER is one of the roles in Dynamics NAV that assigns all permissions (access to all forms, tables, reports, and other objects) to the user who has been assigned that role. An Expiration Date can also be specified for the Database Logins in the last column on the right side of the Database Logins form. This Expiration Date, for example, can be used by subcontractors or short term employees who need access to Dynamics NAV application for only a given period of time. Setting up user accounts We can set up the users from the User Setup menu, in the Administration section, under Application Setup | Users. Using the User Setup screen, there is an option to control some basic features of Dynamics NAV application. We have the ability to restrict the date range of posts from Allow posting from and Allow posting to fields, these fields take precedence over the posting date range specified in the General Ledger Setup form. Users entering the system can also be restricted to particular responsibility center(s) thus allowing them to view/do transactions in that responsibility center only. There is also an option to restrict a database login to a particular company, this will be discussed in the Roles section later in this article. There is an option to register the time for the users logging on to the system. If we mark the Register Time column for a user, the system will log the User ID , Date of login, and Minutes spent on the application. This will be updated every time the user logs off from the Dynamics NAV application. How is a USER ID used across application The User ID is tagged to almost every transaction and ledger entry, and helps in providing an audit trail for transactions. Specific reports can be printed on separate printers by different users. This can be set up in the Printer Selections menu in the Administration | IT Administration | General Setup | Printer Selections. User ID(s) are also represented in the Change Log entries, if the Change Log option is enabled. For more information on Change Log option, refer to the Change Log section in this article. The creation of database logins, appropriate permissions, and so on can be done by a SUPER user or by a user who has appropriate permissions to change security for Dynamics NAV. Logging in using Windows Authentication Microsoft Windows operating system provides a robust and secure computing platform. Dynamics NAV is designed to leverage the Windows security system. The administrators have the ability to set up Windows single sign-on feature with Dynamics NAV installation. When a user opens Dynamics NAV, they have the option to select Windows Authentication. If that is selected, we don't have to key in the username and Password while logging into the application, as shown in the following screenshot:
Read more
  • 0
  • 0
  • 2682

article-image-web-controls-dotnetnuke
Packt
08 Oct 2010
7 min read
Save for later

Web Controls in DotNetNuke

Packt
08 Oct 2010
7 min read
DotNetNuke 5.4 Cookbook Over 100 recipes for installing, configuring, and customizing your own website with the DotNetNuke CMS Create and customize your own DotNetNuke website with blog, forums, newsletters, wikis and many more popular website features Learn custom module development and rich content management with sample code and tips Provides samples of styling and skinning a DotNetNuke portal Offers advanced programming tips combining DNN with AJAX and JQuery Part of Packt's Cookbook series: Each recipe is a carefully organized sequence of instructions to complete the task as efficiently as possible Read more about this book (For more resources on DotNetNuke, see here.) Introduction One of the powerful features of DNN is the variety of flexible and reusable controls that are available for custom module development. These include many of the web controls seen on the core DNN pages. In this article, we will see how to add these web controls to custom modules and tie them to the tables in the database. In general, using these controls requires four simple steps: Adding the control code to the View or Edit .ascx file Adding a new property to the info object that will supply the values for the control Binding the control to the values Capturing the value from the control and saving to the database (if Edit page) Adding web controls to your Toolbox If you frequently use the visual editor in the development tool to layout your pages, this short recipe will show you how to add the DNN web controls to the Toolbox. How to do it… Launch the Development Tool. Change the editor to Design mode. Make sure the toolbox is displayed. Right-click on the toolbox and select Choose Items…. Click on the Browse button. Navigate to the /bin folder within the DNN source (DNNSource/website/bin). Select the DotNetNuke.Webcontrols.dll and click on Open. Make sure the DNN controls are checked and click on OK. The web controls will now appear under the General section of the toolbox when you edit your code. Next, we need to add a reference to DotNetNuke.WebUtility.dll. Right-click on the Employee project in the Solution Explorer and select Add Reference…. In the pop-up dialog, click on the Browse tab and navigate to the folder holding the DNN source files (for example, My DocumentsDNNSourceWebsitebin). Select the file DotNetNuke.WebUtility.dll and click on OK. Showing an e-mail link in a Datagrid The Datagrid control is perfect for showing records from the database in a neatly formatted table. But the Datagrid can show many other types of information and in this recipe we will see how to display an e-mail hyperlink in a column. Getting ready In this recipe, we will extend the Datagrid. In this recipe we are using a function to generate an e-mail address for our example. This keeps the recipe simple, but isn't really practical. In a real production environment you would store this in the database as part of the Employee table. How to do it... Launch the Development Tool and load the Employee project. Double-click to open the ViewEmployee.ascx file. Locate the Datagrid in the code and add a new column just after the Salary column: <dnn:textcolumn datafield="Salary" headertext="Salary"/> <asp:TemplateColumn HeaderText="Email Contact"> <itemtemplate> <asp:HyperLink id="hlEmail" NavigateUrl='<%# "mailto:" & DataBinder.Eval (Container.DataItem,"ContactEmail") %>' Text='<%# DataBinder.Eval (Container.DataItem,"ContactEmail") %>' Target="_new" runat="server" /> </ItemTemplate> </asp:TemplateColumn> </Columns> </asp:datagrid> Next, open the EmployeeInfo.vb file. Find the Public Properties section and add the read-only property EmailAddress to provide an e-mail address constructed from the employee name: ' public properties Public ReadOnly Property EmailAddress() As String Get Return _EmpFirstName.Substring(0, 1) + _EmpLastName + "@yourcompany.com" End Get End Property Select Save All from the File menu. To check the results, build and deploy the module to a development portal for testing. Go to the ACME Employee page to see the list of employees. The new e-mail hyperlink will appear on the right-hand side. (Move the mouse over the image to enlarge.) How it works... In this recipe we saw the tasks to show an e-mail hyperlink in a Datagrid control: We took the Datagrid control and added a new template column holding an e-mail hyperlink control We added a new property to the EmployeeInfo object to provide an e-mail address for the Datagrid Showing checkboxes in a Datagrid An element that is useful to display in a Datagrid is a checkbox-like image to indicate the status of the database record. These are not functioning checkboxes but rather a visual indicator showing the data to be true or false. The control works by having two images, one with a checkmark that is shown when the value is true. The other is an unchecked image that is shown when the value is false. This recipe will work with any image indicating true or false. Checkbox-like images are used in other DNN modules so they are familiar to users, but you can experiment with your own images as well. This recipe has two basic steps: We will create a new property of the EmployeeInfo object called NewHire. This property checks the date of hire from the database and returns true if the employee was hired less than 30 days ago. We will add a new column to the Datagrid that evaluates the NewHire property and shows one image if the NewHire is true and another image if the NewHire is false. Getting ready In this recipe we will extend the Datagrid. How to do it... Launch the Development Tool and load the Employee project. Double-click to open the ViewEmployee.ascx file. The first step is to add a new column to the Datagrid that will show the checkbox images. We will use the Eval function to check the NewHire function. Locate the Datagrid and add a new column just after the Salary column: <dnn:textcolumn datafield="Salary" headertext="Salary"/> <asp:TemplateColumn HeaderText="New Hire"> <itemtemplate> <asp:Image Runat="server" ID="imgApproved" ImageUrl="~/images/checked.gif" Visible='<%# DataBinder.Eval (Container.DataItem,"NewHire")="1" %>'/> <asp:Image Runat="server" ID="imgNotApproved" ImageUrl="~/images/unchecked.gif" Visible='<%# DataBinder.Eval (Container.DataItem,"NewHire")="0" %>'/> </ItemTemplate> </asp:TemplateColumn> </Columns> </asp:datagrid> Next, open the EmployeeInfo.vb file. Find the Public Properties section and add the read-only property NewHire that returns true or false if the employee was hired in the last 30 days: ' public properties Public ReadOnly Property NewHire() As Boolean Get Return (Today() - _HireDate).Days < 30 End Get End Property Select Save All from the File menu. To check the results, build and deploy the module to a development portal for testing. Go to the ACME Employee page to see the list of employees. The new checkbox will appear on the right-hand side. Although you cannot click on these checkboxes, they do provide a clear and easy to understand visual status for the records. How it works... In this recipe we saw the tasks to show checkbox images in a Datagrid control: We took the Datagrid control and added a new template column holding two image controls, one checked and the other unchecked. We added a new property to the EmployeeInfo object that returns true or false depending on the database record. We bound the property to the control so that if the property was true then the checked image was displayed. If the property was false the unchecked image was displayed.  
Read more
  • 0
  • 0
  • 2362
article-image-adding-web-controls-custom-modules-dotnetnuke
Packt
08 Oct 2010
10 min read
Save for later

Adding Web Controls to Custom Modules in DotNetNuke

Packt
08 Oct 2010
10 min read
DotNetNuke 5.4 Cookbook Over 100 recipes for installing, configuring, and customizing your own website with the DotNetNuke CMS Create and customize your own DotNetNuke website with blog, forums, newsletters, wikis and many more popular website features Learn custom module development and rich content management with sample code and tips Provides samples of styling and skinning a DotNetNuke portal Offers advanced programming tips combining DNN with AJAX and JQuery Part of Packt's Cookbook series: Each recipe is a carefully organized sequence of instructions to complete the task as efficiently as possible Read more about this book (For more resources on DotNetNuke, see here.) Showing data in a Treeview A Treeview control is used when you have information arranged in a hierarchy like the organizational chart of a company. The Treeview control will show each level in the hierarchy with an icon to drill-down or expand to the next level. Getting ready To follow along with this recipe you must have completed the following recipes: Deploying a module as a standalone package Displaying a Datagrid with filter controls Adding web controls to your Toolbox The Treeview control requires that the employees in the Employee table have been assigned to managers. Here is the data that was used in this recipe: In this example, the employees are arranged in a simple two-level hierarchy. If your ManagerNo is 0 it means you are a manager. Otherwise the manager number on your record is the ItemID of your manager. So John Smith is a manager (his ManagerNo=0) and he manages Kevin Jones and Amy Roe (as their ManagerNo is John Smith's ItemID). How to do it... Launch the Development Tool and load the Employee project. In the Solution Explorer, look under the references and make sure your project includes a reference to DotNetNuke.WebUtility.dll. Double-click to open the ViewEmployee.ascx file. Start by adding a new register directive at the top of the file: <%@ Register tagprefix="DNN" assembly="DotNetNuke.WebControls" namespace="DotNetNuke.UI.WebControls" %> Next, we'll create a simple tree control by placing the following code at the bottom of the file, right after the paging control: <dnn:PagingControl ID="ctlPagingControl" runat="server"></dnn:PagingControl><br /><DNN:DnnTree ID="treeManager" runat="server" CollapsedNodeImage="~imagesplus.gif" ExpandedNodeImage="~imagesminus.gif"></DNN:DnnTree> Next, open the ViewEmployee.ascx.vb file. Look at the top of the file and make sure the following imports are there: Imports System.Data.SqlClient Imports DotNetNuke.UI.WebControls We must create a procedure to populate the tree control with records from the database. Find the Private Methods region at the top of the file and add the following new procedures: #Region "Private Methods"Private Sub PopulateTreeControl() ' set the images to use for the nodes treeManager.ImageList.Add("..imagesicon_hostusers_16px.gif") treeManager.ImageList.Add("..imagesicon_users_16px.gif") ' reset the tree control treeManager.TreeNodes.Clear() Dim objParentNode As TreeNode ' get the list of all managers and create a parent node for each one Dim objEmployeeController As New EmployeeController Dim drMgr As SqlDataReader drMgr = objEmployeeController.GetManagersDR(ModuleId) If drMgr.HasRows Then Do While drMgr.Read() objParentNode = New TreeNode() objParentNode.Text = drMgr("EmpLastName") + ", " + drMgr("EmpFirstName") objParentNode.ImageIndex = 0 ' manager image objParentNode.ClickAction = eClickAction.Expand ' when click on a manager, expand objParentNode.HasNodes = True treeManager.TreeNodes.Add(objParentNode) PopulateEmployeeNodes(objParentNode, drMgr("ItemId")) Loop End If drMgr.Close()End SubPrivate Sub PopulateEmployeeNodes(ByRef objParentNode As TreeNode, ByVal ParentItemId As Integer) Dim objChildNode As TreeNode ' get the list of all employee with the given manager Dim objEmployeeController As New EmployeeController Dim colEmployees As ArrayList Dim objEmployeeInfo As EmployeeInfo Dim TotalRecords As Integer colEmployees = objEmployeeController.GetEmployeesByFilter (ModuleId, ParentItemId, -1, 0, 1000, TotalRecords) If colEmployees.Count > 0 Then ' add a node to the parent that was passed For intEmp = 0 To colEmployees.Count - 1 objEmployeeInfo = CType(colEmployees(intEmp), EmployeeInfo) objChildNode = New TreeNode(objEmployeeInfo.EmpLastName + ", " + objEmployeeInfo.EmpFirstName) objChildNode.ImageIndex = 1 ' employee image objParentNode.TreeNodes.Add(objChildNode) Next intEmp End IfEnd Sub#End Region What we are doing here is calling a new GetManagersDR function for the first level of the tree, then calling the GetEmployeesByFilter function to get the list of employees for each manager. Next, we need to call these new procedures when the page loads, so scroll down to the Page_Load procedure and add the following code inside the IsPostBack check: If Page.IsPostBack = False Then If Not Request.QueryString("PageRecords") Is Nothing Then ddlRecordsPerPage.SelectedValue = Request.QueryString("PageRecords") End If BindManagerDropDown() BindSalaryDropDown() BindData() PopulateTreeControl()End If Next, open the EmployeeController.vb file. The last step is to create the new GetManagersDR function. This is just like the GetManagers function, but this the function returns the list of managers as a DataReader. Add the following code to the bottom of the Public Methods region: Public Function GetManagersDR(ByVal ModuleId As Integer) As SqlDataReader Return DataProvider.Instance().GetManagers(ModuleId)End Function#End Region Select Save All from the File menu. To check the results, build and deploy the module to a development portal for testing. Go to the ACME Employee page to see the list of employees in a tree control. How it works... In this recipe we saw the tasks to organize database records in a hierarchy tree control: We placed the control in the .ascx file We defined the images to use for the expand and collapse indicators In the code behind file we changed the Page_Load procedure to populate the tree We created a PopulateTreeControl procedure with two parts: Query the database for the employee managers For each manager add them to the tree and query the database for the employees they manage Using a TabStrip to separate content There are many times when you have a lot of information to display, but not enough space on the page. The TabStrip control maximizes the available space by separating the content into tabs and displaying one tab at a time. To demonstrate this control we're going to take the five fields of the Edit Employee page and split them onto two different tabs. Getting ready To follow along with this recipe you must have completed the following recipes: Adding web controls to your Toolbox Deploying a module as a standalone package How to do it... Launch the Development Tool and load the Employee project. In the Solution Explorer, look under the references and make sure your project includes a reference to DotNetNuke.WebUtility.dll. Double-click to open the EditEmployee.ascx file. Make sure the following register directive is at the top of the file: <%@ Register tagprefix="DNN" assembly="DotNetNuke.WebControls" namespace="DotNetNuke.UI.WebControls" %> We will replace the existing HTML table containing the employee fields with a TabStrip control table holding the name fields under the first tab and the information fields under the second tab. Replace the existing HTML table with the following highlighted code: <%@ Control language="vb" Inherits="ACME.Modules.Employee.EditEmployee" AutoEventWireup="false Explicit="True" Codebehind="EditEmployee.ascx.vb" %><%@ Register TagPrefix="dnn" TagName="Label" Src="~/controls/LabelControl.ascx" %><%@ Register TagPrefix="dnn" TagName="TextEditor" Src="~/controls/TextEditor.ascx"%><%@ Register TagPrefix="dnn" TagName="Audit" Src="~/controls/ModuleAuditControl.ascx" %><%@ Register tagprefix="DNN" assembly="DotNetNuke.WebControls" namespace="DotNetNuke.UI.WebControls" %> <DNN:DNNTabStrip ID="tsEmployee" runat="server" TabRenderMode="All" CssTabContainer="LoginTabGroup" CssContentContainer="LoginContainerGroup" DefaultContainerCssClass="LoginContainer" DefaultLabel-CssClass="LoginTab" DefaultLabel-CssClassHover="LoginTabHover" DefaultLabel-CssClassSelected="LoginTabSelected" visible="true" > <dnn:DNNTab Label-Text="Employee Name" ID="tab1"> <table width="650" cellspacing="0" cellpadding="0" border="0" summary="Edit Table"> <tr valign="top"> <td class="SubHead" width="125"><dnn:label id="lblEmpFirstName" runat="server" controlname="lblEmpFirstName" suffix=":"> </dnn:label> </td> <td> <asp:TextBox ID="txtEmpFirstName" runat="server"> </asp:TextBox> <asp:RequiredFieldValidator ID="valEmpFirstName" resourcekey="valEmpFirstName.ErrorMessage" ControlToValidate="txtEmpFirstName" CssClass="NormalRed" Display="Dynamic" ErrorMessage="<br>EmpFirstName is required" Runat="server" /> </td> </tr> <tr valign="top"> <td class="SubHead" width="125"><dnn:label id="lblEmpLastName" runat="server" controlname="lblEmpLastName" suffix=":"> </dnn:label> </td> <td> <asp:TextBox ID="txtEmpLastName" runat="server"> </asp:TextBox> <asp:RequiredFieldValidator ID="valEmpLastName" resourcekey="valEmpLastName.ErrorMessage" ControlToValidate="txtEmpLastName" CssClass="NormalRed" Display="Dynamic" ErrorMessage="<br>EmpLastName is required" Runat="server" /> </td> </tr> </table> </dnn:DNNTab> <dnn:DNNTab Label-Text="Information" ID="tab2"> <table width="650" cellspacing="0" cellpadding="0" border="0" summary="Edit Table"> <tr valign="top"> <td class="SubHead" width="125"><dnn:label id="lblManagerNo" runat="server" controlname="lblManagerNo" suffix=":"> </dnn:label> </td> <td> <asp:TextBox ID="txtManagerNo" runat="server"> </asp:TextBox> <asp:RequiredFieldValidator ID="valManagerNo" resourcekey="valManagerNo.ErrorMessage" ControlToValidate="txtManagerNo" CssClass="NormalRed" Display="Dynamic" ErrorMessage="<br>ManagerNo is required" Runat="server" /> </td> </tr> <tr valign="top"> <td class="SubHead" width="125"><dnn:label id="lblHireDate" runat="server" controlname="lblHireDate" suffix=":"> </dnn:label> </td> <td> <asp:TextBox ID="txtHireDate" runat="server"> </asp:TextBox> <asp:RequiredFieldValidator ID="valHireDate" resourcekey="valHireDate.ErrorMessage" ControlToValidate="txtHireDate" CssClass="NormalRed" Display="Dynamic" ErrorMessage="<br>HireDate is required" Runat="server" /> </td> </tr> <tr valign="top"> <td class="SubHead" width="125"><dnn:label id="lblSalary" runat="server" controlname="lblSalary" suffix=":"> </dnn:label> </td> <td> <asp:TextBox ID="txtSalary" runat="server"></asp:TextBox> <asp:RequiredFieldValidator ID="valSalary" resourcekey="valSalary.ErrorMessage" ControlToValidate="txtSalary" CssClass="NormalRed" Display="Dynamic" ErrorMessage="<br>Salary is required" Runat="server" /> </td> </tr> </table> </dnn:DNNTab></dnn:DNNTabStrip><br /><br /><p> <asp:linkbutton cssclass="CommandButton" id="cmdUpdate" resourcekey="cmdUpdate" runat="server" borderstyle="none" text="Update"> </asp:linkbutton>&nbsp; <asp:linkbutton cssclass="CommandButton" id="cmdCancel" resourcekey="cmdCancel" runat="server" borderstyle="none" text="Cancel" causesvalidation="False"> </asp:linkbutton>&nbsp; <asp:linkbutton cssclass="CommandButton" id="cmdDelete" resourcekey="cmdDelete" runat="server" borderstyle="none" text="Delete" causesvalidation="False"> </asp:linkbutton>&nbsp;</p><dnn:audit id="ctlAudit" runat="server" /> The appearance of the tab strip is controlled by the styles we apply to it (CssTabContainer, CssContentContainer, DefaultLabel-CssClass, DefaultLabel-CssClassHover, and DefaultLabel-CssClassSelected). In this example we used the same styles as the DNN Login page so we have a similar look and feel. The styles are defined in the /portals/_default/default.css by default. Select Save All from the File menu. To check the results, build and deploy the module to a development portal for testing. Go to the ACME Employee page and click on the edit icon (the little pencil) next to an employee to display the Edit Employee page. When you edit the employee record you will see the fields have been separated into two separate tabs. Clicking on Employee Name displays the first tab with the name fields: Clicking on Information reveals the remaining fields: How it works... In this recipe we saw the tasks to use a TabStrip control: We placed the control in the .ascx file We separated the existing content onto separate tabs  
Read more
  • 0
  • 0
  • 2096

article-image-kentico-cms-5-website-development-managing-site-structure
Packt
08 Oct 2010
6 min read
Save for later

Kentico CMS 5 Website Development: Managing Site Structure

Packt
08 Oct 2010
6 min read
  Kentico CMS 5 Website Development: Beginner's Guide A clear, hands-on guide to build websites that get the most out of Kentico CMS 5's many powerful features Create websites that meet real-life requirements using example sites built with easy-to-follow steps Learn from easy-to-use examples to build a dynamic website Learn best practices to make your site more discoverable Practice your Kentico CMS skills from organizing your content to changing the site's look and feel Get going with example starter sites such as a corporate site, an e-commerce site, and a community-driven website to jumpstart your web development Written by Thom Robbins, the Web Evangelist for Kentico Software LLC Read more about this book (For more resources on CMS, see here.) A great example of visual hierarchy that is used on every website is headings (h1, h2, h3) which indicate the importance of information and are usually styled in such a way that they guide a visitor from h1 (most important) down to least important. Without cues to the relative importance of different elements, the user has to work harder to understand the information provided by the website. A potential buyer or even someone looking for general information will quickly disregard a design with poor visual hierarchy. Z flow is a design principle that is important to keep in mind as you create layouts. The eye naturally moves across the page in a Z formation. The eye starts in the upper left, crosses over to the right, and then moves back down to the left and over to the right, similar to how the eye moves when reading text. You always want to make sure your design helps the Z-Flow. It’s important to think of your web site as a story, and organize the material in a way that enhances the telling of your story. Here are a couple of things to keep in mind. Home pages should be short and quick to loads. The home page should contain key information. This includes website introduction and links to other pages that contain additional details. Detail pages allow the website to be created in several pieces instead of one or two larger pieces. Time for action – page organization The content tree represents the site map of the website and allows you to organize the structure of documents and choose documents that appear on the right side of the screen. The content tree is where we will spend the most of our time managing content and site hierarchy. It provides the central location to see all site content (both published and unpublished). It also provides some basic drag and drop methods that will make it easier to change the location of items within your site. In this example we will look at how we can reorganize our site. Log into CMS Desk select the Content tab, select the Partners page and then the Gold partners page Drag the Gold partners page up to Services folder, as shown in the following screenshot: Release the mouse button and you will see that your page hierarchy has changed, as shown in the following screenshot: Select the Gold partners page, select the CTRL key on the keyboard and copy it to the Services hierarchy, as shown in the following screenshot: Link the Gold partners page while selecting the Control + Shift keys, as shown in the following screenshot: What just happened? Managing content within the Content tree is an essential part of maintaining your site. We have seen that there are three ways that you can maintain pages: A move takes the entire page and copies it another location in the site A copy takes a snapshot of the current deployed page and places it in the new location A link creates a copy of the page in the current location Time for action – viewing the Google sitemap file There are many different ways to provide Search Engine Optimization(SEO) for your website. The most basic is the sitemap. As the name implies it’s a map of you site. On a single page it shows the structure of your site, its sections, and the links between them. Sitemaps make navigating the site easier and having an updated sitemap is important for search engines. Sitemaps are an important way to communicate with search engines. In robots.txt you tell search engines which part of your site to exclude from indexing, in your site map you tell search engines where you you’d like them to go. Sitemaps are part of good web design practice and something you want to make sure that you are aware of. Using sitemaps offer the opportunity to inform search engines immediately about any changes in your site. Of course, you cannot expect that search engines will rush right away to index your changed pages, but certainly the changes will be indexed faster, compared to when you don’t have a sitemap. Also when you have a sitemap you can rely less on external links that will bring traffic to your site. Sitemaps also help to classify your site content. In this example, we will look at the default googlesitemap.xml file that can then be used to submit to Google. Log into Site Manager and select the Settings tab. From the Sites drop-down select (Global), select the URLs and SEO menu option, and validate the name googlesitemap.xml appears, as shown in the following screenshot: Open a new browser and use the url http://<domain>/CMSPages/googlesitemap.aspx to view the current site map, as shown in the following screenshot: What just happened? The system provides automatic support for the Google Sitemap protocol. This is a protocol designed to help search engines in indexing your site. Now that we have set up the system defaults the sitemap is created automatically based on any changes that occur with the content tree and site structure. Physically, as you can see here the sitemap is located at http://<domain>/CMSPages/Googlesitemap.aspx</domain>. When you enter your sitemap into Google you would use this URL name. XML Extension DisplayBy default IIS is configured to not display XML files for security purposed. In order to make the sitemap accessible using an XML extension you need to configure the XML extension within IIS.
Read more
  • 0
  • 0
  • 1963

article-image-kentico-cms-5-fundamentals-site-security
Packt
07 Oct 2010
4 min read
Save for later

Kentico CMS 5: Fundamentals of Site Security

Packt
07 Oct 2010
4 min read
  Kentico CMS 5 Website Development: Beginner's Guide A clear, hands-on guide to build websites that get the most out of Kentico CMS 5's many powerful features Create websites that meet real-life requirements using example sites built with easy-to-follow steps Learn from easy-to-use examples to build a dynamic website Learn best practices to make your site more discoverable Practice your Kentico CMS skills from organizing your content to changing the site's look and feel Get going with example starter sites such as a corporate site, an e-commerce site, and a community-driven website to jumpstart your web development Written by Thom Robbins, the Web Evangelist for Kentico Software LLC Read more about this book (For more resources on CMS, see here.) Fundamentals of site security I don't think anyone can dispute that security management is an essential part of our daily routine. We need to make sure that we protect customer data and guard the site from any unwanted intruders. Security management is the process that we use to decide who has access to the site, what areas they are able to see, and what documents they can view and interact with. Kentico CMS security is managed using the: Site Manager Administration tab to edit system-wide data CMS Desk Administration tab to edit data related to a specific website The security model that we use to maintain and administer the system is based on the following: Users — This is an individual user who is assigned a system account. Roles — Security groups that contain users. Because a user can belong to multiple roles, their permissions are calculated as a sum of all permissions granted to all roles they belong to. Document permissions — Document permissions are granted to both users and roles. At runtime, document permissions are calculated as a sum of all permissions granted to the user and their assigned roles. UI personalization — UI personalization is used to remove specific portions of the user interface. Don't forget! Security permissions are calculated at runtime. These are a combination of global settings and individual website settings. It's important to remember that if the user or any of their roles are denied access to a resource, they are always denied access to that resource, even if one of their roles is allowed access. Time for action – creating a new role Now, let's create a new role and assign it to a user using these steps: In CMS Site Manager, select the Administration tab, Roles, and New role, as shown in the following screenshot: What roles are there? Roles are one of the easiest ways to apply security to your users. The system contains a variety of pre-defined roles that are available in the Roles menu item, as shown in the previous screenshot. In the New role dialog, enter the following information and select OK. Select the Add users tab, as shown in the following screenshot: Select the user Joe Brown from the list and select OK, as shown in the following screenshot: Have a go hero – mapping roles As we just saw, the system contains a default set of pre-defined user roles that can be found in Site Manager, the Administration tab, and Roles. Spend some time studying the roles contained in the Site Manager Administration Roles and understand how they fit into your website security model. Once that is completed, put together a proposal that defines any additions or changes that may be needed. What just happened? When you clicked the New role button, you first identified the name of the role used across all system management areas. Once the role was created, you then added the user Joe Brown to the role. Time for action – adding a user to another role Users can belong to multiple roles within the system. Let's add our user Joe Brown to another role using the CMS Desk interface using these steps: Log in to CMS Desk as Global Administrator, select the Administration tab, click Users, and select the manage user roles icon ,as shown in the following screenshot: Select CMS Basic users, click the move right (>) button and select Close, as shown in the following screenshot: Select the edit user icon, as shown in the following screenshot: Select the General tab, uncheck the Is global administrator box, and select OK, as shown in the following screenshot: Why are we doing this? If Joe is a Global Administrator, he will automatically have access to all system resources. Select the Log in as this user link, as shown in the following screenshot: Select OK to change the user prompt, as shown in the following screenshot: Verify that you are logged in as the User: Joe Brown, as shown in the following screenshot:
Read more
  • 0
  • 0
  • 1339
article-image-kentico-cms-5-website-development-workflow-management
Packt
07 Oct 2010
3 min read
Save for later

Kentico CMS 5 Website Development: Workflow Management

Packt
07 Oct 2010
3 min read
  Kentico CMS 5 Website Development: Beginner's Guide A clear, hands-on guide to build websites that get the most out of Kentico CMS 5's many powerful features Create websites that meet real-life requirements using example sites built with easy-to-follow steps Learn from easy-to-use examples to build a dynamic website Learn best practices to make your site more discoverable Practice your Kentico CMS skills from organizing your content to changing the site's look and feel Get going with example starter sites such as a corporate site, an e-commerce site, and a community-driven website to jumpstart your web development Written by Thom Robbins, the Web Evangelist for Kentico Software LLC Read more about this book (For more resources on CMS, see here.) Workflow management Workflow is a way to automate a business process for publishing content. Using workflow allows you to delegate portions of the business process to different users or groups for approval. Kentico CMS allows you to use workflow for all documents, including uploaded files. The workflow engine organizes the process of content creation, updates, and publishing content. The following diagram shows an example document lifecycle with workflow. It's important to keep in mind that document versioning is tightly bound with workflow and allows document comparison and version rollback. Time for action – configuring workflow The Kentico CMS workflow process is designed as a state machine. This means that workflows are event driven. A workflow contains three or more states, with only one state active at any given time. Based on an event, a transition is made to another state. Once a transition is made to the final state, the workflow is completed. Within each workflow step, members of authorized roles are allowed to modify, approve, or reject a document. Now, let's configure a workflow for the News folder. In CMS Site Manager, select the Development tab, select Workflows, and click New workflow, as shown in the following screenshot: For the New workflow, enter the Display Name as Approval and Code Name as Approval, as shown in the following screenshot: Select the Steps tab and click on the New workflow step link, as shown in the following screenshot: Quick tip The Edit, Published, and Archived steps are automatically created for every workflow and can't be deleted. These steps use the default system security. Enter the following information and select OK. Select the Roles tab and click Add roles, as shown in the following screenshot: Select the CMS Desk Administrators role and select OK. Select the Scope tab and click on the New workflow scope link, as shown in the following screenshot: What is a workflow scope? The workflow scope defines the folder, documents, and languages that are included in the workflow. In the Starting alias path, click the Select button, as shown in the following screenshot: Select News and then click the Select button, as shown in the following screenshot: Select OK, as shown in the following screenshot, to save the workflow scope.
Read more
  • 0
  • 0
  • 2461

article-image-nhibernate-30-testing-using-nhibernate-profiler-and-sqlite
Packt
06 Oct 2010
6 min read
Save for later

NHibernate 3.0: Testing Using NHibernate Profiler and SQLite

Packt
06 Oct 2010
6 min read
  NHibernate 3.0 Cookbook Get solutions to common NHibernate problems to develop high-quality performance-critical data access applications Master the full range of NHibernate features Reduce hours of application development time and get better application architecture and performance Create, maintain, and update your database structure automatically with the help of NHibernate Written and tested for NHibernate 3.0 with input from the development team distilled in to easily accessible concepts and examples Part of Packt's Cookbook series: each recipe is a carefully organized sequence of instructions to complete the task as efficiently as possible Read more about this book (For more resources on NHibernate, see here.) Using NHibernate Profiler NHibernate Profiler from Hibernating Rhinos is the number one tool for analyzing and visualizing what is happening inside your NHibernate application, and for discovering issues you may have. In this recipe, I'll show you how to get up and running with NHibernate Profiler. Getting ready Download NHibernate Profiler from http://nhprof.com, and unzip it. As it is a commercial product, you will also need a license file. You may request a 30-day trial license from the NHProf website. Using our Eg.Core model, set up a new NHibernate console application with log4net. (Download code). How to do it... Add a reference to HibernatingRhinos.Profiler.Appender.dll from the NH Profiler download. In the session-factory element of App.config, set the property generate_statistics to true. Add the following code to your Main method: log4net.Config.XmlConfigurator.Configure();HibernatingRhinos.Profiler.Appender. NHibernate.NHibernateProfiler.Initialize();var nhConfig = new Configuration().Configure();var sessionFactory = nhConfig.BuildSessionFactory();using (var session = sessionFactory.OpenSession()){ var books = from b in session.Query<Book>() where b.Author == "Jason Dentler" select b; foreach (var book in books) Console.WriteLine(book.Name);} Run NHProf.exe from the NH Profiler download, and activate the license. Build and run your console application. Check the NH Profiler. It should look like the next screenshot. Notice the gray dots indicating alerts next to the Session #1 and Recent Statements. Select Session #1 from the Sessions list at the top left pane. Select the statement from the top right pane. Notice the SQL statement in the following screenshot: Click on See the 1 row(s) resulting from this statement. Enter your database connection string in the field provided, and click on OK. Close the query results window. Switch to the Alerts tab, and notice the alert: Use of implicit transaction is discouraged. Click on the Read more link for more information and suggested solutions to this particular issue. Switch to the Stack Trace tab, as shown in the next screenshot: Double-click on the NHProfTest.NHProfTest.Program.Main stack frame to jump to that location inside Visual Studio. Using the following code, wrap the foreach loop in a transaction and commit the transaction: using (var tx = session.BeginTransaction()){ foreach (var book in books) Console.WriteLine(book.Name); tx.Commit();} In NH Profiler, right-click on Sessions on the top left pane, and select Clear All Sessions. Build and run your application. Check NH Profiler for alerts. How it works... NHibernate Profiler uses a custom log4net appender to capture data about NHibernate activities inside your application and transmit that data to the NH Profiler application. Setting generate_statistics allows NHibernate to capture many key data points. These statistics are displayed in the lower, left-hand side of the pane of NHibernate Profiler. We initialize NHibernate Profiler with a call to NHibernateProfiler.Initialize(). For best results, do this when your application begins, just after you have configured log4net. There's more... NHibernate Profiler also supports offline and remote profiling, as well as command-line options for use with build scripts and continuous integration systems. In addition to NHibernate warnings and errors, NH Profiler alerts us to 12 common misuses of NHibernate, which are as follows: Transaction disposed without explicit rollback or commit: If no action is taken, transactions will rollback when disposed. However, this often indicates a missing commit rather than a desire to rollback the transaction Using a single session on multiple threads is likely a bug: A Session should only be used by one thread at a time. Sharing a session across threads is usually a bug, not an explicit design choice with proper locking. Use of implicit transaction is discouraged: Nearly all session activity should happen inside an NHibernate transaction. Excessive number of rows: In nearly all cases, this indicates a poorly designed query or bug. Large number of individual writes: This indicates a failure to batch writes, either because adonet.batch_size is not set, or possibly because an Identity-type POID generator is used, which effectively disables batching. Select N+1: This alert indicates a particular type of anti-pattern where, typically, we load and enumerate a list of parent objects, lazy-loading their children as we move through the list. Instead, we should eagerly fetch those children before enumerating the list Superfluous updates, use inverse="true": NH Profiler detected an unnecessary update statement from a bi-directional one-to-many relationship. Use inverse="true" on the many side (list, bag, set, and others) of the relationship to avoid this. Too many cache calls per session: This alert is targeted particularly at applications using a distributed (remote) second-level cache. By design, NHibernate does not batch calls to the cache, which can easily lead to hundreds of slow remote calls. It can also indicate an over reliance on the second-level cache, whether remote or local. Too many database calls per session: This usually indicates a misuse of the database, such as querying inside a loop, a select N+1 bug, or an excessive number of writes. Too many joins: A query contains a large number of joins. When executed in a batch, multiple simple queries with only a few joins often perform better than a complex query with many joins. This alert can also indicate unexpected Cartesian products. Unbounded result set: NH Profiler detected a query without a row limit. When the application is moved to production, these queries may return huge result sets, leading to catastrophic performance issues. As insurance against these issues, set a reasonable maximum on the rows returned by each query Different parameter sizes result in inefficient query plan cache usage: NH Profiler detected two identical queries with different parameter sizes. Each of these queries will create a query plan. This problem grows exponentially with the size and number of parameters used. Setting prepare_sql to true allows NHibernate to generate queries with consistent parameter sizes. See also Configuring NHibernate with App.config Configuring log4net logging
Read more
  • 0
  • 0
  • 42449
Modal Close icon
Modal Close icon