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

7019 Articles
article-image-how-recover-active-directory-failure
Packt
22 Oct 2009
19 min read
Save for later

How to Recover from an Active Directory Failure

Packt
22 Oct 2009
19 min read
Active Directory (AD) failure, which includes corruption, is something that is dreaded by any administrator. Simply put, it means that the directory service can no longer read the Active Directory database that it has locally. This will prevent logon and authentication as well as any directory-dependent services. Essentially, it renders the domain controller (DC) useless. What's worse, though, is that several times, the replication keeps going so that the corrupted database spreads out to the other DCs. In this article by Florian Rommel, we will look at the different options and approaches available to recover a DC that has a database corruption. In addition, this article outlines, symptoms, causes, and solutions for this scenario. Problems and Symptoms Let's take a look at the symptoms and then the causes. Symptoms The database gets corrupted and the DC is no longer able to process and authenticate or perform directory lookups. This becomes apparent when replication fails for some reason, or a large amount of specific event log errors appear. Another symptom could be that the AD services don't start on the DC. Causes This scenario can be caused by:      A software glitch, which can due to upgrading the schema, but having customized schema entries      An unclean AD write      A replication that has been interrupted      An accidental or malicious change in the AD schema with low level tools such as ADSIedit or something similar. Solution Process The recovery process is as follows:      You will have to verify that it is, in fact, a failure or corruption within the AD database, and not a network-related problem or other problem.      You will then have to perform a specific directory restore mode recovery, where you have to decide between an authoritative and a non-authoritative mode.      Once the recovery is complete, you will need to verify whether the DC is replicating and functioning properly. Solution Details What follows is a complete outline of what to do during each part of the solution process. Verification of Corruption If the AD on a domain controller becomes corrupted, or stops replicating to other DC's, or both, find out the root cause for this. A good starting point is to check again that the DNS is in order, and revert any manual changes that may have been made recently. Also, ensure that it is not a network-related problem—this means that no routers and routes have been changed, or firewalls re-configured, and the connection is not down. These are more often than not the main causes, and not an actual corruption. If you can safely rule out those causes, you can use utilities such as ReplMon and DCDiag, which are included in the Windows 2003 support tools, available free from Microsoft's website or on your install CD. Although ReplMon is a graphical utility, it is pretty small, and one of the best tool for checking whether or not there are replication errors within an entire domain. It shows which DCs are not replicating and why. The other utility, DCDiag, scans every DC, and determines if and why they have replication and other errors. When you have checked that all other DCs replicate just fine, you should check the Event log for specific event IDs (467 and 1018), that only occur when you have a real database corruption, and the AD jet database, which AD uses, is unreadable. Tools for Verification The Windows 2003 support tools (found on your installation CD under the SUPPORT folder) and the Windows 2003 resource kit tools (found at http://www.microsoft.com/downloads/details.aspx?FamilyID=9d467a69-57ff-4ae7-96ee-b18c4790cffd&displaylang=en ) provide a variety of tools to verify if the DC is still operational, if there is actually a problem, and where the problem lies. Although the usage of these programs can also be described as part of an AD health check, in this case, we will focus on a single DC. The output from some of these tools is fairly long, and for brevity's sake, we will focus on only the relevant parts. ReplMon ReplMon, short for Replication Monitor, is essential in your arsenal of tools for detecting replication errors within a domain. It can also provide you with a good view of replication partners for each DC, and allows you to run a check against an entire domain for replication errors. The following screenshot shows the default ReplMon window, while the next screenshot shows the right-click action menu for a monitored DC. To run ReplMon,  simply type replmon from the command line. An example of where ReplMon becomes very useful is to detect errors while trying to replicate to other DCs. There are different errors for different scenarios. but, for example, a server that cannot be reached, or is offline, would show the following error in the domain-wide search for errors: DCDiag DCDiag is a command line utility that performs a full check of the DC as regards AD. These tests include forest DNS tests, to check that the DNS is okay at the forest level, domain DNS tests, to do the same on a domain level, configuration test, schema test, and the FSMO test to check that all FSMO servers are available. Running it is as simple as typing dcdiag at the command line, and watching the output. You might want to add an output file such as dcdiag > c:dcdiag_output.txt at the end, to save everything to a text file that you can read easily. A successful DCDiag test would have the following results: NetDiag and DNSDiag Both of these utilities check the network connectivity of the DC on which they are installed. DNSDiag is more geared towards Exchange, and checks that all of the essential DNS records are valid and are working, by pretending to follow the MX records. It also gives us a lot of output with regard to the domain DNS structure, and identifies if there are any problems. NetDiag checks the local networking stack. It tests all the installed protocols and services, including WINS, NetBT, and TCP/IP. Sonar The Sonar.exe utility provides a GUI, which shows exactly where a replication failed, and what the state of the File Replication Service (FRS) is on each of the DCs. This is particularly useful for large environments. It also has different views that allow you to troubleshoot your FRS on a DC. Options to Recover and Stop the Spread of Corruption If, in effect, you have a corrupted or failed AD database, and it hasn't spread yet, meaning it is only on one DC, you should remove that DC from the replication chain as quickly as possible. A good way is, of course, to disconnect the network connection, though this will have an impact if you are working remotely on the machine. The other option is to isolate the DC with firewall rules. This is also the safest way that still gives you access to the machine remotely. If neither option is available to you, you can use the Repadmin utility to stop outbound and inbound replication. The two options are repadmin /options DCNAME +DISABLE_INBOUND_REPL and repadmin /options DCNAME +DISABLE_OUTBOUND_REPL, where DCNAME is the name of the DC that should be disabled. If you want to enable the replication, simply retype the command with a - instead of a + so as repadmin /options DCNAME -DISABLE_INBOUND_REPL. The following screenshot shows the command line for disabling outbound replication with Repadmin. Please note that when you disable outbound replication, errors with Event ID 1115 will appear in the event log, just as errors with event ID 1113 will show when inbound replication is disabled. When either one is re-enabled, informative Event IDs 1116 (outbound) and 1114 (inbound) will appear in the event log. The fastest way to recover from a corrupted AD database is to forcefully demote the DC to become a member server, and to promote it again to replicate off of another DC, if there is one in the same network. You should take this step only if you are sure, and have verified that the AD is actually working on the other DC. You can use DCDiag to easily verify whether everything is correctly order. You should not replicate from another DC within the same site if you cannot verify whether the DC is actually operational. Make sure that the event log does not contain any Jet database, or FRS errors such as 1173, which would indicate an internal error in the Jet Database. You will have to perform a metadata cleanup if you force-demote the DC because a clean demotion is not an option. If you use Dcpromo normally, it will replicate its "change" out to another DC. In other words, you are spreading the corrupted or non-functioning database this way. You can easily force-demote it by running  dcpromo /forceremoval, and then do a metadata cleanup. Non-Authoritative and Authoritative Restore To speed up the data replication of the AD, for example, for sites that have a slow or saturated network connection, or to make the whole restore process much quicker, you should perform a non-authoritative restore of the AD database. Non-authoritative restore means that you are restoring a database, but that database will not assert authority in the AD. This means that it will take all changes that the replication partners send it, where an authoritative restore is set to be the master replication in your domain. It will restore itself, and give itself such high update sequence numbers to objects that every other DC in the domain replicates from it because it is assumed it has the newest copy. Effectively, you are restoring a backup of the AD database to its original location, overwriting the current database. This can only be done when you are in Directory Restore mode. After the database is restored, reboot your DC normally. If you have changed the boot order, reverse the order again. Please make sure your backups are run regularly, whether it is on tape or on disk, according to your organization's backup policy. After the restore is complete, and you reboot the DC, the next replication will be much faster because only changed objects will be replicated to the server. This is because it has most of the AD database already, depending on how much the AD has changed, and how recent the backup was. In a non-authoritative restore, data that is restored includes AD objects with original update sequence numbers. This requires a lot of caution, as any data that is restored with a non-authoritative restore will appear to be outdated to the AD replication system. Hence, the data will not get replicated to other domain controllers. You therefore run the risk of having the data overwritten from DCs that have not yet been restored to, and contain somewhat newer data, including other corruptions. Since this article is meant for a corruption or AD failure on a single DC only, with a replication partner relatively close by, we will skip the authoritative restore. The following figure illustrates how authoritative and non-authoritative restores work. Option One: Restoring AD from a Backup In order to restore an AD database on a Domain Controller, you have to go into the "Directory Services Restore" mode. To do this, reboot the DC, and at the boot prompt, which is where the boot process waits for a second before the splash screen of Windows 2003 comes up, press the F8 key, after which you will be presented with a menu similar to the following: Windows 2003 Advanced Options MenuPlease select an option: Safe ModeSafe Mode with NetworkingSafe Mode with Command Prompt Enable Boot LoggingEnable VGA ModeLast Known Good ConfigurationDirectory Services Restore Mode (Windows NT domain controllers only)Debugging Mode Use | and | to move the highlight to your choice.Press Enter to choose. At the menu, select the Directory Services Restore Mode, by moving up and down with the arrow keys on your keyboard, and then press ENTER. You will then be in the same menu again. Press ENTER again, after which, your display will show Directory Restore Mode at the bottom of the screen. Your DC will now boot, but no AD-related services will be started. Once booted, restore the AD/system state from a trusted and recent backup, and reboot the machine. After the machine is rebooted, you should have working AD services with a slightly outdated AD database. Wait for the replication to take effect, and your AD will be updated. No Physical Access to the Machine If you do not have physical access to the machine in question, you can achieve the same effect by editing the boot.ini file, which is located in c:. This file, bydefault, is hidden and may be write-protected. To see the hidden files and system files, you will need to change your Windows Explorer settings, as shown in the following screenshot. When you can see the file, check its properties, that is, whether it is read-only or not, by right-clicking on it and selecting Properties. However, instead of changing file permissions of system files, you can edit this quite easily with the Graphical User Interface. Some people are not comfortable editing protected files, and then you can also run into problems if you forget to un-mark or re-mark the read-only flag. To get to the GUI editor, right-click on My Computer in your Start menu, or click the icon with the server name in the right hand upper-right, and then select Properties. Once you have done this, the following screen will appear: On the properties window, go to the Advanced tab, as shown in the following screenshot: And then click on Settings in the Startup and Recovery section of the  Advanced tab, as shown in the screenshot below: In the resulting window, which contains quite a few options and sections, you can click on the  Edit button and the boot.ini file will be opened in Notepad. Once editing is completed, and the file has been saved and closed, all permissions will be reset to their original settings. The editing of this file is pretty straightforward, yet not easily understandable for someone who has never done this. In the following screenshot, you can see the actual file displayed: To edit the file in order to reboot in Directory Restore Mode, it is recommended to just copy and paste the last line again, and perform two changes:      Change the display name by adding something like Recovery.      Add the /safeboot:dsrepair at the end of the line, as shown in the following screenshot: When editing is done, save and close the file as you would with any other text file, and click  OK in the Startup and Recovery window so that it closes. To select the option on which you want to boot, click SETTINGS in the  Startup and Recovery section again. And As you can see in the following screenshot, you can now select the boot default from the drop-down menu in the opening window: Select the Recovery line and click OK. Then click OK again to reboot the server. It will now boot automatically into the Directory Restore Mode. Restoring from a Backup Once you are in Directory Restore Mode (DRM), you can use your company's backup software to recover the AD database. If you use Windows backup, you can safely backup and restore the system state of the server, as you can see in the following screenshot. This will allow you to fully revert to a completely working system. However, if you do not need to, or do not want to, recover the whole system state, you can easily choose to restore only AD from the list, as shown in the following screenshot. We assume that we have a complete backup of the server, and that we need to restore the AD database. You can restore the AD or system state to a different location, or overwrite the original files, depending on whether you want to perform an authoritative or a non-authoritative restore, or even an install from media. Option Two: Replication In case you have no valid recent backup media from which to restore the AD, or you need to act very fast, you can restore the AD by first force-demoting the DC in question with dcpromo /forceremoval. This way, demoting will prevent replication to any replication partners, but will successfully demote the DC from the domain. If you have any important Flexible Server Master Operations (FSMO) roles running on the DC that you are removing by force, you will be presented with the following warning: Make sure that you seize the FSMO roles after you have demoted the DC, or after you disconnect its network cable. Do not forget this though, as the FSMO roles are quite important. As you can see in the following screenshot, the Active Directory wizard will now proceed to remove AD without updating the forest. This means that it will not replicate out its own data or changes. Once demoted, reboot the server, and remove its leftover information from AD as a DC. Then, verify whether the network connection is fully functional, and promote the DC again with the same name. You should encounter no problems in completing the promotion. The AD will replicate to it during the next scheduled replication. If your AD is very large and contains many records or files, such as pictures in the user information, the replication to a "blank" DC will take a long time and stress your network quite heavily. The replication option in a larger environment with a large dataset can take along time if the other DC is either busy, or the replication link is not a very high-speed connection. The size of the AD databases can start from 1 GB and may run up to several gigabytes. If your DC has to replicate from a DC over a leased line, or an average consumer Internet class connection (2 to 8mbit), you may have to consider the other option of  restoring from a backup, or performing a non-authoritative restore. Option Three: Rebuild DC with Install from Media Starting from Windows 2000 SP3, there is a dcpromo option available called "IFM" (install from media). This option adds a step to the DC promotion that will pre-populate the AD database on the promoted DC from a recent system state backup of a working DC, which is restored to a disk, CD or DVD. IFM is the fastest option if you have to install, recover, or re-install a DC that is connected by only a slow link to its closest replication partner. As you are pre-populating the local AD, the replication changes it will get from its partner are much smaller, and therefore will replicate much faster. To use IFM, restore the backup to the server BEFORE you make it a DC, and before you run dcpromo. A good way to do this, if you want to, or need to, restore several DCs with IFM, is to restore it to a network drive.. To prepare a backup and restore for IFM, please see Microsoft's Knowledge base article http://support.microsoft.com/kb/311078 IFM can only be used for additional DCs within a domain, not for the first DC. You can also only pre-populate, or restore a DC with a backup of the domain that you are building in. A good option for this is to force-demote the DC, reboot it, and start it as a normal member server. You then need to clean up all of the records from the AD regarding the DC, and then perform an install from Media. Restore the most recent backup to a separate directory, for example, c:restore. This restore should be a restore of the System State of a DC, and the directory will contain sub-directories such as AD, Boot Files, Registry and so on. Once the restore has succeeded, click on Start, Run, and enter dcpromo /adv as shown: The /adv flag in the Dcpromo command gives you advanced options within Dcpromo, such as the install from media options. Follow the dialog as you would normally do for a dcpromo. However, when you see the screen regarding Copying Domain Information, select the option:  From these restored backup files, and navigate to and select the directory to which you restored the system state. As you can see in this screenshot, you also have the option to pre-populate immediately from an existing DC. This is, of course, an option, but if your link is slow, or if your replication partner is busy serving other partners, it will be much slower than from media. Not just for disaster recovery! If you have to install several DCs for any reason, the /adv switch can save you the time spent waiting for the first replication, if you have a fast link, or a backup, that you can use to pre-populate. When following the wizard, you will be asked if you want to make this DC a Global Catalog, and then you may be required to use an account with Administrator privileges in order to proceed with the dcpromo. Once the Dcpromo wizard completes its task, and the AD records are copied from a previous backup, at the next replication only the changes since the last backup will be replicated. This saves a lot of bandwidth and time. This is especially useful for sites with a slow or saturated network connection, where replication would take far too long, so if you need to recover or install fast, this is probably your best bet. Summary In this article, we looked at the recovery procedure in the event of a corruption or failure of the AD database on a single domain controller. This is a scenario that happens more frequently than one might expect. So, instead of "just re-installing", these options and procedures will help you get a healthy DC back in no time while limiting the amount of errors in the event log. We also looked at some tools that will help you not only diagnose AD problems, but also allow you to perform, when used regularly, AD health tests to make sure your AD is always in perfect working order. This way, you might prevent failures because you might find the symptoms earlier.  
Read more
  • 0
  • 0
  • 17690

