Category: Computing

Build a Basic Authorize.net Payment Form

By blobaugh, March 10, 2010 7:44 pm

Zac Vineyard wrote a great tutorial on building a basic Authorize.net payment for and connecting to their payment gateway. Zac used some of my code and was kind enough to reference me for it, and since he wrote such a clean tutorial I see no need to write my own (used my code anywho!).

Check his out!

Build a Basic Authorize.net Payment Form

PHP: A new kind of template engine

By blobaugh, February 21, 2010 12:09 am

I have been developing a custom Content Management System (CMS) for Blam Designs and though there are several really good templating engines out there for PHP (such as Smarty) I find them usually bulky. Then there is also the need to learn the templating language as well. Though the templating languages are simple, it is one more thing for a designer to worry about knowing that pulls them away from their designs.

With that in mind I set out to find or create a new kind of templating system that works in a way similar to the JavaScript DOM, but works with PHP. The beauty of this sort of a system lies in the fact that a designer can create a layout with all the filler content and dummy text they can imagine and they do not have to remove any of it, or add any special template tags before uploading their snazzy layout to a web server. Simply add a normal HTML id attribute to whatever it is the designer wants to place content in and the template engine will automagically take care of the rest for you!

For example:

 
<div id="content">Lorem ipsum solet dolomar</div>
 

Might be replaced with:

 
<div id="content">Hello World! I am some content</div>
 

Sounds pretty cool doesn't it? I wound up creating my own PHP classes to handle this for me. I ran across a library called PHP Simple HTML DOM Parser (SHDP) which does all the heavy lifting for me. My class it basically a wrapper object that makes it easier to deal with the SHDP, in addition to providing some extra functionality. Using my class it is possible to replace the entire contents of a tag (such as <title>), replace by the element id (such as <span id="myid">), or through the use of "special" tags. The "special" tags I call special because they do not fit inside the rest of the template paradigm. A special tag works in much the same manner as a tag from a normal template system like Smarty would. Tags are created using curly braces and look similar to {{my_tag}}. I needed to keep these in in the case that some special piece of code needs to be dynamically added to the template, but is not an HTML tag or id. This happens with things such as file paths.

Though I may not be fully done tweaking the new template engine it is fully operational and I am going to provide a few code example and a download of my class with SHDP packaged with it. Eventually I would like to setup a new site dedicated to this template engine, and would like to fully re-write SHDP so that the template system is one complete unit, not relying on any external libraries.

HTML File:

 
<html>
<head>
	<title>Template Engine Demo</title>
	<meta name="author" content="Ben Lobaugh">
</head>
<body>
<div id="contents" style="border: 1px dashed #000000">
This is inside the contents div
</div>
<div id="d2" style="margin-top: 20px; border: 1px solid #000000">
This is inside the d2 div
</div>
 
{{special_tag}}
</body>
</html>
 

Replace the contents of a tag:

$t->setTag('title', 'This is a new title');

Replace the contents of an element by id:

$t->setById('contents', 'Hello World! I am new content');

Append the contents of an element by id:

$t->setById('d2', ' I am appended content', 'a');

Set a special tag

$t->setSpecialTag('special_tag', 'I am special!');

Final Output:

 
<html>
<head>
	<title>This is a new title</title>
	<meta name="author" content="Ben Lobaugh">
</head>
<body>
<div id="contents" style="border: 1px dashed #000000">Hello World! I am new content</div>
<div id="d2" style="margin-top: 20px; border: 1px solid #000000">
This is inside the d2 div
 I am appended content</div>
 
I am special!
</body>
</html>
 

Please be sure to template_engine_demo the template engine to see all the working examples.

If you use this template engine on your site please drop me a comment below.

Enjoy :D

What is an Extranet?

By blobaugh, February 17, 2010 12:29 am

extranet

Intrigued by why my Systems Analysis and Design professor consistently uses the word 'extranet' in a form in which I am unfamiliar I have embarked on a quest for realization. It is my extreme hope that in my quest and answer will reveal itself in a form with which I may enhance and compliment my currently miniscule knowledge of all things.

Let us start with what I currently understand an extranet to be:

An extranet is an extension of your internal network (also called the intranet, though I may have to defend that later as well) to the outside. This 'external' network may run over the internet (a large group of interconnected networks), or it may be a private connection.