article-image-php-data-objects-error-handling
Packt
22 Oct 2009
11 min read
Save for later

PHP Data Objects: Error Handling

Packt
22 Oct 2009
11 min read
In this article, we will extend our application so that we can edit existing records as well as add new records. As we will deal with user input supplied via web forms, we have to take care of its validation. Also, we may add error handling so that we can react to non-standard situations and present the user with a friendly message. Before we proceed, let's briefly examine the sources of errors mentioned above and see what error handling strategy should be applied in each case. Our error handling strategy will use exceptions, so you should be familiar with them. If you are not, you can refer to Appendix A, which will introduce you to the new object-oriented features of PHP5. We have consciously chosen to use exceptions, even though PDO can be instructed not to use them, because there is one situation where they cannot be avoided. The PDO constructors always throw an exception when the database object cannot be created, so we may as well use exceptions as our main error‑trapping method throughout the code. Sources of Errors To create an error handling strategy, we should first analyze where errors can happen. Errors can happen on every call to the database, and although this is rather unlikely, we will look at this scenario. But before doing so, let's check each of the possible error sources and define a strategy for dealing with them. This can happen on a really busy server, which cannot handle any more incoming connections. For example, there may be a lengthy update running in the background. The outcome is that we are unable to get any data from the database, so we should do the following. If the PDO constructor fails, we present a page displaying a message, which says that the user's request could not be fulfilled at this time and that they should try again later. Of course, we should also log this error because it may require immediate attention. (A good idea would be emailing the database administrator about the error.) The problem with this error is that, while it usually manifests itself before a connection is established with the database (in a call to PDO constructor), there is a small risk that it can happen after the connection has been established (on a call to a method of the PDO or PDO Statement object when the database server is being shutdown). In this case, our reaction will be the same—present the user with an error message asking them to try again later. Improper Configuration of the Application This error can only occur when we move the application across servers where database access details differ; this may be when we are uploading from a development server to production server, where database setups differ. This is not an error that can happen during normal execution of the application, but care should be taken while uploading as this may interrupt the site's operation. If this error occurs, we can display another error message like: "This site is under maintenance". In this scenario, the site maintainer should react immediately, as without correcting, the connection string the application cannot normally operate. Improper Validation of User Input This is an error which is closely related to SQL injection vulnerability. Every developer of database-driven applications must undertake proper measures to validate and filter all user inputs. This error may lead to two major consequences: Either the query will fail due to malformed SQL (so that nothing particularly bad happens), or an SQL injection may occur and application security may be compromised. While their consequences differ, both these problems can be prevented in the same way. Let's consider the following scenario. We accept some numeric value from a form and insert it into the database. To keep our example simple, assume that we want to update a book's year of publication. To achieve this, we can create a form that has two fields: A hidden field containing the book's ID, and a text field to enter the year. We will skip implementation details here, and see how using a poorly designed script to process this form could lead to errors and put the whole system at risk. The form processing script will examine two request variables:$_REQUEST['book'], which holds the book's ID and $_REQUEST['year'], which holds the year of publication. If there is no validation of these values, the final code will look similar to this: $book = $_REQUEST['book'];$year = $_REQUEST['year'];$sql = "UPDATE books SET year=$year WHERE id=$book";$conn->query($sql); Let's see what happens if the user leaves the book field empty. The final SQL would then look like: UPDATE books SET year= WHERE id=1; This SQL is malformed and will lead to a syntax error. Therefore, we should ensure that both variables are holding numeric values. If they don't, we should redisplay the form with an error message. Now, let's see how an attacker might exploit this to delete the contents of the entire table. To achieve this, they could just enter the following into the year field: 2007; DELETE FROM books; This turns a single query into three queries: UPDATE books SET year=2007; DELETE FROM books; WHERE book=1; Of course, the third query is malformed, but the first and second will execute, and the database server will report an error. To counter this problem, we could use simple validation to ensure that the year field contains four digits. However, if we have text fields, which can contain arbitrary characters, the field's values must be escaped prior to creating the SQL. Inserting a Record with a Duplicate Primary Key or Unique Index Value This problem may happen when the application is inserting a record with duplicate values for the primary key or a unique index. For example, in our database of authors and books, we might want to prevent the user from entering the same book twice by mistake. To do this, we can create a unique index of the ISBN column of the books table. As every book has a unique ISBN, any attempt to insert the same ISBN will generate an error. We can trap this error and react accordingly, by displaying an error message asking the user to correct the ISBN or cancel its addition. Syntax Errors in SQL Statements This error may occur if we haven't properly tested the application. A good application must not contain these errors, and it is the responsibility of the development team to test every possible situation and check that every SQL statement performs without syntax errors. If this type of an error occurs, then we trap it with exceptions and display a fatal error message. The developers must correct the situation at once. Now that we have learned a bit about possible sources of errors, let's examine how PDO handles errors. Types of Error Handling in PDO By default, PDO uses the silent error handling mode. This means that any error that arises when calling methods of the PDO or PDOStatement classes go unreported. With this mode, one would have to call PDO::errorInfo(), PDO::errorCode(), PDOStatement::errorInfo(), or PDOStatement::errorCode(), every time an error occurred to see if it really did occur. Note that this mode is similar to traditional database access—usually, the code calls mysql_errno(),and mysql_error() (or equivalent functions for other database systems) after calling functions that could cause an error, after connecting to a database and after issuing a query. Another mode is the warning mode. Here, PDO will act identical to the traditional database access. Any error that happens during communication with the database would raise an E_WARNING error. Depending on the configuration, an error message could be displayed or logged into a file. Finally, PDO introduces a modern way of handling database connection errors—by using exceptions. Every failed call to any of the PDO or PDOStatement methods will throw an exception. As we have previously noted, PDO uses the silent mode, by default. To switch to a desired error handling mode, we have to specify it by calling PDO::setAttribute() method. Each of the error handling modes is specified by the following constants, which are defined in the PDO class: PDO::ERRMODE_SILENT – the silent strategy. PDO::ERRMODE_WARNING – the warning strategy. PDO::ERRMODE_EXCEPTION – use exceptions. To set the desired error handling mode, we have to set the PDO::ATTR_ERRMODE attribute in the following way: $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); To see how PDO throws an exception, edit the common.inc.php file by adding the above statement after the line #46. If you want to test what will happen when PDO throws an exception, change the connection string to specify a nonexistent database. Now point your browser to the books listing page. You should see an output similar to: This is PHP's default reaction to uncaught exceptions—they are regarded as fatal errors and program execution stops. The error message reveals the class of the exception, PDOException, the error description, and some debug information, including name and line number of the statement that threw the exception. Note that if you want to test SQLite, specifying a non-existent database may not work as the database will get created if it does not exist already. To see that it does work for SQLite, change the $connStr variable on line 10 so that there is an illegal character in the database name: $connStr = 'sqlite:/path/to/pdo*.db'; Refresh your browser and you should see something like this: As you can see, a message similar to the previous example is displayed, specifying the cause and the location of the error in the source code. Defining an Error Handling Function If we know that a certain statement or block of code can throw an exception, we should wrap that code within the try…catch block to prevent the default error message being displayed and present a user-friendly error page. But before we proceed, let's create a function that will render an error message and exit the application. As we will be calling it from different script files, the best place for this function is, of course, the common.inc.php file. Our function, called showError(), will do the following: Render a heading saying "Error". Render the error message. We will escape the text with the htmlspecialchars() function and process it with the nl2br() function so that we can display multi-line messages. (This function will convert all line break characters to tags.) Call the showFooter() function to close the opening and tags. The function will assume that the application has already called the showHeader() function. (Otherwise, we will end up with broken HTML.) We will also have to modify the block that creates the connection object in common.inc.php to catch the possible exception. With all these changes, the new version of common.inc.php will look like this: <?php/*** This is a common include file* PDO Library Management example application* @author Dennis Popel*/// DB connection string and username/password$connStr = 'mysql:host=localhost;dbname=pdo';$user = 'root';$pass = 'root';/*** This function will render the header on every page,* including the opening html tag,* the head section and the opening body tag.* It should be called before any output of the/*** This function will 'close' the body and html* tags opened by the showHeader() function*/function showFooter(){?></body></html><?php}/*** This function will display an error message, call the* showFooter() function and terminate the application* @param string $message the error message*/function showError($message){echo "<h2>Error</h2>";echo nl2br(htmlspecialchars($message));showFooter();exit();}// Create the connection objecttry{$conn = new PDO($connStr, $user, $pass);$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);}catch(PDOException $e){showHeader('Error');showError("Sorry, an error has occurred. Please try your requestlatern" . $e->getMessage());} As you can see, the newly created function is pretty straightforward. The more interesting part is the try…catch block that we use to trap the exception. Now with these modifications we can test how a real exception will get processed. To do that, make sure your connection string is wrong (so that it specifies wrong databasename for MySQL or contains invalid file name for SQLite). Point your browser to books.php and you should see the following window:
Read more
  • 0
  • 0
  • 6809

article-image-social-bookmarking-mediawiki
Packt
21 Oct 2009
4 min read
Save for later

Social Bookmarking - MediaWiki

Packt
21 Oct 2009
4 min read
Traditionally, bookmarking was done through Internet browsing software, such as Internet Explorer, Safari, Firefox, or Opera. With social bookmarking, your bookmarks are not confined to one browser, but are stored online. The following two options are available for enabling social bookmarking on your website: Link to each individual social bookmarking service that you wish to use Use a social bookmarking aggregator such as Socializer or AddThis Even if you do not have links to allow visitors to bookmark your website, many services allow their users to install toolbars in their browser, which allows your website to be added anyway. Adding these links will help to spread your wiki and its new skin very fast. Individual Social Bookmarking Services There are huge numbers of social bookmarking services on the Internet, and quite a number of these have become reasonably popular. We will look at some of the more popular bookmarking services such as: Mister Wong Furl Facebook Your Wiki's Audience One thing to consider before adding social bookmarking service links to your wiki is your audience. For instance, if your wiki is technology-related, you may find it better to use Digg than Facebook, as Digg is more popular than Facebook for your wiki's intended audience. If your wiki's visitors are primarily from Germany, you may find Mister Wong more useful than Furl, because Mister Wong is more popular with the German users. There are many other social bookmarking services available, including Del.icio.us (http://del.icio.us) and StumbleUpon (http://stumbleupon.com), which you can use after asking your wiki's visitors by means of a poll, or following simple experimentation. Example of Audience durhamStudent (http://durhamStudent.co.uk) is a niche website aimed at students of Durham University in the UK: The durhamStudent website uses both the methods of social bookmarking discussed earlier, providing links for eKstreme's Socializer and a link to an individual bookmarking service, Facebook: Facebook was linked individually here because it is incredibly popular among the students at Durham University (indeed, the Durham network is only open to those with a university email address). Although Facebook's bookmarking service is accessible through Socializer, it is also linked separately as the website's target audience is more likely to use that service than any other. Mister Wong Mister Wong, http://www.mister-wong.com, is popular with German and other European users (though not so much in Great Britain), and allows the users to store their bookmarks while maintaining their privacy, with the ability to set bookmarks as "public" or "private". Generally, the social bookmarking services ask for two pieces of information when creating a link from your website to them: the URL (address) of the page or website you want to add, and the title of that page or website, as you wish it to be posted. Linking to Mister Wong To link to Mister Wong, create a link where you want your social bookmark to be shown in your MediaWiki template in the following format: http://www.mister-wong.com/index.php?action=addurl&bm_url=www.example. com &bm_description=Your+Website Spaces are automatically escaped with a "+" sign by the majority of social bookmarking services. You don't have to worry about properly escaping spaces in the title of your link when linking to bookmarking services. To use these services with MediaWiki, we will be required to use some PHP. In particular, we will need the following: The page's title, which we can get with <?php $this->text('pagetitle') ?>. The website's address, retrievable with <?php $this->urlencode('serverurl') ?>. For simplicity, we will assume that our visitors will always want to bookmark JazzMeet's homepage, http://www.jazzmeet.com. Thus, the code in our MediaWiki template would appear as follows: <a href= "http://www.mister-wong.com/index.php?action=addurl&bm_url=www.jazzmeet.com &bm_description=JazzMeet" title="Bookmark JazzMeet with Mister Wong">Bookmark JazzMeet with Mister Wong</a> What Mister Wong Users See If a visitor to your wiki decides to bookmark your wiki with Mister Wong, they will be greeted with a screen similar to the following, with fields for the address of the website (URL), title, related keywords ("tags"), and a comment about the website: They are also given the option to bookmark as either "public", allowing other Mister Wong users to see it, or "private", which restricts the bookmarked website to their account only.
Read more
  • 0
  • 0
  • 2078

article-image-customizing-plugins-joomla-15x-part-1
Packt
21 Oct 2009
9 min read
Save for later

Customizing Plugins in Joomla! 1.5x (Part 1)

Packt
21 Oct 2009
9 min read
The code used in this article can be downloaded from here. Plugin composition and operation     Like a module, in its simplest form, a plugin can consist of only two files, a PHP file with the actual code for the plugin, and an XML manifest that tells Joomla! what to do with the plugin. Despite this apparent simplicity, plugins are very powerful, and more difficult to understand than modules and components. Plugins are designed to run at certain times during the execution of our site, and they perform actions that can only be done at these times. For example, in our sample site we want to hide some of our content from guests, and only show it to paid subscribers. This action can only be performed when we are actually preparing the content to be displayed, because we need to wait until we identify if the viewer is a guest or subscriber, and then make the changes to the content dynamically. In a different example, checking if a subscriber's subscription is valid is something that only needs to be done when they try to login, and not on every page load. Plugin types Plugins are divided into eight types, as follows: Authentication Content Editors Editors-XTD Search System User XML-RPC Authentication Authentication plugins are designed to allow the site to check the user's authentication against a variety of sources. The default is to check the user's authentication against a username and password stored in the Joomla! database, which, as of Joomla! 1.5, will be the username and password fields in the #__user table (#__ is the table prefix we chose when setting up Joomla!). However, any source with a public API can be used to verify someone's authentication details. Common uses are LDAP, OpenID, a Google account, a subscription, community component, and more. On our site, for example, we are already using an authentication plugin to verify the subscriptions of users when they attempt to login. Content Possibly the most commonly used of all plugins, content plugins allow content items to be modified or have additional features added to them. We could, for example, use content plugins to cloak email addresses, embed audio or video into our pages, or do text replacements. We can even embed components and modules into our pages via plugins. We will later look at a content plugin that we will use to hide and show content depending on a user's subscription. Editors Editors plugins add WYSIWYG editors that we can use when editing our content. We installed JCE on our site earlier, which is the most popular Joomla! editor plugin as of this publication according to Joomla.org. Editors-XTD Editors-XTD (extended) plugins allow us to add additional buttons to the editors. The Image, Read more, and Pagebreak buttons on the default Joomla! WYSIWYG editor, for example, are actually plugins. Search Search plugins allow us to search through the data from different components. By default, Joomla! comes with plugins that search through content articles and the Contacts and Weblinks components. These can be expanded upon by creating or installing search plugins for other extensions. System System plugins are arguably the most powerful and most flexible types of plugins for Joomla!, as they can execute at several different pre-defined points during the execution of a Joomla! page plugin. They can be used to perform a vast array of functions, such as loading extra scripts or CSS into the header of a web page, redirecting people away from pages, logging statistics, and more. User User plugins allow us to perform actions at different times with respect to users. Such times include logging in and out, and also when saving changes to a user's profile. User plugins are often used to create a "bridge" between Joomla! and other web applications (such as the phpBB forum or the osCommerce e-commerce platform.). XML-RPC XML-RPC plugins are for communicating between our Joomla! site and other external applications, such as a desktop application or a different web site. Plugin events As a Joomla! site loads a page, it steps through a series of events as part of that process. The events it steps through are determined by the type of page it is loading. Plugins are always tied to one or more of these events, and are executed during those events as required. When loading a page of content, for example, we would step through a mix of the system and some of the content events. When loading the same page for editing, we will step through the system events, different content events, and also possibly editor events. The events triggered in Joomla! are: Authentication onAuthenticate Content onPrepareContent onAfterDisplayTitle onBeforeDisplayContent onBeforeContentSave onAfterContentSave Editors onInit onGetContent onSetContent onSave onDisplay onGetInsertMethod Editors XTD (Extended) onDisplay Search onSearch onSearchAreas System onAfterInitialise onAfterRoute onAfterDispatch onAfterRender User onLoginUsexr onLoginFailure onLogoutUser onLogoutFailure onBeforeStoreUser onAfterStoreUser onBeforeDeleteUser onAfterDeleteUser XML-RPC onGetWebServices Most of these events are easy to understand from their name, but just in case, more information can be found on the Joomla! documentation wiki at http://docs.joomla.org/CategoryPlugins. Some events are only activated at specific times, such as onAuthenticate, which is only activated when someone logs into their account. Others are activated on every page load. Content events are activated on all content pages and only on content pages, not on pages with components other than com_content. Content plugins are also only executed on the main body content itself and don't have access to the template or other module data. So a text replacement content plugin, for example, wouldn't change any text in modules or the template, only in the main content itself. It is actually possible for modules and components to manually activate plugin events with clever programming, but this is not the default Joomla! behavior. It is usually done when a developer wants to apply content plugin restrictions/changes to a module. Plugin order Aside from the events and types, there is a third important factor to consider when setting up our plugins. That is the order in which the plugins of a particular type are executed. This order is best observed on the Plugin Manager screen that can be found under the Extensions menu. The order in which the plugins execute is something not many people think about, but is really quite powerful and useful. This is because the plugins which execute later, can then use the output or effects of the earlier executing plugins as input. For example, imagine we have a plugin that displays different text for different user types, and we have another plugin that reads certain text values and replaces them with embedded video or audio. If we wanted to be able to show different videos to different groups, then we could use the first plugin to generate the different command strings for the second plugin, and have it generate them based on the user type. The second plugin, our media embedding plugin, doesn't even know that the first plugin exists. All it knows is which videos it needs to display based on what is in the content item. If the media plugin executes first, then it will generate both videos regardless of the user type. As another example, imagine we have some sort of external application and we log users into it after they authenticate via an authentication plugin. We need to make sure that this plugin is executed after all of our other authentication plugins that may check a user's credentials or account status. Otherwise, someone may get logged into our external application even though they were prevented from login into our Joomla! site. So a hacker, for example, could get access to our external application without needing to even successfully get into our main site. This was all because we had the order of our plugins wrong. So when we install and activate plugins, it is well worth taking the time to double check that everything happens in the order it is meant to be in. If one of our plugins is not behaving how it should, it might be worth checking the order to see if another plugin is conflicting with it. Customizing a Plugin Now that we have a better understanding of how our plugins work and fit together, we are going to try our hand at customizing one for our site. This will hopefully give us the understanding and confidence to make any other customizations we need in the future. As with modules, it is often easier to find a plugin that does most of what we want it to do and then make changes to it so that it meets our needs more completely. Looking back over our goals, one that requires a plugin is that we want to limit access to certain parts of our content to only our paying subscribers. This effect is going to be best achieved via content plugin, so we chose the Ninja Access plugin to fill this need. To use Ninja Access we first need to mark the content we want to restrict with special tags and indicate the user groups we want to see what is contained within the tags. When the page is produced, the plugin reads the visitor's user group and then compares it to the ones in the list provided by the tag. If the user groups match, then the content is displayed, if not, then it is hidden. For example: {njaccess 0}shows only to guest users{/njaccess}{njaccess 18,19,20,21,23,24,25}shows to all users who are not a guest{/njaccess} The numbers in the examples above indicate the default Joomla! user group ids. The most important ones are: 0 = Guests 18 = Registered 24 = Administrators 25 = Super Administrators We could use this as it is, but as we don't have a component installed to create new access groups, it won't be very flexible. We could get into trouble in the future if we decide to let people register without getting a subscription, or create a free subscription. In this instance, we will have paying and free subscribers all in the number 18 user group. Also, as we are always going to be restricting the same groups, we don't really need to type the parameters in every single time. Making our plugins always restrict the same groups automatically will save us some time and reduce mistakes. Lastly, do we really need to type njaccess every time? Let's shorten it to something like soc—subscriber only content. For our first dilemma, a better idea than groups might be to associate the access to certain AEC subscriptions that are currently active. That way if people's subscriptions expire, or they get a free account, the content is still properly controlled regardless of their user groups.
Read more
  • 0
  • 0
  • 2042

article-image-putting-sakai-work
Packt
21 Oct 2009
16 min read
Save for later

Putting Sakai to Work

Packt
21 Oct 2009
16 min read
The fundamental determinants of course quality have always been, and remain, the course content, the instructor(s), the learning activities in which the students are engaged, and the students themselves. We do not make any exaggerated promises about the transformative nature of technology in education. Technology like Sakai can be used to improve your course by allowing you and your students to do things that might have been impractical without the technology or by reducing the amount of time spent on administrative issues. But the tools Sakai provides are just that—tools—and unless they are used purposefully they will not make much of a difference. So it is most important for you to consider what you want to accomplish with your students and how the capabilities Sakai provides can support the course activities. There is not a single "best" way of teaching. What works in a small graduate seminar in philosophy may not work in a large introductory computer science class, and what works for one instructor may not work for another. The good news is that Sakai is designed with this variety in mind. The tools and structure of a Sakai site You can think of Sakai as a framework that allows you to create the kind of online experience you want for your students. There is not a single way that a Sakai course site needs to function—it is ultimately up to you, with assistance from your Sakai user support team, to determine how the course is presented to the students online. Not all Sakai sites are used for courses. In many institutions, it is common to find Sakai used for research work groups and administrative collaboration. In fact, at many institutions, there are more "collaboration sites", as they are called in the Sakai community, than there are course sites. So, these types of sites are included in the overview. Many institutions integrate Sakai with other enterprise systems—automatically creating a Sakai site for each course being taught, for example, and adding students who are registered for the course to the site. Other organizations require instructors to create a site online but, once that's created, students are added and removed based on data from the registrar's office. Regardless of the type of course (or collaboration site) you might be teaching, there is a basic structure to Sakai that is useful to understand. This section describes that basic structure and common tools. It also gives you a quick and easy way to customize a Sakai site, so we recommend having a browser window handy with access to an instance of Sakai. If you have not yet created a Sakai site or if you don't have access to an instance of Sakai at your organization, several Sakai Commercial Affiliates host trial versions of Sakai that you can access free of charge. Check www.sakaiproject.org for the current listing. At the time of writing, hosted trials were available from rSmart (http://sakaisandbox.com), Serensoft (http://sakaisthelimit.com), and Unicon (http://testdrivesakai.com). When you create your account, a site is automatically created for you. Sakai's site structure Once you've logged into Sakai the top of the screen consists of a Sakai banner that contains your organization's branding and a logout button. Just below that banner is a series of tabs, one for each Sakai site that you are a member of. Every course or project consists of a Sakai site and is accessed by clicking a tab labeled with the name of the site. If you are a member of more than one site, you have more than one tab across the top of your screen. If you have too many sites to fit, a More Sites menu (often renamed My Sites or My Active Sites) is present; it enables you to access the appropriate site. Always be sure you're in the correct site when you're doing your work. My Workspace There is also a tab called My Workspace, a special site that only you have access to. You use it to manage your preferences, store personal files, manage site memberships, and even provide a calendar that pulls information from all the Sakai sites to which you belong. Contact your local Sakai support team for more information about uses of My Workspace. You can modify which sites appear across the top of the page so that your most frequently accessed sites are a single click away. To do that, go to your My Workspace site and choose the Preferences tool. The Customize Tabs function enables you to change which sites are visible. A basic Sakai site is a collection of tools that users have access to, typically presented to users in a sidebar on the left of the screen. In most Sakai installations, each link in the left sidebar corresponds to a single tool. To access the Assignments tool, for example, a user clicks the Assignments link in the sidebar. The Assignments tool then appears in the main content area of Sakai. In most cases, it is as simple as that. The major exception to this rule is the site Home page. It is a significant exception because it is the first page you see when you access a site. The Home tool contents Unlike most tools, the Home tool is not a tool at all. It is really a summary page. It generally includes information pulled from several different tools. Sakai tries to be helpful by providing the most commonly useful information and, therefore, a typical course site Home page includes areas (called panels) that present the following information: A site description (a description of the course or project) Recent course announcements Recent discussion forum posts Recent chat messages A course calendar Most of the panels on the Home page can be configured directly from the Home page. The Calendar panel, for example, allows you to specify whether the calendar is presented by week or by month. To add events to the Calendar, however, you need to use the Calendar tool itself. The Announcements panel lets you to determine how many recent announcements are shown (you can specify either a certain number of announcements or have the panel display announcements that have been created since a specific number of days in the past). Some panels enable you to edit the content itself. The Site Description panel, for example, provides an Options link that allows you to edit the content directly, obviating the need to access the tool directly. Of course, if you are not planning to use a tool in your site you do not want its information panel to appear on the course Home page. If you are not going to make a chat room available in your course, for instance, you do not want your course Home page to include a summary of recent chat messages because that would make your site look unfinished. Thankfully, Sakai is generally very smart about this—if you turn off the Chat tool in your site, the recent chat messages summary panel on the Home page simply disappears. Except for editing the Course Description content, you can mostly ignore the Home page and let Sakai take care of it for you. To edit the Site Description, simply click on the Options button. There are four things you can do: Specify the title for the panel. A good title reflects the type of site you have (for example changing the default Site Description to Course Description or, better yet, Welcome to Theater 101). Create the content that appears in the body of the panel. An easy-to-use HTML editor enables you to enter whatever content you want. If you don't know HTML, the default WYSIWYG mode can be used like a simple word processor. Just type away using the built-in text styling buttons to add bold, italics, bulleted lists, and so on. You can also add images, hyperlinks, and tables quite easily. If you know HTML, you can use the source code mode to view and edit the HTML directly. Specify the height for the panel. You want to make the panel large enough so there is no scroll bar within the panel itself. This is easy if there is not another panel just below it. If there is, make the panel just large enough to hold your content but not so large that there is excessive white space between the panels. This may take a bit of trial and error. Enter a URL instead of writing content. If you already have an HTML page that describes the site published elsewhere, you can simply enter that web address. Sakai will display that page in the Site Description panel. Then simply click Update Options to save the changes you've made. If you have access to Sakai, this would be a good time to try it out. Remember to ensure you are working in the correct site. There are, certainly, many instructors who want their course Home page to appear in a very specific manner. There are risks to that level of customization—remember that your students are likely taking several courses at one time and they may benefit from a consistent Home page experience. Nonetheless, it is often quite appropriate to create a custom Home page. Later, you'll see a number of ways to significantly customize the appearance of your site, including the Home page. First, though, let's review tools to make available and just let the Sakai Home page do most of the work. The basic collaboration tools There are four basic tools that almost every Sakai site uses, regardless of whether it is a course or a collaboration site: Resources. The tool for storing files that can be accessed by other members of the site. You can create folders to organize these files, and even make certain files publicly viewable (such as a web page you want to show to those who aren't part of your site). Announcements. Use it to send announcements to members of the site. These announcements appear on the site Home page and can be sent to all site members via email. Email Archive. This tool provides a dedicated email address for your site (mysitename@sakai.myschool.edu, for instance). While permissions can be configured to make Sakai behave differently, typically members of your site can send email to this address and everyone belonging to the site will get the email. All emails are archived and accessible using the Email Archive tool. Calendar. Sometimes called Schedule, the Calendar tool allows you to put important events on a calendar. The Sakai Calendar supports recurring events and has different icons for different types of events such as class meetings, exams, and special events. Site administration As a site owner, there are certain tasks that you may want to undertake to modify the site and/or the members of the site. The Site Info tool allows you to: Modify the tools available in your site, including modifying the order in which those tools appear in the toolbar and changing the names of the tools. Manage access to the site, including specifying whether individuals can join your site without your approval. Manage the membership of your site. What you can and cannot do with membership depends on your local Sakai installation and often varies based on organizational policies, but typically includes the capability to add and remove members and change the role of individual members. Manage groups of users in your site. Many Sakai tools have special features that allow you to work with a particular set of users inside your site. Groups and class sections are good examples of predefined groups that may be automatically created by your Sakai administrators. You can also create ad hoc groups for particular purposes. If you have project teams in your course, for example, it might be useful to create a group for each team. Import content from an existing site or export content from the current site to a new one. As a site owner, you always have access to the Site Info tool. Depending on how you use Sakai and how Sakai is integrated with other systems on your campus, you may never use Site Info. Still, you should take a quick look to familiarize yourself with what is available to you. Every Sakai installation is different from every other. Your organization may not make the same Sakai tools available as another organization. This article mainly restricts itself to those tools that will be commonly available in installations of Sakai version 2.6.x, but there may be instances where we mention a tool that is not available in your instance of Sakai. In many cases, you can request these tools from your Sakai administrator. We also try to mention alternatives to the recommended tool where they exist. The basic teaching and learning tools In addition to the basic collaboration and administration tools, there are three tools that are commonly used in Sakai Course sites: Syllabus, Assignments, and Gradebook. Syllabus. Use this tool to put your syllabus (clear guidelines and expectations for your course) online. You can upload a document (such as a Microsoft Word document or a PDF), build a structured syllabus in Sakai, or even point to an existing syllabus you have posted online in another location. Regardless of how you use the tool, you can have Sakai automatically email students when you've made a change to the syllabus. Assignments. This tool allows you to create and post assignments that students can submit electronically. Using the tool can help eliminate paper assignments and reduce class time spent collecting and returning student work. It allows students to send questions about assignments and enables you to post online comments, grade assignments, and transfer grades to the Gradebook automatically. The tool lets you set opening and closing times for each assignment, supports resubmissions, and marks each student submission with a date and time stamp. Gradebook. The Gradebook tool allows instructors to record and compute cumulative student grades. Students can refer to the Gradebook to check their progress in a course. The Gradebook tool is often used hand-in-hand with the Assignments tool although they can be used separately. With these three tools and the four basic collaboration tools reviewed earlier, you can create a solid online presence for your class. Students will get course announcements and can send and receive emails via the class email address and can check past messages online. You can post reading material and other resources for students online and build a course calendar to remind students of important events and deadlines. Your syllabus is available online and students are automatically updated with any modifications to it. You've provided a facility for students to submit their assignments electronically, and they can receive feedback on those assignments via Sakai as well. Their grades are computed online and they can check to see how they are doing at any time. Now that you have your course's online infrastructure set up, we can begin to add some more sophisticated uses of online tools. We'll do this by turning our attention to the several common types of courses and discuss how a Sakai site can be structured to support each type of course. Types of Sakai sites There are more than four thousand universities and colleges in the United States alone. Each of these teaches hundreds or even thousands of classes every year. Trying to create some structure from such a diverse world would be an exercise in oversimplification. The categories discussed here along with the associated recommendations about how to support them in Sakai are not meant to be rules or even best practices but rather a place to start when thinking about structuring your Sakai site. Do read through all of the site types because it is likely that your course mixes the structures and activities in two or more site types. And your own personal comfort with technology will also determine how many (and which) tools you might want to use. The site types you'll be working with are as follows: Problem-based courses Small discussion courses Large, introductory courses Project-based courses Collaboration sites The following sections highlight a small number of tools that are especially useful in a site used for that purpose. Other tools are often useful as well, but because you're just starting out, you'll have more success using a few tools well. Still, we encourage you to read through all the class types and mix and match the tools you feel will work best for your situation. Problem-based courses A problem-based course presents learners with one or more problems to solve on a regular basis (weekly, for instance). The problems are presented by the instructor and generally have either correct answers (such as a Calculus problem set) or at least a fairly clear way to distinguish better solutions (such as an analysis of a poem in an English literature class). Problem-based courses are often targeted at developing skills related to the topic at hand and students are therefore asked to apply what they've learned by solving problems. Math courses might include weekly problem sets, computer science courses might include small programming assignments, creative writing classes may have weekly writing exercises, an acting class may have a series of small scene studies—the general approach is to increase the level of student skill through repeated practice with frequent feedback. The tools introduced so far serve this type of course very well, with a special emphasis on the Assignments and Resources tools, and with the addition of just a few extra tools, you can make the online aspect of your problem-based class very effective: Assignments. Use this tool to enter all or most of the term's assignments at the beginning of the term. That provides students with an excellent guide to the weeks ahead and helps them plan their time accordingly. Resources. For problems with correct answers, use this tool to share sample problems and solutions to past problem sets. For classes where high-quality answers are less well defined (such as a performing arts or product design class), share samples of previous classes' best work. You can even upload video or audio recordings. By providing examples of excellent solutions to open-ended problems, you help your students understand what you're looking for. Forums. This tool provides online discussion that allows students to help each other with difficult problems. You can set up a forum for each problem set. (Be sure to monitor the forum to ensure that students are giving each other good advice and aren't crossing the boundaries by helping too much.) Chat. Use this tool to provide online problem-set help two nights before an assignment is due (don't encourage procrastination by scheduling it the night before the assignment is due). From the comfort of your home, you can take student questions about the assignment and suggest resources they might refer to while working on it.
Read more
  • 0
  • 0
  • 3694

article-image-gateways-sipxecs-40-part-1
Packt
21 Oct 2009
5 min read
Save for later

Gateways in sipXecs 4.0: Part 1

Packt
21 Oct 2009
5 min read
Gateways provide the connectivity required to reach other systems. These systems can be other sipXecs PBX's, traditional phone lines, or Internet Telephony Service Providers (ITSPs).Connecting the IP phone system to the outside world is one of the most difficult tasks in making the phone system work. If the network infrastructure is configured properly for quality of service, the connection to the outside world can most likely be the source of any call quality problems. Traditional analog Plain Old Telephone Service (POTS) lines are the largest source of frustration. If you can avoid them by utilizing a digital type of service or an ITSP, by all means take that avenue. For those not so lucky, you'll learn more about them then you ever thought you needed to. Typically, volume levels, line disconnect, and echo are the most common problems. Most gateways will have some advanced settings for dealing with these issues but they are different for every manufacturer. Adding gateways There are three types of gateways that can be configured to work in sipXecs; managed, unmanaged, and SIP Trunks. A managed gateway is a hardware device that connects to a traditional phone line. sipXecs knows how to generate configuration files (plug and play) for it. An unmanaged gateway is either a hardware device for which sipXecs doesn't know how to generate configuration files, or it may be another SIP PBX. A SIP Trunk is a connection to an ITSP. Managed gateways At present, there are eight gateways for which sipXecs generates configuration information (ACME 1000 and AudioCodes Models MP114, MP118, Mediant 1000/2000/3000/BRI, and TP260). This is just a small cross section of gateways available in the market. If your gateway is not in this list, see the following Unmanaged gateways subsection. The following detailed information about managed gateways may prove to be useful in setting up an unmanaged gateway. For the following example screens, we'll utilize an AudioCodes MP114 FXO (Foreign Exchange Office) gateway. This particular gateway has four analog ports for connecting to POTS lines. Information on the gateway is available at http://www.audiocodes.com/products/mediapack-1xx. To  add the gateway, click on the Gateways menu item in the  Devices menu. As shown in the following screenshot, there are no gateways configured by default. To add the gateway, click on the Gateways menu item in the Devices menu. As shown in the following screenshot, there are no gateways configured by default. To add a managed gateway, click on the Add new gateway drop-down box and select the appropriate gateway. The gateway configuration page will be displayed as follows: The following configuration information can be configured on this page (click on the Show Advanced Settings hyperlink to display all configuration items): Name: A name given to the gateway (no spaces). Address: The IP address of the gateway or the fully qualified hostname of the gateway (see manufacturer's documentation for information on configuring IP address and other basic settings). Port: An optional setting for UDP or TCP port if a non-standard port is used. Set to 0 to ignore this field. Transport protocol : This can be manually configured to UDP or TCP to force the SIP transport protocol. If it is set to Auto, the transport is determined through a DNS query. Serial Number : This is the Ethernet MAC address of the gateway. Firmware Version : Certain gateways may have different configuration file information or formats depending on the version of firmware in the device. Select the version of firmware that is loaded in the gateway (see manufacturer's documentation). Location: It is possible to restrict the gateway by selecting a specific location for which it can be used. A location is represented by a group of users. A user group must be created for every location that needs to be distinguished (remember that users can be in more than one group). This setting allows routing of calls based on the location or the user from which the call originates (source routing). This is useful if users located in a branch office would like to have a gateway preference so that calls are routed through their local gateway, for example, to preserve WAN bandwidth or to use caller ID offered by an analog gateway based on the PSTN number assigned to it. Only if that gateway is not available, will call routing fall back to other gateways specified for the corresponding dialing rule. Shared: If this setting is checked, this gateway can be used by any user in any location, even if a specific location is selected. This setting is checked by default so that users in an identified location still use their preferred gateway, but the gateway can also be used by other users in other locations. Description : This is for documenting the system configuration. Information about the lines connected to the gateway is very useful here. With all of the configuration information entered, click on the OK button and the Gateway page will be displayed as follows with the new gateway on it. Click on the gateway name to reveal more configuration options, as shown in the following screenshot: With all of the configuration information entered, click on the OK button and the Gateway page will be displayed as follows with the new gateway on it. Click on the gateway name to reveal more configuration options, as shown in the following screenshot: In the following subsections, we'll explore the managed gateway settings available.
Read more
  • 0
  • 0
  • 4509
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-creating-efficient-reports-visual-studio
Packt
21 Oct 2009
5 min read
Save for later

Creating efficient reports with Visual Studio

Packt
21 Oct 2009
5 min read
Report Services, Analysis Services, and Integration Services are the three pillars of Business Intelligence in Microsoft's vision that continues to evolve. Reporting is a basic activity, albeit one of the most important activities of an organization because it provides a specialized and customized view of the data of various forms (relational, text, xml etc) that live in data stores. The report is useful in making business decisions, scheduling business campaigns, or assessing the competition. The report itself may be required in hard copy in several document formats such as DOC, HTML, PDF, etc. Many times it is also required to be retrieved in an interactive form from the data store and viewed on a suitable interface, including a web browser. The Microsoft SQL Server 2005 Reporting Services, popularly known by its acronym SSRS, provides all that is necessary to create and manage reports and deploy them on a report server with output available in several document formats. The reader will greatly benefit from reading the several articles detailed in the author's Hodentek Blog. The content for the articles were developed using VS 2003, VS 2005, SQL 2000 and SQL 2005. (For more resources on Microsoft, see here.) The content for the present tutorial uses a Visual Studio 2008 Professional and a Microsoft SQL Server Compact 3.5 embeddable database for its data. In Visual Studio a Report Design Wizard guides you through fashioning a report from your choices. Create a Windows Project in VS2008 Create a new project from File | New | Project. Provide a name instead of the default name (WindowsApplicaiton1). This is changed to ReportDesign for this tutorial as shown in the next figure. VS 2008 supports multi-version targeting. In the top right of the New Project window you can see that this report is targeted for the NET 2.0 Framework Version and can be published to a Net 2.0 web site. Slightly enlarge the Form1. Drag and drop the Microsoft Report Viewer control shown in the next figure on to the form from the Toolbox. This has the same functionality as the ReportViewer control in VS 2005 as shown in the next figure. The control will be housed on the form as shown in the next figure. You can display the tasks needed to configure the Report Viewer by clicking on the Smart Task as shown in the same figure. The report will have all the functionalities like print, save to different formats, navigating through pages, etc. Working with the Report Wizard Now click on the Design a new report task. The opens the Report Wizard window as shown in the figure. Read the instructions on this page carefully. Click on the Next Button. This displays the Data Source Configuration Wizard shown in the next figure. Choosing a Data Source The application can obtain data from these different resources. Click on the Database icon and then click on the Next button. This displays the window where you need to select a connection to the data source. If there are existing connections you should be able to see them in the drop-down list box. Making a Connection to Get Data Click on the New Connection button. This brings up the Add Connection window showing a default connection to a Microsoft SQL Server Compact 3.5.NET Framework Data Provider. It also shows the location to be My Computer. This source can be changed by clicking on the Change... button. This will bring up the Change Data Source window where you can choose. As found in this version you have the following options: Microsoft SQL Server option lets you connect to SQL 2000 or 2005 using the .NET Framework Data Provider for SQL Server. Microsoft SQL Server Compact 3.5 lets you connect to a database file. Microsoft SQL Server Database File lets you connect to a Local Microsoft SQL Server Instance including a SQL Express. Although it is not explicitly stated what these versions are. For this tutorial the Compact 3.5 will be used (also uses a .NET Framework Data Provider of Compact 3.5). Click on the OK button in the Change Data Source window. VS 2008 installation also installs a database file on the computer for the SQL Server Compact 3.5. Click on Browse button (you could also create one if you like, herein it will be browsed). This brings up the Select SQL Server Compact 3.5 Database File window with the default location where the database file is parked as shown in the next figure. Click on the Northwind icon in the window and click on the Open button. This updates the Add Connection window with this information as shown in the next figure. You may test the connection by hitting the Test Connection button which should display a successful outcome as shown in the next figure. There is no need for a password as you are the owner. Click OK twice and this will take you back to the Data Source Configuration Wizard updating the connection information which you may review as shown in the next figure. Click on the Next button. This brings up the Microsoft Visual Studio message window giving you the option to bring this data source to your project.    
Read more
  • 0
  • 0
  • 6528

article-image-deploying-your-dotnetnuke-portal
Packt
21 Oct 2009
7 min read
Save for later

Deploying Your DotNetNuke Portal

Packt
21 Oct 2009
7 min read
Acquiring a Domain Name One of the most exciting parts of starting a website is acquiring a domain name. When selecting the perfect name there are a few things that you need to keep in mind: Keep it brief: The more letters that a user has to type in to get to your site the more difficult it is going to be for them to remember your site. The name you select will help to brand your site. If it is catchy then people will remember it more readily. Have alternative names in mind: As time goes on, great domain names are becoming fewer and fewer. Make sure you have a few alternatives to choose from. The first domain name you had in mind may already be taken so having a backup plan will help when you decide to purchase a name. Consider buying additional top-level domain names: Say you've already bought www.DanielsDoughnuts.com. You might want to purchase www.DanielsDoughnuts.net as well to protect your name. Once you have decided on the name you want for your domain, you will need to register it. There are dozens of different sites that allow you to register your domain name as well as search to see if it is available. Some of the better-known domain-registration sites are Register.com and NetworkSolutions.com. Both of these have been around a long time and have good reputations. You can also look into some of the discount registers like BulkRegister (http://www.BulkRegister.com) or Enom (http://www.enom.com). After deciding on your domain name and having it registered, you will need to find a place to physically host your portal. Most registration services will also give the ability to host your site with them but it is best to search for a provider that fits your site's needs. Finding a Hosting Provider When deciding on a provider to host your portal, you will need to consider a few things: Cost: This is of course one of the most important things to look at when looking for a provider. There are usually a few plans to select from. The basic plan usually allows you a certain amount of disk space for a very small price but has you share the server with numerous other websites. Most providers also offer dedicated (you get the server all to yourself) and semi-dedicated (you share with a few others). It is usually best to start with the basic plan and move up if the traffic on your site requires it. Windows servers: The provider you select needs to have Windows Server 200/2003 running IIS (Internet Information Services). Some hosts run alternatives to Microsoft like Linux and Apache web server. .NET framework: The provider's servers need to have the .NET framework version 1.1 installed. Most hosts have installed the framework on their servers, but not all. Make sure this is available because DotNetNuke needs this to run. Database availability: You will need database server availability to run DotNetNuke and Microsoft SQL Server is the preferred back-end. It is possible to run your site off Microsoft Access or MySQL (with a purchased provider), but I would not suggest it. Access does not hold up well in a multi-user platform and will slow down considerably when your traffic increases. Also, since most module developers target MS SQL, MySQL, while able to handle multiple users, does not have the module support. FTP access: You will need a way to post your DotNetNuke portal files to your site and the easiest way is to use FTP. Make sure that your host provides this option. E-mail server: A great deal of functionality associated with the DotNetNuke portal relies on being able to send out e-mails to users. Make sure that you will have the availability of an e-mail server. Folder rights: The ASPNET or NetworkService Account (depending on server) will need to have full permissions to the root and subfolders for your DotNetNuke application to run correctly. Make sure that your host either provides you with the ability to set this or is willing to set this up for you. We will discuss the exact steps later in this article. The good news is that you will have plenty of hosting providers to choose from and it should not break the bank. Try to find one that fits all of your needs. There are even some hosts (www.WebHost4life.com) that will install DotNetNuke for you free of charge. They host many DotNetNuke sites and are familiar with the needs of the portal. Preparing Your Local Site Once you have your domain name and a provider to host your portal, you will need to get your local site ready to be uploaded to your remote server. This is not difficult, but make sure you cover all of the following steps for a smooth transition. Modify the compilation debug setting in the web.config file: You will need to modify your web.config file to match the configuration of the server to which you will be sending your files. The first item that needs to be changed is the debug configuration. This should be set to false. You should also rebuild your application in release mode before uploading. This will remove the debug tokens, perform optimizations in the code, and help the site to run faster: <!-- set debugmode to false for running application --> <compilation debug="false" /> Modify the data-provider information in the web.config file: You will need to change the information for connecting to the database so that it will now point to the server on your host. There are three things to look out for in this section (changes shown overleaf): First, if you are using MS SQL, make sure SqlDataProvider is set up as the default provider. Second, change the connection string to reflect the database server address, the database name (if not DotNetNuke), as well as the user ID and password for the database that you received from your provider. Third, if you will be using an existing database to run the DotNetNuke portal, add an objectQualifier. This will append whatever you place in the quotations to the beginning of all of the tables and procedures that are created for your database. <data defaultProvider=" SqlDataProvider" > <providers> <clear/> <add name = "SqlDataProvider" type = "DotNetNuke.Data.SqlDataProvider, DotNetNuke.SqlDataProvider" connectionStringname = "Server=MyServerIP;Database=DotNetNuke; uid=myID;pwd=myPWD;" providerPath = "~ProvidersDataProvidersSqlDataProvider" objectQualifier = "DE" databaseOwner = "dbo" upgradeConnectionString = "" />   Modify any custom changes in the web.config file: Since you set up YetAnotherForum for use on our site, we will need to make the modifications necessary to ensure that the forums connect to the hosted database. Change the to point to the database on the server: <yafnet> <dataprovider>yaf.MsSql,yaf</dataprovider> <connstr> user id=myID;password=myPwd;data source=myServerIP;initial catalog=DotNetNuke;timeout=90 </connstr> <root>/DotNetNuke/DesktopModules/YetAnotherForumDotNet/</root> <language>english.xml</language> <theme>standard.xml</theme> <uploaddir>/DotNetNuke/DesktopModules/yetanotherforum.net /upload/</uploaddir> <!--logtomail>email=;server=;user=;pass=;</logtomail--> </yafnet> Add your new domain name to your portal alias: Since DotNetNuke has the ability to run multiple portals we need to tell it which domain name is associated with our current portal. To do this we need to sign on as host (not admin) and navigate to Admin | Site Settings on the main menu. If signed on as host, you will see a Portal Aliases section on the bottom of the page. Click on the Add New HTTP Alias link:
Read more
  • 0
  • 0
  • 2724

article-image-managing-pages-liferay-portal-52-systems-development
Packt
21 Oct 2009
14 min read
Save for later

Managing Pages in Liferay Portal 5.2 Systems Development

Packt
21 Oct 2009
14 min read
Each site is represented as a community and each community is made up of a lot of pages, for example, public pages and private pages. In order to build web sites, we need to manage communities and, further, manage pages for each community. The Communities portlet provides the ability to create and manage communities and their users, as well as of the Manage Pages portlet. Extending Communities portlet The Communities portlet provides the ability to create and manage communities and their users. A community is a special group holding a number of users who share common interests. By default, a community is represented by the Group_ table with fields such as groupId, companyId, creatorUserId, name, description, type, typeSettings, friendlyURL, active, and so on. Now let's take an in-depth look at the customization of the community. As shown in the following screenshot, we may want to add one searchable field for each community, which is Keywords. For example, suppose we are creating a new community with the name Book Street, and the description a community for website www.bookpubstreet.com. Now we have a chance to add the new Keywords field with the value, for example, Book; Street; Palm Tree; Publication. Similarly, when editing the properties of a community—for example Name, Description, Type, and Active—we again have a chance to edit Keywords. In addition, we expect to have more fields in the customized communities: Created (when the community was created), ModifierUserId (who modified the community), and Modified (when the community was modified). As shown in the preceding screenshot, when listing communities, not only should the default fields (for example, Name, Type, Members, Online Now, Active, Pending Requests) and Actions icons (for example, Edit, Permissions, Manage Pages, Assign User Roles, Assign Members, Leave, and Delete) be displayed, but also the customized columns (for example, the username and Keywords) should be displayed. How do we implement these features? In this article, we're going to show how to customize the Communities portlet using the above requirements as examples. Obviously, it is open for you to customize this portlet in a number of ways according to your own requirements. In general, the processes for customization of this portlet should be the same. Building Ext Communities portlet The Communities portlet can be used to create and manage new portal communities and their users. As you can see, a community can be regarded as a separate portal instance; each community gets its own set of pages, content management system, shared calendar, and default permissions. Moreover, a user belonging to multiple communities can navigate among them within the same portal session. Generally speaking, we do not want to update the Communities portlet, but keep it as it is. Our goal is to customize and extend it. In general, this can be done by using the following two steps: Build a customized Ext Communities portlet, which has exactly the same functions, look, and feel as that of the original Communities portlet. Extend this customized portlet and let it have an additional model and service, and moreover, its own look and feel. In this part, let's build the Ext Communities portlet, having exactly same functions, look, and feel as that of the Communities portlet. Constructing the portlet Now let's define a Struts portlet with the name "Ext Communities". We first need to configure it in both portlet-ext.xml and liferay-portlet-ext.xml, and then set the title in Language-ext.properties, and then add the Ext Communities portlet to the Book category in liferay-display.xml. Locate the portlet-ext.xml file in the /ext/ext-web/docroot/WEB-INF folder and open it. Add the following lines between </portlet> and </portlet-app> and save the file: <portlet> <portlet-name>extCommunities</portlet-name> <display-name>Ext Communities</display-name> <portlet-class>com.liferay.portlet.StrutsPortlet</portlet-class> <init-param><name>view-action</name> <value>/ext/communities/view</value></init-param> <expiration-cache>0</expiration-cache> <supports><mime-type>text/html</mime-type></supports> <resource-bundle> com.liferay.portlet.StrutsResourceBundle </resource-bundle> <security-role-ref> <role-name>power-user</role-name> </security-role-ref> <security-role-ref> <role-name>user</role-name> </security-role-ref> </portlet> As shown in the code above, the portlet-name element contains the canonical name of the portlet (for example, extCommunities). The display-name element contains a short name that is intended to be displayed in the portal (for example, Ext Communities). The portlet-class element contains the fully qualified class name of the portlet (for example, com.liferay.portlet.StrutsPortlet). The init-param element contains a name-value pair, for example view-action-ext/communities/view, as an initialization parameter of the portlet. Further, the expiration-cache defines expiration-based caching for this portlet. The supports element contains the supported MIME-type. The resource-bundle element contains a resource bundle class, for example com.liferay.portlet. StrutsResourceBundle. Finally, the security-role-ref element contains the declaration of a security role reference in the code of the web application. Secondly, let's register the extCommunities portlet in liferay-portlet-ext.xml as follows: Locate the liferay-portlet-ext.xml file in the /ext/ext-web/docroot/WEB-INF folder and open it. Add the following lines immediately after <!-- Custom Portlets --> and save it: <portlet> <portlet-name>extCommunities</portlet-name> <struts-path>ext/communities</struts-path> <use-default-template>false</use-default-template> <restore-current-view>false</restore-current-view> </portlet> As shown in the code above, the Ext Communities portlet is registered in the portal. The portal will check struts-path to see whether a user has the required permissions to access the portlet or not. As you can see, struts-path has the value ext/communities. It means that all requests to the ext/communities/* path are considered a part of this portlet scope. Only those users whose request paths match ext/communities/* will be granted access. Moreover, the use-default-template element has the value false, so the portlet will not use any user's default template. The restore-current-view element has the value false so the portlet will reset the current view when toggling between maximized and normal states. Thirdly, add a title (for example, Ext Communities), for the Ext Communities portlet at Language-ext.properties as follows: Locate the Language-ext.properties file in the /ext/ext-impl/src/content folder and open it. Add the following line after javax.portlet.title.book_reports=Reports for Books and save it: javax.portlet.title.extCommunities=Ext Communities The code above provides mapping for the title of the portlet. If the mapping is not provided, the portal will show the default title javax.portlet.title.extCommunities. Finally, add the Ext Communities portlet to the Book category in liferay-display.xml as follows: Locate the liferay-display.xml file in the /ext/ext-web/docroot/WEBINF folder and open it. Add the following line immediately after the line <portlet id="book_reports" /> and save it: <portlet id="extCommunities" /> As shown in the code above, it adds the Ext Communities portlet to the category Book. From now on, you are able to select this portlet from the Book category directly when adding portlets to pages. Setting up actions Now, let's set up all actions required for the Ext Communities portlet. We need to prepare an action class, for example, ExtEditGroupAction. So how do we build this action? You can build the actions from scratch, but our purpose is to customize and extend the Communities portlet. In one word, we expect to reuse the out of the box portlet source code as much as possible and to write minimum code. As mentioned earlier, we have the portal project for the portal source code in the Eclipse IDE, which is referred to as the /portal prefix. We also have the ext project for customized code, which is referred to as the /ext prefix. The following is a process flow to build the ExtEditGroupAction action class of the Ext Communities portlet. Create a com.ext.portlet.communities.action package in the /ext/ext-impl/src folder. Create an ExtEditGroupAction class in this package and open it. Add the following lines and save it: public class ExtEditGroupAction extends EditGroupAction { public void processAction( ActionMapping mapping, ActionForm form, PortletConfig portletConfig, ActionRequest actionRequest, ActionResponse actionResponse) throws Exception { String cmd = ParamUtil.getString(actionRequest, Constants.CMD); try { if (cmd.equals(Constants.ADD) || cmd.equals(Constants.UPDATE)) { updateGroup(actionRequest); } else if (cmd.equals(Constants.DELETE)) { deleteGroup(actionRequest); } sendRedirect(actionRequest, actionResponse); } catch (Exception e) { if (e instanceof NoSuchGroupException || e instanceof PrincipalException) { SessionErrors.add(actionRequest, e.getClass().getName()); setForward(actionRequest, "portlet.ext.communities.error"); } else if (e instanceof DuplicateGroupException || e instanceof GroupFriendlyURLException || e instanceof GroupNameException || e instanceof RequiredGroupException) { SessionErrors.add(actionRequest, e.getClass().getName(), e); if (cmd.equals(Constants.DELETE)) { actionResponse.sendRedirect( ParamUtil.getString(actionRequest, "redirect")); } } else { throw e;} } } public ActionForward render(ActionMapping mapping, ActionForm form, PortletConfig portlonfig, RenderRequest renderRequest, RenderResponse renderResponse) throws Exception { try { ActionUtil.getGroup(renderRequest); } catch (Exception e) { if (e instanceof NoSuchGroupException || e instanceof PrincipalException) { SessionErrors.add(renderRequest, e.getClass().getName()); return mapping.findForward ("portlet.ext.communities.error"); } else {throw e;} } return mapping.findForward(getForward(renderRequest, "portlet.ext.communities.edit_community")); } } As shown in the code above, ExtEditGroupAction extends EditGroupAction from the com.liferay.portlet.communities.action package in the /portal/portal-impl/src folder. It overrides two methods (render and processAction) of EditGroupAction. Setting up page flow and page layout We have set up the action. We have also updated the forward path as the portlet.ext.communities.* value. In order to get the page flow working, we need to set up an action path and a page flow. First, let's set up the action path and page flow in struts-config.xml as follows: Locate the struts-config.xml file in the /ext/ext-web/docroot/WEB-INF folder and open it. Add the following lines after <struts-config> <action-mappings> and save it: <!-- Ext Communities --> <action path="/ext/communities/edit_community" type="com.ext.portlet.communities.action. ExtEditGroupAction"> <forward name="portlet.ext.communities.edit_community" path="portlet.ext.communities.edit_community" /> <forward name="portlet.ext.communities.error" path="portlet.ext.communities.error" /> </action> <action path="/ext/communities/view" forward="portlet.ext.communities.view" /> The code above defines a set of action paths associated with the action and forward paths, as well as those mentioned earlier. For example, the action path /ext/communities/edit_community is associated with the com.ext.portlet.communities.action.ExtEditGroupAction action and the forward path names portlet.ext.communities.edit_community and portlet.ext.communities.error. Then based on the page flow and JSP files, let's define the page layout in tiles-defs.xml: Locate the tiles-defs.xml file in the ext/ext-web/docroot/WEB-INF folder and open it. Add the following lines after <struts-config> <action-mappings> and save it: <!-- Ext Communities --> <action path="/ext/communities/edit_community" type="com.ext.portlet.communities.action. ExtEditGroupAction"> <forward name="portlet.ext.communities.edit_community" path="portlet.ext.communities.edit_community" /> <forward name="portlet.ext.communities.error" path="portlet.ext.communities.error" /> </action> <action path="/ext/communities/view" forward="portlet.ext.communities.view" /> The code above defines a set of action paths associated with the action and forward paths, as well as those mentioned earlier. For example, the action path /ext/communities/edit_community is associated with the com.ext.portlet.communities.action.ExtEditGroupAction action and the forward path names portlet.ext.communities.edit_community and portlet.ext.communities.error. Then based on the page flow and JSP files, let's define the page layout in tiles-defs.xml: Locate the tiles-defs.xml file in the ext/ext-web/docroot/WEB-INF folder and open it. Add the following lines after <tiles-definitions> and save it: <!-- Ext Communities --> <definition name="portlet.ext.communities" extends="portlet" /> <definition name="portlet.ext.communities.edit_community" extends="portlet.ext.communities"> <put name="portlet_content" value="/portlet/ext/communities/edit_community.jsp" /> </definition> <definition name="portlet.ext.communities.view" extends="portlet"> <put name="portlet_content" value="/portlet/ext/communities/view.jsp" /> </definition> <definition name="portlet.ext.communities.error" extends="portlet"> <put name="portlet_content" value="/portlet/communities/error.jsp" /> </definition> The code above defines the page layout for the Ext Communities portlet. For example, portlet.ext.communities.edit_community is associated with the JSP file /portlet/ext/communities/edit_community.jsp. In addition, it specifies that the community view page layout (for example, portlet.ext.communities.view) is associated with the JSP page file /portlet/ext/communities/view.jsp. Preparing JSP files We have now set up the actions. We have also set up page flow and page layout. Now let's set up the JSP files that are required for the Ext Communities portlet. We need to prepare JSP files such as view.jsp, edit_community.jsp, group_search.jsp, and so on. So how do we build this? You can build them from scratch. However, here we will copy and modify JSP files of the Communities portlet. In this section we expect to reuse the source code, including JSP files, as much as possible. First, let's create the view.jsp JSP file as follows: Create a communities folder within the /ext/ext-web/docroot/html/portlet/ext/ folder. Locate the view.jsp JSP file in the /portal/portal-web/docroot/html/portlet/communities folder, and copy it to the /ext/ext-web/docroot/html/portlet/ext/communities folder. Open view.jsp in the /ext/ext-web/docroot/html/portlet/ext/communities folder, update /communities/edit_community with /ext/communities/edit_community as shown in the following two lines, and save it: portletURL.setParameter("struts_action", "/ext/communities/view"); <liferay-ui:search-form page="/html/portlet/ext/communities/group_search.jsp" searchContainer="<%= searchContainer %>" showAddButton="<%= showTabs1 %>" /> Next, we need to create the JSP file edit_community.jsp as follows: Locate the JSP file edit_community.jsp in the /portal/portal-web/docroot/html/portlet/communities folder, and copy it to the /ext/extweb/docroot/html/portlet/ext/communities folder. Open edit_community.jsp in the /ext/ext-web/docroot/html/portlet/ext/communities folder, update /communities/edit_community with /ext/communities/edit_community as shown in following line, and save it: <form action="<portlet:actionURL windowState="<%= WindowState.MAXIMIZED. toString() %>"> <portlet:param name="struts_action" value="/ext/communities/edit_community" /> </portlet:actionURL>" method="post" name="<portlet:namespace />fm" onSubmit="<portlet:namespace />saveGroup(); return false;"> In addition, we need to make the button Add Community available, in the following manner: Locate JSP file group_search.jsp in the /portal/portal-web/docroot/html/portlet/enterprise_admin folder. Copy the JSP file group_search.jsp from /portal/portal-web/docroot/html/portlet/enterprise_admin to /ext/ext-web/docroot/html/portlet/ext/communities, and open it. Update /communities/edit_community with /ext/communities/edit_community as shown in the following lines, and save it: submitForm(document.<portlet:namespace />fm, '<portlet:renderURL windowState="<%= WindowState.MAXIMIZED.toString() %>"> <portlet:param name="struts_action" value="/ext/communities/edit_community" /> <portlet:param name="redirect" value="<%= currentURL %>" /> </portlet:renderURL>'); Congratulations! You have cloned the Communities portlet. Finally, we can deploy updates into Tomcat as follows: Stop Tomcat if it is running. Click on the Ant target: deploy at the Ant view ext. Start Tomcat. Open up a new browser with the URL http://localhost:8080. Click on Sign in and enter test@liferay.com / test. Click on Add Application | Book
Read more
  • 0
  • 0
  • 1738

article-image-gateways-sipxecs-40-part-2
Packt
21 Oct 2009
5 min read
Save for later

Gateways in sipXecs 4.0: Part 2

Packt
21 Oct 2009
5 min read
Advanced Parameters The Advanced Parameters settings, shown as follows, are accessed by clicking on the Advanced Parameters item in the lefthand menu and are a collection of AudiCodes-specific settings. The following configuration options are available on this page (click on Show Advanced Settings to reveal all options): Secure SIP Calls: If this is enabled, gateways will only accept SIP calls from IP addresses listed below. The default is disabled (unchecked) Accepted IP Addresses: They are used in conjunction with the above setting. It is a space-separated list of IP addresses from which gateway will accept the calls. It is taken into account only if Secure SIP Calls is enabled. The default is the IP address provided for the PBX during install. Digit Delivery to Telephony Port: This setting enables a digit string to be played to the port at the far end, after off-hook. The default is disabled (unchecked). Digit Delivery to IP: This setting enables a digit string to be played to the port at the far end, after off-hook. The default is disabled (unchecked). DID Wink Support: When this is enabled, the gateway can connect to EIA/TIA 464B Loop Start DID lines. Both generation and detection are supported. The default setting is disabled (unchecked). Enable Call Disconnect on Polarity Reversal: If this is checked, enables port disconnect (on-hook) based on polarity reversal. Some POTS providers will reverse the polarity of the analog phone line to signal disconnection to a PBX. The default is disabled (unchecked). Enable Call Disconnect on Current Drop: If this is set to 1, enables port disconnect (on-hook) based on current drop. The default setting is disabled (0). Enable Call Disconnect on Broken Connection: If this is checked, the call is released if the gateway stops receiving RTP for a period of time. The default is enabled (checked). Broken Connection Timeout (10msec): The amount of time for which RTP is not received, before the call is cleared. In 10 ms steps, the default is 500, 10 ms steps (5 seconds). Enable Call Disconnect on Far End Silence: If this checked, enables disconnection of call based on silence. The default is disabled (unchecked). Silence Period for Disconnect: The detection period, in seconds, before the call is released based on silence. The default is 120 seconds. Silence Detection Method: This setting can be set to "None" (silence detection option is disabled), "Packets Count" (according to packet count), "Voice/Energy Detectors" (according to energy and voice detectors (default)) or "All" (according to packet count and energy / voice detectors). Silence Threshold: The threshold of packet count, in percentage, below which is considered as silence. The default setting is 8 packets. Detail Level in Debug Log: The detail level of the log messages sent to syslog server. Default is 0 (off), max is 5 (full). CDR Server IP Address: An optional separate syslog server to collect CDRs only. If null and CDR is enabled, the output is mixed with the log messages and is routed to the syslog server IP. (Default: 0.0.0.0) CDR Report Level: This can be set to "None", (Call Detail Recording or CDR information isn't sent to the Syslog server, which is the default value), "End Call" (CDR information is sent to the Syslog server at the end of each Call) and, "Start & End Call" (CDR information is sent to the Syslog server at the start and at the end of each Call). Port Busy-Out Method  : If there is a network-side failure on the gateway, the POTS interfaces can be set to busy. If this is  checked, telephony ports are busied out (special tone) in case of LAN failure or proxy communication failure. The default is disabled (unchecked). Delay After Reset [sec]: Amount of time delay before answering calls after gateway reset. The default is 7 seconds. Max Number of Active Calls: This is the maximum number of active calls the PBX can process. It should be set to the number of PSTN lines active. Max Call Duration [min]: This is the maximum duration of a phone call. The default is 0, which means no maximum. Enable LAN Watchdog: When LAN Watchdog is enabled, the gateway's overall communication integrity is checked periodically. If no communication for about 3 minutes is detected, the gateway performs a self test. If the self test succeeds, the problem is logical link down (for example, Ethernet cable disconnected on the switch side), and the "Busy Out" mechanism is activated if enabled (EnableBusyOut = 1). Lifeline is activated if enabled. If the self test fails, the gateway restarts to overcome an internal fatal communication error (default: unchecked). Enable SAS: This setting is to enable/disable Stand-Alone Survivability (SAS) (default: unchecked). • SAS Registration Time: This is the time after which SAS is enabled (default: 20 seconds). SAS Local SIP UDP port: This is the UDP Port for SAS SIP signaling (default: 5080). SAS Local SIP TCP port: This is the TCP Port for SAS SIP signaling (default: 5080). SAS Local SIP TLS port: This is the TLS Port for SAS SIP signaling (default: 5081). SAS Default Gateway: This is the SAS Default Gateway IP address (default blank). SAS Short Number Length: This is the SAS short number length. Click on the Apply button to keep any changes made on this page.
Read more
  • 0
  • 0
  • 4725
article-image-theming-modules-drupal-6
Packt
21 Oct 2009
5 min read
Save for later

Theming Modules in Drupal 6

Packt
21 Oct 2009
5 min read
Our Target Module: What We Want Before we begin developing a module, here's a brief overview of what we want to accomplish. The module we will write in this article is the Philosophy Quotes module (philquotes will be our machine-readable name). The goal of this module will be to create a block that displays pithy philosophical quotes. We will implement the following features: Quotes should be stored along with other basic content, making it possible to add, modify, and delete this content in exactly the same way that we create other articles. Since our existing themes aren't aware of this quotes module, it must provide some default styling. We will progress through the creation of this module by first generating a new "quote" content type, and then building a theme-aware module. Creating a Custom Content Type As Drupal evolved, it incorporated an increasingly sophisticated method for defining content. Central to this system is the idea of the content type. A content type is a definition, stored in Drupal's database, of how a particular class of content should be displayed and what functionality it ought to support. Out of the box, Drupal has two defined content types: Page and Story. Pages are intended to contain content that is static, like an "About Us" or "Contact Us" page. Stories, on the other hand, are intended to contain more transient content—news items, blog postings, and so on. Creating new pages or stories is as simple as clicking on the Create Content link in the default menu. Obviously, not all content will be classified as either a page or a story, and many sites will need specialized content types to adequately represent a specific class of content. Descriptions of events, products, component descriptions, and so on might all be better accomplished with specialized content types. Our module is going to display brief quotes. These quotes shouldn't be treated like either articles or pages. For example, we wouldn't want a new quote to be displayed along with site news in the center column of our front page. Thus, our quotes module needs a custom content type. This content type will be very simple. It will have two parts: the text of the quote and the origin of the quote. For example, here's a famous quote: The life of man [is] solitary, poor, nasty, brutish, and short.—Thomas Hobbes. The text of this quote is "The life of man [is] solitary, poor, nasty, brutish, and short", and the origin in this example is Thomas Hobbes. We could have been more specific and included the title of the work (Leviathan) or even the exact page reference, edition, and so on. But all this information, in our simple example, would be treated as the quote's origin. Given the simplicity of our content type, we can simply use the built-in Drupal content type tool to create the new type. To generate even more sophisticated content types, we could install the CCK (Content Creation Kit) module, and perhaps some of the CCK extension modules. CCK provides a robust set of tools for defining custom fields, data types, and features. But here our needs are simple, so we won't need any additional modules or even any custom code to create this new content type. Using the Administration Interface to Create a Content Type The process of creating our custom content type is as simple as logging into Drupal and filling out a form. The content type tool is in Administer | Content management | Content types. There are a couple of tabs at the top of the page: Clicking the Add content type tab will load the form used to create our new content type. On this form, we need to complete the Name and Type fields—the first with a human-friendly name, and the second with a computer-readable name. Description is often helpful. In addition to these fields, there are a few other form fields under the Submission form settings and Workflow settings that we need to change. In the Submission form settings section, we will change the labels to match the terminology we have been using. Instead of Title and Body, our sections will be Origin and Text. Changing labels is a superficial change. While it changes the text that is displayed to users, the underlying data model will still refer to these fields as title and body. We will see this later in the article. In the Workflow settings section, we need to make sure that only Published is checked. By default, Promoted to front page is selected. That should be disabled unless you want new quotes to show up as content in the main section of the front page. Once the form is complete, pressing the Save content type button will create the new content type. That's all there is to it. The Create content menu should now have the option of creating a new quote: As we continue, we will create a module that displays content of type quote in a block. Before moving on, we want a few pieces of content. Otherwise, our module would have no data to display. Here's the list of quotes (as displayed on Administer | Content management | Content) that will constitute our pool of quotations for our module.  
Read more
  • 0
  • 0
  • 1855

article-image-access-control-php5-cms-part-2
Packt
21 Oct 2009
17 min read
Save for later

Access Control in PHP5 CMS - Part 2

Packt
21 Oct 2009
17 min read
Framework Solution The implementation of access control falls into three classes. One is the class that is asked questions about who can do what. Closely associated with this is another class that caches general information applicable to all users. It is made a separate class to aid implementation of the split of cache between general and user specific. The third class handles administration operations. Before looking at the classes, though, let's figure out the database design. Database for RBAC All that is required to implement basic RBAC is two tables. A third table is required to extend to a hierarchical model. An optional extra table can be implemented to hold role descriptions. Thinking back to the design considerations, the first need is for a way to record the operations that can be done on the subjects, that is the permissions. They are the targets for our access control system. You'll recall that a permission consists of an action and a subject, where a subject is defined by a type, and an identifier. For ease of handling, a simple auto-increment ID number is added. But we also need a couple of other things. To make our RBAC system general, it is important to be able to control not only the actual permissions, but also who can grant those permissions, and whether they can grant that right to others. So an extra control field is added with one bit for each of those three possibilities. It therefore becomes possible to grant the right to access something with or without the ability to pass on that right. The other extra data item that is useful is a "system" flag. It is used to make some permissions incapable of deletion. Although not being a logical requirement, this is certainly a practical requirement. We want to give administrators a lot of power over the configuration of access rights, but at the same time, we want to avoid any catastrophes. The sort of thing that would be highly undesirable would be for the top level administrator to remove all of their own rights to the system. In practice, most systems will have a critical central structure of rights, which should not be altered even by the highest administrator. So now the permissions table can be seen to be as shown in the following screenshot: Note that the character strings for role, action, and subject_type are given generous lengths of 60, which should be more than adequate. The subject ID will often be quite short, but to avoid constraining generality, it is made a text field, so that the RBAC system can still handle very complex identifiers, if required. Of course, there will be some performance penalties if this field is very long, but it is better to have a design trade-off than a limitation. If we restricted the subject ID to being a number, then more complex identifiers would be a special case. This would destroy the generality of our scheme, and might ultimately reduce overall efficiency. In addition to the auto-increment primary key ID, two indices are created, as shown in the following screenshot. They involve overhead during update operations but are likely to speed access operations. Since far more accesses will typically be made than updates, this makes sense. If for some reason an index does not give a benefit, it is always possible to drop it. Note that the index on the subject ID has to be constrained in length to avoid breaking limits on key size. The value chosen is a compromise between efficiency through short keys, and efficiency through the use of fine grained keys. In a heavily used system, it would be worth reviewing the chosen figure carefully, and perhaps modifying it in the light of studies into actual data. The other main database table is even simpler, and holds information about assignment of accessors to roles. Again, an auto-increment ID is added for convenience. Apart from the ID, the only fields required are the role, the accessor type, and the accessor ID. This time a single index, additional to the primary key, is sufficient. The assignment table is shown in the following screenshot, and its index is shown in the screenshot after that: Adding hierarchy to RBAC requires only a very simple table, where each row contains two fields: a role, and an implied role. Both fields constitute the primary key, neither field on its own being necessarily unique. An index is not required for efficiency, since the volume of hierarchy information is assumed to be small, and whenever it is needed, the whole table is read. But it is still a good principle to have a primary key, and it also guarantees that there will not be redundant entries. For the example given earlier, a typical entry might have consultant as the role, and doctor as the implied role. At present, Aliro implements hierarchy only for backwards compatibility, but it is a relatively easy development to make hierarchical relationships generally available. Optionally, an extra table can be used to hold a description of the roles in use. This has no functional purpose, and is simply an option to aid administrators of the system. The table should have the role as its primary key. As it does not affect the functionality of the RBAC at all, no further detail is given here. With the database design settled, let's look at the classes. The simplest is the administration class, so we'll start there. Administering RBAC The administration of the system could be done by writing directly to the database, since that is what most of the operations involve. There are strong reasons not to do so. Although the operations are simple, it is vital that they be handled correctly. It is generally a poor principle to allow access to the mechanisms of a system rather than providing an interface through class methods. The latter approach ideally allows the creation of a robust interface that changes relatively infrequently, while details of implementation can be modified without affecting the rest of the system. The administration class is kept separate from the classes handling questions about access because for most CMS requests, administration will not be needed, and the administration class will not load at all. As a central service, the class is implemented as a standard singleton, but it is not cached because information generally needs to be written immediately to the database. In fact, the administration class frequently requests the authorization cache class to clear its cache so that the changes in the database can be effective immediately. The class starts off: class aliroAuthorisationAdmin { private static $instance = __CLASS__; private $handler = null; private $authoriser = null; private $database = null; private function __construct() { $this->handler =& aliroAuthoriserCache::getInstance(); $this->authoriser =& aliroAuthoriser::getInstance(); $this->database = aliroCoreDatabase::getInstance(); } private function __clone() { // Enforce singleton } public static function getInstance() { return is_object(self::$instance) ? self::$instance : (self::$instance = new self::$instance()); } private function doSQL($sql, $clear=false) { $this->database->doSQL($sql); if ($clear) $this->clearCache(); } private function clearCache() { $this->handler->clearCache(); } Apart from the instance property that is used to implement the singleton pattern, the other private properties are related objects that are acquired in the constructor to help other methods. Getting an instance operates in the usual fashion for a singleton, with the private constructor, and clone methods enforcing access solely via getInstance. The doSQL method also simplifies other methods by combining a call to the database with an optional clearing of cache through the class's clearCache method. Clearly the latter is simple enough that it could be eliminated. But it is better to have the method in place so that if changes were made to the implementation such that different actions were needed when any relevant cache is to be cleared, the changes would be isolated to the clearCache method. Next we have a couple of useful methods that simply refer to one of the other RBAC classes: public function getAllRoles($addSpecial=false) { return $this->authoriser->getAllRoles($addSpecial); }public function getTranslatedRole($role) { return $this->authoriser->getTranslatedRole($role); } Again, these are provided so as to simplify the future evolution of the code so that implementation details are concentrated in easily identified locations. The general idea of getAllRoles is obvious from the name, and the parameter determines whether the special roles such as visitor, registered, and nobody will be included. Since those roles are built into the system in English, it would be useful to be able to get local translations for them. So the method getTranslatedRole will return a translation for any of the special roles; for other roles it will return the parameter unchanged, since roles are created dynamically as text strings, and will therefore normally be in a local language from the outset. Now we are ready to look at the first meaty method: public function permittedRoles ($action, $subject_type, $subject_id) { $nonspecific = true; foreach ($this->permissionHolders ($subject_type, $subject_id) as $possible) { if ('*' == $possible->action OR $action == $possible->action) { $result[$possible->role] = $this->getTranslatedRole ($possible->role); if ('*' != $possible->subject_type AND '*' != $possible_subject_id) $nonspecific = false; } } if (!isset($result)) { if ($nonspecific) $result = array('Visitor' => $this->getTranslatedRole('Visitor')); else return array(); } return $result; }private function &permissionHolders ($subject_type, $subject_id) { $sql = "SELECT DISTINCT role, action, control, subject_type, subject_id FROM #__permissions"; if ($subject_type != '*') $where[] = "(subject_type='$subject_type' OR subject_type='*')"; if ($subject_id != '*') $where[] = "(subject_id='$subject_id' OR subject_id='*')"; if (isset($where)) $sql .= " WHERE ".implode(' AND ', $where); return $this->database->doSQLget($sql); } Any code that is providing an RBAC administration function for some part of the CMS is likely to want to know what roles already have a particular permission so as to show this to the administrator in preparation for any changes. The private method permissionHolders uses the parameters to create a SQL statement that will obtain the minimum relevant permission entries. This is complicated by the fact that in most contexts, asterisk can be used as a wild card. The public method permittedRoles uses the private method to obtain relevant database rows from the permissions table. These are checked against the action parameter to see which of them are relevant. If there are no results, or if none of the results refer specifically to the subject, without the use of wild cards, then it is assumed that all visitors can access the subject, so the special role of visitor is added to the results. When actual permission is to be granted we need the following methods: public function permit ($role, $control, $action, $subject_type, $subject_id) { $sql = $this->permitSQL($role, $control, $action, $subject_type, $subject_id); $this->doSQL($sql, true); }private function permitSQL ($role, $control, $action, $subject_type, $subject_id) { $this->database->setQuery("SELECT id FROM #__permissions WHERE role='$role' AND action='$action' AND subject_type='$subject_type' AND subject_id='$subject_id'"); $id = $this->database->loadResult(); if ($id) return "UPDATE #__permissions SET control=$control WHERE id=$id"; else return "INSERT INTO #__permissions (role, control, action, subject_type, subject_id) VALUES ('$role', '$control', '$action', '$subject_type', '$subject_id')"; } The public method permit grants permission to a role. The control bits are set in the parameter $control. The action is part of permission, and the subject of the action is identified by the subject type and identity parameters. Most of the work is done by the private method that generates the SQL; it is kept separate so that it can be used by other methods. Once the SQL is obtained, it can be passed to the database, and since it will normally result in changes, the option to clear the cache is set.   The SQL generated depends on whether there is already a permission with the same parameters, in which case only the control bits are updated. Otherwise an insertion occurs. The reason for having to do a SELECT first, and then decide on INSERT or UPDATE is that the index on the relevant fields is not guaranteed to be unique, and also because the subject ID is allowed to be much longer than can be included within an index. It is therefore not possible to use ON DUPLICATE KEY UPDATE. Wherever possible, it aids efficiency to use the MySQL option for ON DUPLICATE KEY UPDATE. This is added to the end of an INSERT statement, and if the INSERT fails by virtue of the key already existing in the table, then the alternative actions that follow ON DUPLICATE KEY UPDATE are carried out. They consist of one or more assignments, separated by commas, just as in an UPDATE statement. No WHERE is permitted since the condition for the assignments is already determined by the duplicate key situation. A simple method allows deletion of all permissions for a particular action and subject: public function dropPermissions ($action, $subject_type, $subject_id) { $sql = "DELETE FROM #__permissions WHERE action='$action' AND subject_type='$subject_type'AND subject_id='$subject_id' AND system=0"; $this->doSQL($sql, true); } The final set of methods relates to assigning accessors to roles. Two of them reflect the obvious need to be able to remove all roles from an accessor (possibly preparatory to assigning new roles) and the granting of a role to an accessor. Where the need is to assign a whole set of roles, it is better to have a method especially for the purpose. Partly this is convenient, but it also provides an extra operation, minimization of the set of roles. The method is: public function assign ($role, $access_type, $access_id, $clear=true) { if ($this->handler->barredRole($role)) return false; $this->database->setQuery("SELECT id FROM #__assignments WHERE role='$role' AND access_type='$access_type' AND access_id='$access_id'"); if ($this->database->loadResult()) return true; $sql = "INSERT INTO #__assignments (role, access_type, access_id) VALUES ('$role', '$access_type', '$access_id')"; $this->doSQL($sql, $clear); return true; }public function assignRoleSet ($roleset, $access_type, $access_id) { $this->dropAccess ($access_type, $access_id); $roleset = $this->authoriser->minimizeRoleSet($roleset); foreach ($roleset as $role) $this->assign ($role, $access_type, $access_id, false); $this->clearCache(); }public function dropAccess ($access_type, $access_id) { $sql = "DELETE FROM #__assignments WHERE access_type='$access_type' AND access_id='$access_id'"; $this->doSQL($sql, true); } The method assign links a role to an accessor. It checks for barred roles first, these are simply the special roles discussed earlier, which cannot be allocated to any accessor. As with the permitSQL method, it is not possible to use ON DUPLICATE KEY UPDATE because the full length of the accessor ID is not part of an index, so again the existence of an assignment is checked first. If the role assignment is already in the database, there is nothing to do. Otherwise a row is inserted, and the cache is cleared. Getting rid of all role assignments for an accessor is a simple database deletion, and is implemented in the dropAccess method. The higher level method assignRoleSet uses dropAccess to clear out any existing assignments. The call to the authorizer object to minimize the role set reflects the implementation of a hierarchical model. Once there is a hierarchy, it is possible for one role to imply another as consultant implied doctor in our earlier example. This means that a role set may contain redundancy. For example, someone who has been allocated the role of consultant does not need to be allocated the role of doctor. The minimizeRoleSet method weeds out any roles that are superfluous. Once that has been done, each role is dealt with using the assign method, with the clearing of the cache saved until the very end. The General RBAC Cache As outlined earlier, the information needed to deal with RBAC questions is cached in two ways. The file system cache is handled by the aliroAuthoriserCache singleton class, which inherits from the cachedSingleton class. This means that the data of the singleton object will be automatically stored in the file system whenever possible, with the usual provisions for timing out an old cache, or clearing the cache when an update has occurred. It is highly desirable to cache the data both to avoid database operations and to avoid repeating the processing needed in the constructor. So the intention is that the constructor method will run only infrequently. It contains this code: protected function __construct() { // Making private enforces singleton $database = aliroCoreDatabase::getInstance(); $database->setQuery("SELECT role, implied FROM #__role_link UNION SELECT DISTINCT role, role AS implied FROM #__assignments UNION SELECT DISTINCT role,role AS implied FROM #__permissions"); $links = $database->loadObjectList(); if ($links) foreach ($links as $link) { $this->all_roles[$link->role] = $link->role; $this->linked_roles[$link->role][$link->implied] = 1; foreach ($this->linked_roles as $role=>$impliedarray) { foreach ($impliedarray as $implied=>$marker) { if ($implied == $link->role OR $implied == $link->implied) { $this->linked_roles[$role][$link->implied] = 1; if (isset($this->linked_roles[$link->implied])) foreach ($this->linked_roles[$link->implied] as $more=>$marker) { $this->linked_roles[$role][$more] = 1; } } } } } $database->setQuery("SELECT role, access_id FROM #__assignments WHERE access_type = 'aUser' AND (access_id = '*' OR access_id = '0')"); $user_roles = $database->loadObjectList(); if ($user_roles) foreach ($user_roles as $role) $this- >user_roles[$role->access_id][$role->role] = 1; if (!isset($this->user_roles['0'])) $this->user_roles['0'] = array(); if (isset($this->user_roles['*'])) $this->user_roles['0'] = array_merge($this->user_roles['0'], $this->user_roles['*']); } All possible roles are derived by a UNION of selections from the permissions, assignments, and linked roles database tables. The union operation has overheads, so that alone is one reason for favoring the use of a cache. The processing of linked roles is also complex, and therefore worth running as infrequently as possible. Rather than working through the code in detail, it is more useful to describe what it is doing. The concept is much simpler than the detail! If we take an example from the backwards compatibility features of Aliro, there is a role hierarchy that includes the role Publisher, which implies membership of the role Editor. The role Editor also implies membership of the role Author. In the general case, it is unreasonable to expect the administrator to figure out the implied relationships. In this case, it is clear that the role Publisher must also imply membership of the role Editor. But these linked relationships can plainly become quite complex. The code in the constructor therefore assumes that only the least number of connections have been entered into the database, and it figures out all the implications. The other operation where the code is less than transparent is the setting of the user_roles property. The Aliro RBAC system permits the use of wild cards for specification of identities within accessor, or subject types. An asterisk indicates any identity. For accessors whose accessor type is user, another wild card available is zero. This means any user who is logged in, and is not an unregistered visitor. Given the relatively small number of role assignments of this kind, it saves a good deal of processing if all of them are cached. Hence the user_roles processing is done in the constructor. Other methods in the cache class are simple enough to be mentioned rather than given in detail. They include the actual implementation of the getTranslatedRole method, which provides local translations for the special roles. Other actual implementations are getAllRoles with the option to include the special roles, getTranslatedRole, which translates a role if it turns out to be one of the special ones and barredRole, which in turn, tests to see if the passed role is in the special group. It may therefore not be assigned to an accessor.
Read more
  • 0
  • 0
  • 2174

article-image-comparing-asterisk-and-openser
Packt
21 Oct 2009
4 min read
Save for later

Comparing Asterisk and OpenSER

Packt
21 Oct 2009
4 min read
Introduction If you work with IP telephony, it's quite possible that you have not heard about OpenSER, but certainly you must have heard about Asterisk. Well, I love a polemic headline and I have seen this question asked in the forums many times.  So, I will dare to compare these two very popular softwares dedicated to the VoIP market.  The idea here is not to show you which one is the best, but mainly how they are different from each other. Below is a comparison topic by topic. Architecture Asterisk is a Back to Back User Agent (B2BUA), while OpenSER is a Session Initiation Protocol (SIP) Proxy.  This makes all the difference between them. The SIP proxy architecture is faster than a B2BUA because it deals only with signaling. On the other hand, the B2BUA architecture, even being slower, handles the media and it is capable of several services not available in a SIP proxy such as Codec Translation (that is G729<->G.711), Protocol Translation (SIP<->H323), and services related to media such as IVR, Queuing, Text to Speech, and Voice Recognition. Nat Traversal OpenSER deals a lot better with NAT traversal then Asterisk. You can send the media from your customer directly to the provider using OpenSER in most cases (non-symmetric NAT). Manipulating directly the SIP protocol allows you to handle special cases, such as, when you have two customers behind the same NAT device and want to send the media directly between them. Load Balancing OpenSER has specific load balancing algorithms with hash. So it can load balance by the "ruri", "username", "call-id", and some other properties. It can use redirected messages consuming very few resources from the load balancer machine. Failover is part of the solution, things you won't find on Asterisk, but are complementary. Low Level Access to SIP Header and Transactions OpenSER gives you low level access to the protocol. You can handle all the requests and responses. So it is possible, most times, to translate between two incompatible versions of SIP, handling directly the SIP headers, requests, and responses. This is an important feature when you have SIP implementations from different manufacturers, which can be incompatible between each other. Integration with Radius, Diameter, and LDAP OpenSER has built-in integration with LDAP, Radius, and Diameter. While this is also possible with Asterisk, the implementation on OpenSER is developed in C, integrated as a module, and is part of the OpenSER distribution (no perl, no python, no third-party modules). Carrier Class Routing The module CARRIERROUTE implements sophisticated algorithms to route calls to the PSTN. Some times VoIP providers have tables with more then 40.000 routes. In this case, you will absolutely need a specific routing module capable of failback, blacklists, and some other features specific to VoIP providers. Media Services OpenSER is a SIP Proxy and is not capable of any media related services. So it is not possible to create, using OpenSER, systems such as VoiceMail, IVR, TTS, and Voice Recognition. However, it is possible to integrate any of these services to the platform using a separate Media Server such as Asterisk, Yate, and FreeSwitch.  This is by design, and it is the way the SIP protocol is defined in the standards (RFC3261). Connectivity to the PSTN OpenSER always need a SIP gateway to connect to the PSTN. There is no possibility to install telephony cards in the server.  In several cases, Asterisk is used as the PSTN gateway for OpenSER. Conclusion I love this discussion, because Asterisk and OpenSER completes one another. OpenSER provides rock solid SIP services to VoIP providers, it is capable to handle large volumes of calls, to load balance SIP, to solve advanced NAT scenarios, and to deal with SIP signaling as no other. Asterisk is a B2BUA, very strong in the PBX market. It is simpler to configure and can handle low to medium volumes. Asterisk can be used as a "single box does it all", while OpenSER requires all the architectural components of SIP to work. OpenSER is a "hit" in the VoIP provider market and in Universities. Asterisk PBX is a success in the IP PBX market, and it is getting a piece of the small to medium VoIP providers. Usually you start using OpenSER when you have some special need, such as load balancing or when you have large volumes such as more than a thousand registered users. Choose wisely!   If you have read this article you may be interested to view : Using Asterisk as a PSTN Gateway for OpenSER Building the User Portal with SerMyAdmin for OpenSER
Read more
  • 0
  • 0
  • 4773
article-image-sakai-web-services-connecting-enterprise-part-1
Packt
21 Oct 2009
17 min read
Save for later

Sakai Web Services: Connecting to the Enterprise (Part 1)

Packt
21 Oct 2009
17 min read
Connecting to Sakai is straightforward, and simple tasks, such as automatic course creation, take only a few tens of lines of programming effort. There are significant advantages to having web services in the enterprise. If a developer writes an application that calls a number of web services, then the application does not need to know the hidden details behind the services. It just needs to agree on what data to send. This loosely couples the application to the services. Later, you can replace one web service with another. Programmers do not need to change the code on the application side. SOAP works well with most organizations' firewalls (http://en.wikipedia.org/wiki/Firewall), as SOAP uses the same protocol as web browsers. System administrators have a tendency to protect an organization's network by closing unused ports to the outside world. This means that most of the time there is no extra network configuration effort required to enable web services. Another simplifying factor is that a programmer does not need to know the details of SOAP or REST, as there are libraries and frameworks that hide the underlying magic. For the Sakai implementation of SOAP, to add a new service is as simple as writing a small amount of Java code within a text file, which then is automatically compiled and run the first time the service is called. This is great for rapid application development and deployment, as the system administrator does not need to restart Sakai for each change. Just as importantly, the Sakai services use the well-known libraries from the Apache Axis project (http://ws.apache.org/axis/). SOAP is an XML message passing protocol that, in the case of Sakai sites, sits on top of the Hyper Text Transfer Protocol (HTTP). HTTP is the protocol used by web browsers to obtain web pages from a server. The client sends messages in XML format to a service, including the information that the service needs, and then the service returns a message with the results or an error message. A readable reference to this interchange is the book Pro Apache XML by Poornachandra Sarang, PhD (http://www.freesoftwaremagazine.com/articles/book_review_pro_apache_xml). The full definition of HTTP is given at http://www.w3.org/TR/soap12-part1. The architects introduced SOAP-based web services first to Sakai and later RESTful services. Unlike SOAP, instead of sending XML via HTTP posts to one URL that points to a service, REST sends to a URL that includes information about the entity, such as a user, with which the client wishes to interact. For example, a REST URL for viewing an address book item could look similar to http://host/direct/addressbook_item/15. Applying URLs in this way makes understandable address spaces that are easier for a human to read. This more intuitive approach simplifies coding. Further, SOAP XML passing requires that the client and server parse the XML and at times, the parsing effort is expensive in CPU cycles and response times. The Entity Broker is an internal service that makes life easier for programmers and helps them manipulate entities. Entities in Sakai are managed pieces of data such as representations of courses, users, grade books, and so on. In the newer versions of Sakai, the Entity Broker has the power to expose entities as RESTful services. In contrast, for SOAP services, if you wanted a new service, you would need to write it yourself. Over time, the Entity Broker exposes more and more entities RESTfully, delivering more hooks free to integrate with other enterprise systems. Both SOAP and REST services sit on top of the HTTP protocol, which is explained in the next section of this article. Protocols This section explains how web browsers talk to servers in order to gather web pages. It explains how to use the telnet command and a visual tool called TCPMON (http://ws.apache.org/commons/tcpmon/tcpmontutorial.html) to gain insight into how web services and Web 2.0 technologies work. Playing with Telnet It turns out that message passing occurs via text commands between the browser and the server. Web browsers use HTTP (http://www.w3.org/Protocols/rfc2616/rfc2616.html) to get web pages and the embedded content from the server and to send form information to the server. HTTP talks between the client and server via text (7 bit ASCII) commands. When humans talk with each other, they have a wide vocabulary. However, HTTP uses fewer than twenty words. You can experiment directly with HTTP using a Telnet client to send your commands to a web server. For example, if your demonstration Sakai instance is running on port 8080, the following command will get you the login page: telnet localhost 8080GET /portal/login The GET command does what it sounds like and gets a web page. Forms can use the GET verb to send data at the end of the URL. For example, GET /portal/login?name=alan&age=15 is sending the variables name=alan and age=15 to the server. Installing TCPMON You can use the TCPMON tool to view requests and responses from a web browser such as Firefox. One of TCPMON's abilities is that it can act as an invisible man in the middle, recording the messages between the web browser and the server. Once set up, the requests sent from the browser go to TCPMON and TCPMON passes the request on to the server. The server passes back a response and then TCPMON, a transparent proxy (http://en.wikipedia.org/wiki/Proxy_server), returns the response to the web browser. This allows us to look at all requests and responses graphically. First, you can set TCPMON up to listen on a given port number—by convention, normally, port 8888—and then you can configure your web browser to send its requests through the proxy. Then, you can type the address of a given page into the web browser, but instead of going directly to the relevant server, the browser sends the request to the proxy, which then passes it on and passes the response back. TCPMON displays both the request and responses in a window. You can download TCPMON from http://ws.apache.org/commons/tcpmon/download.cgi. After downloading and unpacking, you can, from within the build directory, run either tcpmon.bat for the Windows environment or tcpmon.sh for Unix/Linux environments. To configure a proxy, you can click the Admin tab and then set the Listen Port to 8888 and select the Proxy radio button. After that, clicking Add will create a new tab, where the requests and responses will later be displayed. Your favorite web browser now has to recognize the newly set up proxy. For Firefox 3, you can do this by selecting the menu option Edit/Preferences and then choosing the advanced tab and the network tab, as shown next. You will need to set the proxy options HTTP proxy to 127.0.0.1 and the port number to 8888. If you do this, you will need to ensure that the No proxies text input is blank. Clicking the OK button enables the new settings. To use the Proxy from within Internet Explorer 7 for a Local Area Network (LAN), you can edit the dialog box found under Tools | Internet Options | Connections | LAN settings. Once the proxy is working, typing http://localhost:8080/portal/login in the address bar will seamlessly return the login page of your local Sakai instance. Otherwise, you will see an error message similar to Proxy Server Refused Connection for Firefox or Internet Explorer cannot display the webpage. To turn the proxy settings off, simply select the No Proxies radio box and click OK for Firefox 3, or unselect the Use the proxy server for the LAN tick box in Internet Explorer 7 and click OK. Requests and returned status codes When TCPMON is running a proxy on port 8888, it allows you to view the requests from the browser and the response in an extra tab, as shown in the following screen grab. Notice the extra information that the browser sends as part of the request. HTTP/1.1 defines the protocol and version level and the lines below the GET are header variables. The User-Agent defines which client sent the request. The Accept headers tell the server what the capabilities of the browser are, and the Cookie header defines the value stored in a cookie. HTTP is stateless, that is, in principle; each response is based only on the current request. However, to get around this, persistent information can be stored in cookies. Web browsers normally store their representation of a cookie as a little text file or in a small database on the end users' computers. Sakai uses the supporting features of a servlet container, such as Tomcat, to maintain state in cookies. A cookie stores a session ID, and when the server sees the session ID, it can look up the request's server-side state. Server-side state contains information such as whether the user is logged in or what he or she has ordered. The web browser deletes the local representation of the cookie each time the browser closes. A cookie that is deleted when a web browser closes is known as a session cookie. The server response starts with the protocol followed by a status number. HTTP/1.1 200 OK tells the web browser that the server is using HTTP version 1.1 and it was able to return the requested web page successfully. 2xx status codes imply success. 3xx status codes imply some form of redirection and tell the web browser where to try to pick up the requested resource. 4xx status codes are for client errors, such as malformed requests or lack of permission to obtain the resource. 4xx states are fertile grounds for security managers to look in log files for attempted hacking. 5xx status codes mostly have to do with a failure of the server itself and are mostly of interest to system administrators and programmers during the debugging cycle. In most cases, 5xx status numbers are about either high server load or a broken piece of code. Sakai is changing rapidly and even with the most vigorous testing, there are bound to be the occasional hiccups. You will find accurate details of the full range of status codes at: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html. Another important part of the response is the Content-Type, which tells the web browser which type of material the response is returning so the browser knows how to handle it. For example, the web browser may want to run a plug-in for video types and display text natively. The Content-Length in characters is normally also given. After the header information is finished, there is a newline followed by the content. Web browsers interpret any redirects that are returned by sending extra requests. Web browsers also interpret any HTML pages and make multiple requests for resources such as JavaScript files and images. Modern browsers do not wait until the server returns all the requests, but render the HTML page live as the server returns the parts. The GET verb is not very efficient for posting a large amount of data, as the URL has a length limit of around 2000 characters. Further, the end user can see the form data, and the browser may encode entities such as spaces to make the URL unreadable. There is also a security aspect: if you are typing in passwords in forms using GET, others may see your password or other details. This is not a good idea, especially at Internet Cafés where the next user who logs on can see the password in the browsing history. The POST verb is a better choice. Let us take as an example the Sakai demonstration login page http://localhost:8080/portal/login. The login page itself contains a form tag that points with the POST method to the relogin page. <form method="post" action="http://localhost:8080/portal/relogin" enctype="application/x-www-form-urlencoded"> Notice the HTML tag also defines the content type. Key features of the Post request compared to the GET are: the form values are stored as content after the header values, there is a newline between the end of the header and the data, and the request mentions data and the amount of data by the use of the Content-Length header value. The essential POST values for a login form with user admin (eid=admin) and password admin (pw=admin) will look like: POST http://localhost:8080/portal/relogin HTTP/1.1Content-Type: application/x-www-form-urlencodedContent-Length: 31eid=admin&pw=admin&submit=Login POSTs can contain much more information than GETs, and the request hides the values from the Address bar of the web browser. This is not secure. The header is just as visible as the URL, so POST values are also neither hidden nor secure. The only viable solution is for your web browser to encrypt your transactions using SSL/TLS (http://www.ietf.org/rfc/rfc2246.txt) for security, and this occurs every time you connect to a server using an HTTPS URL. SOAP Sakai uses the Apache Axis framework, which the developers have configured to accept SOAP calls via POST. SOAP sends messages in a specific XML format with the Content-Type, otherwise known as MIME type, application/soap+xml. A programmer does not need to know much more than that, as client libraries take care of the majority of the excruciating low-level details. An example SOAP message generated by the Perl module SOAP::Lite (http://www.soaplite.com/) for creating a login session in Sakai will look like the following Post data: <?xml version="1.0" encoding="UTF-8"?><soap:Envelope soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" ><soap:Body><login ><c-gensym3 xsi_type="xsd:string">admin</c-gensym3><c-gensym5 xsi_type="xsd:string">admin</c-gensym5></login></soap:Body></soap:Envelope> There is an envelope with a body containing data for the service to consume. The important point to remember is that both the client and the server have to be able to parse the specific XML schema. SOAP messages can include extra security features, but Sakai does not require these. The architects expect organizations to encrypt web services using SSL/TSL. The last extra SOAP-related complexity is the Web Service Description Language (http://www.w3.org/TR/wsdl). Web services may change location or exist in multiple locations for redundancy. The service writer can define the location of the services and the data types involved with those services in another file, in XML format. JSON Also worth mentioning is JavaScript Object Notation (JSON) (http://tools.ietf.org/html/rfc4627), which is another popular format passed using HTTP. A significant improvement in the quality of the end user experience during web browsing occurred when web developers realized that they could force browsers to load parts of a web page in at a time. This asynchronous loading enables all kinds of whiz-bang features, such as when you type in a search term and can choose from a set of search term completions before pressing submit. Asynchronous loading delivers more responsive and richer web pages that feel more like traditional applications than a plain old web page. JSON is one of the formats of choice for passing asynchronous requests and responses. The asynchronous communication normally occurs through HTTP GET or POST, but with a specific content structure that is designed to be human readable and script language parser-friendly. JSON calls have the file extension .json as part of the URL. As mentioned in RFC 4627, an example image object communicated in JSON looks like: { "Image": { "Width": 800, "Height": 600, "Title": "View from 15th Floor", "Thumbnail": { "Url": "http://www.example.com/image/481989943", "Height": 125, "Width": "100" }, "IDs": [116, 943, 234, 38793] }} To confuse the boundaries between client and server, a lot of the presentation and business logic is locked on the client side in scripting languages such as JavaScript. The scripting language orchestrates the loading of parts of pages and the generation of widget sets. Frameworks such as jQuery (http://jquery.com/) and MyFaces (http://myfaces.apache.org/) significantly ease the client-side programming burden. REST To understand REST, you need to understand the other verbs in HTTP (http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html). The full HTTP set is OPTIONS, GET, HEAD, POST, PUT, DELETE, and TRACE. The HEAD verb returns from the server only the headers of the response without the content, and is useful for clients that want to see if the content has changed since the last request. PUT requests that the content in the request be stored at the particular location mentioned in the request. DELETE is for deleting the entity. REST uses the URL of the request to route to the resource, and the HTTP verb GET is used to get a resource, PUT to update, DELETE to delete, and POST to add a new resource. In general, POST=create an item, PUT=update an item, DELETE=delete an item, and GET=return information on the item. In SOAP, you are pointing directly towards the service the client calls or indirectly via the web service description. However, in REST, part of the URL describes the resource or resources you wish to work with. For example, a hypothetical address book application that lists all email addresses in HTML format would look similar to the following: GET /email To list the addresses in XML format or JSON format: GET /email.xmlGET /email.json To get the first email address in the list: GET /email/1 To create a new email address, of course remembering to add the rest of email details to the end of the GET: POST /email And to delete address 5 in the list: DELETE /email/5 To obtain address 5 in other formats such as JSON or XML, then use file extensions at the end of the URL, for example: GET /email/5.jsonGET /email/5.xml RESTful services are more intuitively descriptive than SOAP services and they enable easy switching of the format from HTML to JSON to fuel dynamic, asynchronously-loaded web sites. Due to the direct use of HTTP verbs by REST, this methodology also fits well with the most common application type: CRUD (Create, Read, Update, Delete) applications, such as the site or user tools within Sakai. Now that we have discussed the theory, in the next section, we shall discuss which Sakai-related SOAP services already exist. Existing web services Sakai has built in, by default, the most community-requested web services, and there are also a few more services in the contributed section of the source code repository. This section describes the currently available services and the next section explains an example use, creating a new user. Recapping terminology In general, developers write web services for other developer's code to connect to (consume). Therefore, terminology can be confusing. In Sakai, a realm is a set of roles and their associated permissions. When you create a site, a copy is made from a specific realm template for that particular site type. The permissions can then be modified for the roles in the site, and members added to the site with one or other of the specific roles. Internally, Sakai uses AuthzGroups to keep track of groups of users. An AuthzGroup is an authorization group (a group of users, each with a role and a set of permissions of functions assigned to each role). A site contains pages; when you click on the tool menu for a given tool, normally, you will see one tool displayed in a page. However, for the home page tool, you will see more tools contained within a page.
Read more
  • 0
  • 0
  • 2015

article-image-implementing-document-management-alfresco-3-part1
Packt
21 Oct 2009
5 min read
Save for later

Implementing Document Management in Alfresco 3- part1

Packt
21 Oct 2009
5 min read
Managing spaces A space in Alfresco is nothing but a folder that contains content as well as sub spaces. The space users are the users invited to a space to perform specific actions such as editing content, adding content, discussing a particular document, and so on. The exact capability that a given user has within a space is a function of their role, or rights. Let's consider the capability of creating a sub-space. By default, in order to create a sub-space, one of the following must apply: The user is the administrator of the system The user has been granted the Contributor role The user has been granted the Coordinator role The user has been granted the Collaborator role Similarly, to edit space properties, a user will need to be the administrator or be granted a role that gives them rights to edit the space. These roles include Editor, Collaborator and Coordinator. Space is a smart folder Space is a folder with additional features, such as, security, business rules, workflow, notifications, local search capabilities, and special views. The additional features, which make the space a smart folder, are explained as follows: Space security: You can define security at the space level. You can designate a user or a group of users who can perform certain actions on the content in a space. For example, on the Marketing Communications space in the Intranet, you can specify that only users in the marketing group can add content, and other users can only see the content. Space business rules: Business rules, such as transforming content from Microsoft Word to Adobe PDF and sending notifications when content gets into a space, can be defined at the space level. Space workflow: You can define and manage the content workflow on a space. Typically, you will create a space for the content that needs to be reviewed, and a space for the content that has been approved. You will create various spaces for dealing with the different stages that the work flows through, and Alfresco will manage the movement of the content between those spaces. Space events: Alfresco triggers events when content moves into a space, when content moves out of a space, or when content is modified within a space. You can capture such events at the space level, and trigger certain actions, such as sending email notifications to certain users. Space aspects: Aspects are additional properties and behavior that can be added to the content, based on the space in which it resides. For example, you can define a business rule to add customer details to all of the customer contract documents that are in your intranet's Sales space. Space search: Alfresco search functions can be limited to a space. For example, if you create a space called Marketing, then you can limit the search to documents within the Marketing space, instead of searching the entire site. Space syndication: Content in a space can be syndicated by applying RSS feed scripts to a space. You can apply RSS feeds to your News space, so that other applications and web sites can subscribe to this feed for news updates. Space content: Content in a space can be versioned, locked, checked-in and checked-out, and managed. You can specify certain documents in a space to be versioned, and others not. Space network folder: Space can be mapped to a network drive on your local machine, enabling you to work with the content locally. For example, by using CIFS interface, a space can be mapped to the Windows network folder. Space dashboard view: Content in a space can be aggregated and presented using special dashboard views. For example, the Company Policies space can list all of the latest policy documents, that have been updated in the past one month or so. You can create different views for Sales, Marketing, and Finance departmental spaces. Why space hierarchy is important Like regular folders, a space can have child spaces (called sub spaces). These sub spaces can have further sub spaces of their own. There is no limitation on the number of hierarchical levels. However, the space hierarchy is very important for all of the reasons specified above, in the previous section. Any business rules and security defined for a space is applicable to all of the content and sub spaces within that space. Your space hierarchy should look similar to the following screenshot: A space in Alfresco enables you to define various business rules, a dashboard view, properties, workflow, and security for the content belonging to each department. You can decentralize the management of your content by providing access to departments at the individual space levels. The example of the Intranet space should contain sub spaces, as shown in the preceding screenshot. You can create spaces by logging in as the administrator. It is also very important to set the security (by inviting groups of users to these spaces).
Read more
  • 0
  • 0
  • 2006
Modal Close icon
Modal Close icon