What I currently understand the extranet to exist for:

The extranet is a network designed to connect with another private user or private network, primarily used as a connection between businesses or locations. Extranets do not need to be through businesses only, individuals who own a network (such as a home network) may link their network with an associates network via an extranet. One of the most common extranet configurations is through a Virtual Private Network (VPN). It could probably be argued that internet gaming servers use extranets for their players, however I am not going to go into that, I simply want the possibility to be seen.

What I currently understand extranets to be used for:

An extranet is commonly used as the connection through which another party can access a company's resources. This may be data shares (such as documents), it may be to access an outward facing web application, it may be to access programs which other organizations (such as product suppliers) can use. There are about as many uses for an extranet as there are ideas you can conceive.

How I currently understand the word 'extranet' to be misused:

The word 'extranet' is misused as a label for what is available on the extranet. Saying something like “the extranet is the application suppliers use” is a mislabeling of the extranet. The proper wording should have been “the application suppliers use is available on the extranet”. This properly shows that the extranet is not the application but rather the method of accessing the application. Similarly saying “the extranet is the developer's file repository” is another mislabeling. “The developer's file repository is on the extranet” is the proper wording.

I currently understand 'extranet' is misused because:

As with all other context sensitive disciplines, technology has it's own subset of words and ideas those not a part of it do not understand. Some call this a 'lingo'. Often those outside the discipline use a term incorrectly and it is easier for those within the discipline to simply understand what is meant than to explain to the user why they are using a term incorrectly. Sometimes this leads to a word or phrase becoming common language. That presents a danger to those within the discipline to whom the errant word or phrase belongs. It creates a sense of confusion and loss of dis-ambiguity that can be hard to correct later on, thus it is important that those inside a discipline understand those words or phrases that are incorrect and how to reinterpret them properly.

How I went about determining what 'extranet' means:

  • First I hit Wikipedia. Though many in education believe Wikipedia to be inaccurate and full of errors, Wikipedia in fact has a full staff of people dedicated to ensuring information is correct and highlighting area that may be sketchy and are in need of support. Wikipedia is accurate enough now that much of it is released in book form, similar to that of an encyclopedia.

  • Next I went to http://google.com to verify Wikipedia's information. I used the following search terms:

    • extranet

    • what is an extranet

  • I compiled a listing of definitions which can be found below, and read several articles, which will also be linked below.

Here are some of the definitions I found on the first page:

  • A private computer network that uses Internet protocols and can be accessed by authorized individuals via the Internet.

  • The extension of a company's intranet out onto the Internet, e.g. to allow selected customers, suppliers and mobile workers to access the company's private data and applications via the World Wide Web. Generally an extranet implies real-time access through a firewall of some kind.

  • A network that supplements a closed intranet by providing access to customers, suppliers, subcontractors, and others outside the organization who have a need for selective information from the organization. It is not accessible to the Internet at large.

  • A secure extension of an Intranet that allows external users to access some parts of an organisation’s Intranet

  • Similar to an Intranet, an extranet is designed for authorized access by outside users.

  • Private networks, connected by the Internet, which allow only users who have a valid password or digital certificate to use the system. The Internet, by comparison, allows any user to access without the verification of the identity of the user.

  • An extranet is a software application that delivers information from within an organisation to a defined group of users outside of that organisation, typically customers, suppliers or business partners. For example, a telephone company may deliver billing information to it’s customers over the web via an extranet.

    • http://www.oranz.co.uk/glossary_text.htm

    • Ben Note: This definition seems to both misuse and use correctly from my current understanding. Take note that it first says it is an application (misuse) and then says via, which implies the extranet is the delivery medium.

  • An intranet that is accessible to computers that are not physically part of a company’s own private network, but that is not accessible to the general public. For example, an extranet allows vendors and business partners to access private areas of a company web site. Users from outside the company’s network usually access the extranet using VPN.

  • A private computer network that uses Internet technology to link an organisation with its suppliers, customers and other collaborators.

  • An extranet is a private network that uses Internet technology and the public telecommunication system to securely share part of a business's information or operations with suppliers, vendors, partners, customers, or other businesses. An extranet can be viewed as part of a company's intranet that is extended to users outside the company. It has also been described as a "state of mind" in which the Internet is perceived as a way to do business with other companies as well as to sell products to customers.

  • An "intranet" is the generic term for a collection of private computer networks within an organization. An "extranet" is a computer network that allows controlled access from the outside for specific business or educational purposes. Intranets and extranets are communication tools designed to enable easy information sharing within workgroups.

  • An extranet is a private virtual space to securely collaborate, share information or integrate operations with travelling teams, suppliers, vendors, partners, or customers. A few examples are a sales extranet containing order forms and client directories for the sales team, a partner extranet enabling management of joint tasks, or a customer extranet portal where you collaborate on specifications documents with clients.

  • Answers.com shares several definitions:

    • An extension of an institution's intranet, especially over the World Wide Web, enabling communication between the institution and people it deals with, often by providing limited access to its intranet.

    • A Web site for customers rather than the general public. It can provide access to research, current inventories and internal databases, virtually any information that is private and not published for everyone. An extranet uses the public Internet as its transmission system, but requires passwords to gain entrance. Access to the site may be free or require payment for some or all of the services offered.

    • Private network that uses the Internet protocols and the public telecommunication system to securely share part of a business's information or operations with suppliers, vendors, partners, customers, or other businesses. An extranet can be viewed as part of a company's Intranet that is extended to users outside the company.

    • http://www.answers.com/topic/extranet

Articles I read:

My Conclusion:

The large majority of the articles speak of an extranet as being a network that is connected into and resources are utilized over. There was an article that speaks of an extranet as being a website, however it seems to me that based off the weight of the articles speaking of an extranet as a network that the author of the article using the website as an example of an extranet must be misusing the word. What the author is most probably doing is using the extranet as an alias for what is running on the extranet. If the website is the only thing running on the extranet it might possibly be acceptable to alias the extranet to the website, however the questions most likely asked of a network administrator are “What does your extranet do?”, and “What runs on your extranet?”. The answer to the first may look like “It is a website that does...”, however more than likely the response would sound like “It runs our outward facing website”, which implies that the extranet carries something and is not the application itself. Any answer to the second question assumes the extranet is the medium for transport, not an application.

What I now understand an extranet to be:

An extranet is an extension of an internal network. Extranets seem to primarily be run over the internet, though private connections may be used. Sometimes an outward facing web application is called an extranet, though it seems that it is simply delivered over an extranet as it's only service. It seems to me that saying a web application that suppliers use is called an extranet may be acceptable here, but only if the person understands that the 'extranet' used is not referring the actual network, but to an application running on the network. It must be translated in the person's head to be proper.

What I now understand extranets to exist for and be used for:

Extranets are used by external networks and users to connect them into a private network, usually at a business. Using an extranet allows the outsider to utilize network resources, such as network data shares (documents) and applications, that are not normally available to the general public.

Final comments:

I believe that an extranet is an extension of an intranet that can be used by outsiders to gain access to network resources, just as my original understanding stated. I also think that extranet is a term that can and is misused, both in the professional and academic worlds. There are many words currently in the english dictionary that have more than one unique meaning. It could be possible that what I am seeing is a shift towards creating an additional definition for extranet, however the evidence currently overwhelmingly is in favor of my original definition. As this is the case, great care should be taken when using extranet to refer to anything other than the network itself. If extranet is used to denote the application running over the extranet it should be known by all parties involved that the extranet term in this instance is being used not in the standard definition way, and the listeners should assume the application is in fact simply a service provided by the extranet, and not the extranet itself.

New Website Launch: Integrity Excavation and Rock Products

comments Comments Off
By blobaugh, February 6, 2010 3:53 pm

A friend of mine recently took a course on HTML web design and after completing her class she developed a website for Integrity Excavation and Rock Products. As a first site she did a great job. Go check it out.

Integrity Excavation and Rock Products

C++: Virtual Token Ring Network

By blobaugh, February 2, 2010 10:06 pm

My networking professor handed out a group project to build a virtual token ring network and I thought I would share my findings here. Before you say anything, I know it is not a true token ring network, but it sorta acts like one which was more the goal of the project.

My group partner and I went through several different models, which included; building a virtual DHCP server and virtual cables, telling the program at run time who it's neighbor was, sending out a broadcast and having the virtual nodes organize themselves into a network, and a few others. We finally settled on pulling out a switch and creating a network of static IPs that we controlled. The program attempts to send to the next IP number from itself and if it cannot find it the token is sent to the first node. An unintended side effect is that we have the ability to add and remove machines at the highest IP number without breaking the ring. The requirement was only that it worked with three machines.

This code is not the cleanest, nor is it in any way awesome, and there are probably a ton of things I can take out of it to make it better, but it runs beautifully on the Dell Mini 10s running Ubuntu that I tested it on with a 5 port Netgear switch. Just make sure your network is in the range 192.168.0.1 and the machines go in sequential order (e.g. 192.168.0.1, 192.168.0.2, 192.168.0.3)

 
/*
 * Virtual Token Ring Network
 *
 * Networking II
 * Spring 2009-2010
 * Prof: Xueyi Wang
 * Group: Ben Lobaugh, Jake Bodenstab
 *
 * Project Description: Sorta creates a virtual token
 *      ring network simulation
 */
 
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <string>
#include <string.h>
#include <strings.h>
#include <sstream>
#include <iostream>
 
using namespace std;
 
// Global Constants and Variables
int PORT = 55555, node, s_sockfd , s_clilen, s_n;
struct message{
        int sender;
        int receiver;
        string message;
};
struct token{
        int type; // 1 = empty token, 2 = token with data
        int valid;
        message msg;
        int checksum;
        int turn;
};
struct sockaddr_in s_serv_addr, s_cli_addr;
 
// Function Definitions
void getToken(char* token);
void sendToken(char* token);
bool messageExists();
void createServerSocket();
void error(string msg);
 
int main(int argc, char** argv) {
        char* token;
		string start_token;
 
		node = atoi(argv[1]);
		cout << "Node: " << node << endl << endl;
 
		createServerSocket();
 
		if(node == 1) {
			cout << "Start token? (y/n): ";
			cin >> start_token;
 
			if(start_token.compare("y") == 0) {
				cout << "\nInitializing Token\n";
				sendToken(token);
			}
		}
 
		cout << "**** Ctrl-C Terminates **** \n\n";
 
		while(1) {
			getToken(token);
 
			if(token[0] == 2) {
				// Token Contains a message
				if(token[2] == node) {
					// Message is from us. Erase it and change token type to 1
					token[2] = -1;
					token [3] = -1;
					token[4] = -1;
					token[0] = 1;
				} else if(token[3] == node) {
					// Message in token is for us. Display it
					cout << "--------------\n";
					cout << "From: " << token[2] << endl;
					//cout << token.msg.message << endl;
				}
			} else if(token[0] == 1) {
				// Token does not contain a message
				if(messageExists()) {
					// There is a message to send. Load message into token and change type
 
					 // Open file ./message.tok
					 // Read first line as the receiver
					 // Rest of file is message 
 
					token[0]  = 2;
				}
			} else {
				// This token is a type we do not know about
				// Don't worry about this token, just forward it
			}
			sleep(2);
			// Send token along it's merry way
			sendToken(token);
		}
 
       return (EXIT_SUCCESS);
}
 
void getToken(char* token) {
	int newsockfd;
	/*
	 * Create a server socket on PORT
	 * Listen on socket until message is received
	 * If message is of type token load it into token
	 * Close socket
	 * Return filled token
	 */
     listen(s_sockfd,5);
     s_clilen = sizeof(s_cli_addr);
     newsockfd = accept(s_sockfd,
                 (struct sockaddr *) &s_cli_addr,
                 (socklen_t*) &s_clilen);
     if (newsockfd < 0)
          error("ERROR on accept");
     bzero(token,256);
     s_n = read(newsockfd,token,255);
     if (s_n < 0) error("ERROR reading from socket");
 
	cout << "I've got the token\n";
}
 
void createServerSocket() {
 
	s_sockfd = socket(AF_INET, SOCK_STREAM, 0);
     if (s_sockfd < 0)
        error("ERROR opening socket");
 
	int on = 1;
	  if ( setsockopt ( s_sockfd, SOL_SOCKET, SO_REUSEADDR, ( const char* ) &on, sizeof ( on ) ) == -1 )
	    error("ERROR setting socket options");
 
     bzero((char *) &s_serv_addr, sizeof(s_serv_addr));
     s_serv_addr.sin_family = AF_INET;
     s_serv_addr.sin_addr.s_addr = INADDR_ANY;
     s_serv_addr.sin_port = htons(PORT);
 
     if (bind(s_sockfd, (struct sockaddr *) &s_serv_addr, sizeof(s_serv_addr)) < 0)
              error("ERROR on binding");
}
 
void sendToken(char* token) {
	int to;
	string ip = "192.168.0.";
 
	// Start Socket Vars
	int sockfd, n;
    struct sockaddr_in serv_addr;
    struct hostent *server;
	// End Socket Vars
 
	// Find the next node to send to
	to = node + 1;
	std::ostringstream sin;
	sin << to;
	std::string val = sin.str();
	ip.append(val);
 
	/*
	 * Create socket connection to next node
	 * Send token
	 * Close socket
	 */
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0)
        error("ERROR opening socket");
 
	try {
	    server = gethostbyname(ip.c_str());
	    if (server == NULL) {
	        error("ERROR, no such host\n");
	    }
 
	    bzero((char *) &serv_addr, sizeof(serv_addr));
	    serv_addr.sin_family = AF_INET;
	    bcopy((char *)server->h_addr,
	         (char *)&serv_addr.sin_addr.s_addr,
	         server->h_length);
	    serv_addr.sin_port = htons(PORT);
 
	    if (connect(sockfd, (struct sockaddr*) &serv_addr,sizeof(serv_addr)) < 0)
			throw 1;//("ERROR connecting");
 
		cout << "Token Sent To: 192.168.0." << to << endl << endl;
	} catch (int i)  {
		cout << "Could not contact " << ip << " sending to 192.168.0.1\n\n";
		server = gethostbyname("192.168.0.1");
	    if (server == NULL) {
	        error("ERROR, no such host\n");
	    }
 
	    bzero((char *) &serv_addr, sizeof(serv_addr));
	    serv_addr.sin_family = AF_INET;
	    bcopy((char *)server->h_addr,
	         (char *)&serv_addr.sin_addr.s_addr,
	         server->h_length);
	    serv_addr.sin_port = htons(PORT);
 
	    if (connect(sockfd, (struct sockaddr*) &serv_addr,sizeof(serv_addr)) < 0)
	        error("ERROR connecting");
 
	}
 
	bzero(token,256);
    n = write(sockfd,token,strlen(token));
    if (n < 0)
         error("ERROR writing to socket");
 
	close(sockfd);
	unlink(ip.c_str());
}
 
bool messageExists() {
	bool ret = false;
	return ret;
}
 
void error(string msg) {
    perror(msg.c_str());
    exit(0);
}
 

jQuery: Oh How I Love Thee

By blobaugh, November 16, 2009 5:03 pm

I started using jQuery last week and I am finding it to be a great library so far. It is very easy to interact with elements on the page in fun and creative ways.

As a sample, I have been working with the Northwest Nazarene University web team and they wanted to develop a simple wizard they can put on any page that will help prospective students find the degree they are interested in. I decided to tackle that task. At first I was looking at slide show sample, then one of the other developers showed me the beauty of .load(), which allows me to load into any arbitrary element the contents of any file or web address. After playing with .load() and the event handlers for an hour I figured out a way to implement what they wanted. It took me maybe 4 hours going from ground zero of no knowledge on the subject to implementing a working system complete with calls to a backend PHP file that gets the contents for the wizard from the database. jQuery is really neat, I highly encourage other web developers to check it out. A working sample may be found here or on NNU's website.

Here is the jQuery code I used. Try not to be too critical, I am positive there has to be a better way of doing this. I still am learning the vast amount of options available to me in jQuery.

 
<script type="text/javascript">
 
$(document).ready(function() {
	$('#programs').load('programs.php', {}, function() { // Load the degree options
           $('.choice').bind('click', function() { // Load the school in that degree
	        $('.choice').bind('click', function() { // Load the list of degrees
						$('#programs').load($(this).attr('href'), {}, function () {
							$('.choice').bind('click', function() {
								$('#programs').load($(this).attr('href'), {}, function () { // Load a degree
					                        });
							});
					});
				});			
		 });
	});
 });
</script>
 

New Website Launch: Lewis County Chaplaincy

By blobaugh, August 17, 2009 8:54 pm

Launch another website this week. This one is for the Lewis County Chaplaincy, a group that serves the needs of emergency services personnel as well as people throughout the community in need.

Check out the Lewis County Chaplaincy website.

PHP: Fatal error: Trying to clone an uncloneable object of class mysqli

comments Comments Off
By blobaugh, July 18, 2009 11:20 am

I was working on a report for a client when I discovered this rather odd error: Fatal error: Trying to clone an uncloneable object of class mysqli. I am still not sure what caused this error, but there does seem to be a quick fix for it.

ini_set('zend.ze1_compatibility_mode', 0);

Here is what the PHP manual has to say about zend.ze1_compatibility_mode:

Name  - zend.ze1_compatibility_mode
Default - "0"
Changeable -  	PHP_INI_ALL
Changelog -  	Available since PHP 5.0.0. Removed in PHP 5.3.0

Enable compatibility mode with Zend Engine 1 (PHP 4). It affects the cloning, casting (objects with no properties cast to
FALSE or 0), and comparing of objects. In this mode, objects are passed by value instead of reference by default.

I hope that helps someone out there.

PHP: __call Magic

By blobaugh, July 10, 2009 8:24 am

Lastnight as I was researching how to build a plugin system for a cms I am working on I ran across several implementations using the __call method. I had not used it before myself, but after doing a little googling I devised a test. It really is quite simple and can be a powerhouse in your applications.

First, what is this __call thing even for? Remember those classes you built? Then remember how you were doing something else and forgot you had not yet created a method in the class to handle it and your application blew up? That is where __call comes to the rescue! Whenever a method in your class is called that does not exist PHP automagically sends the request to the __call() method. If __call exists then PHP assumes it knows how to take care of the missing method. If it does not exist is when things get hairy, fatal errors get thrown, the application blows up, and you loose your job cause one of the company execs got a phone call while in Hawaii. Oops, consider using __call in any of your important objects :D

Let's start with an example of the calling code:

$Car = new Car();
$Car-&gt;ZoomZoom(120);
$Car-&gt;Fly('Super Jets');

I am using a Car for this example. Most cars can go pretty fast, but currently there are no cars that can fly. Normally calling Fly() would cause a fatal error right? Not this time.

Take a look at the Car class:

class Car {
 
        // Constructor
        public function __construct() {
                echo "Your car has arrived";
        }
 
        // Let's roll! How fast?
        public function ZoomZoom($Speed) {
                echo "And we're off at an amazing $Speed! Hope you're buckled!";
        }
 
        /*
         * This is a magic function.
         * This function gets called when a method that does
         * not exist in this class is called. Once inside this
         * method you are free to deal with it however you
         * would like
         */
        public function __call($Function, $Args) {
                $Args = implode(', ', $Args);
                echo "I can't $Function you idiot! Especially with $Args! Hoser";
        }
}

Note the two arguments. They do not have to be called that, but it will help you remember what they are in 6 months.

Here is the output:

Your car has arrived
And we're off at an amazing 120! Hope you're buckled!
I can't Fly you idiot! Especially with Super Jets! Hoser

Pretty simple eh? I hope you realize the potentially huge impact the use of this magic method could have on your application. Heck, if nothing else use it with a logger to log errors.

Cheers,

Website Redesign: Enchanted with Nature

By blobaugh, July 5, 2009 10:33 pm

I hadn't intended on redoing any websites tonight, but while I was talking with maddslacker of my Linux group he mentioned that he did not like how his mother-in-law's site looked. He sent me a link and I made a couple suggestions, then I saved the page with Firefox and did a little editing to show him what I was talking about. Soon I had redone almost the entire layout. Since it is a simple two page static site it did not take very long at all.

Here is the original look

Seeing that there was potential for a good layout already I simply moved the content to the middle, put a border around it, then made the background gray. The font size for the testimonials continued to scream at me, distracting from the page so I made the text smaller, then thought a rotator would tidy the look up. After looking at the rest of the page I realized I could move some other elements around to provide a contrast between the content the visitor should see, and the additional info needed to make the site useful.

By this point I had completely changed the look and maddslacker liked what he saw. Even though it started out as an example of what could be done to improve it, I wound up simply redoing the entire site.

Here is the fresh new layout

Another site successfully and satisfactorally designed.

Visit the Enchanted with Nature website!

Theme by Blam Designs
Based on Themocracy