PHP

A Linux Web based tool completed in just 2 weeks

A new Visual WebGui RIA Platform showcase is published:
A Linux (Mono) Web based OS Deployment tool completed in just 2 weeks

The company needed to develop a solution which would operate as an OS Deployment tool that is customized for the needs of their Datacenter according the specific design parameters given.

The team decided not to use PHP but to use Mono (mod_mono) with Visual WebGui because of the short timeframe they had for deploying the solution and since Visual WebGui provided the easiest and quickest graphical development possible.

The web development process was straight forward. While the final goal was well defined, some of the concepts and functions were being defined while coding the solution. The Visual WebGui unique approach enabling easy integration of UserControls and intuitive graphical development allowed for this unstructured development cycle which led to an extremely shortened process as stated by Axel Westerhold: "Because of the easy graphical development environment and the integration into Visual Studio we were able to roll out the product within 2 weeks."

Go to the full case study.

Having Fun with Pligg - Installing

Last time I told you that I was setting up a Pligg site for my new video game site, wastingtimegames.com. This is second in a series of posts where I will explain how to get a working customized Pligg site.

To install Pligg you will first need to download the files from pligg.com. The most current release is 1.0.0 RC2. Once you download the .zip file you will need to unzip all of the files into a folder.

To get the rest of the software installed you will just need to follow the below directions, taken from the Pligg readme file.

  1. Create a mysql database. If you are unfamiliar with how to create a mysql database, please contact your web host or search their support site. Please pay careful attention when creating a database and write down your database name, username, password, and host somewhere.
  2. Rename settings.php.default to settings.php. Do the same for /libs/dbconnect.php.default.
  3. Upload the files to your server (please note that your server will need to be running PHP 4.3.0 or higher).
  4. CHMOD 755 the following folders, if they give you errors try 777.
    • /admin/backup/
    • /avatars/groups_uploaded/
    • /avatars/user_uploaded/
    • /cache/
    • /cache/admin_c/
    • /cache/templates_c/
    • /languages/ (And all of the files contained in this folder should be CHMOD 777)
  5. CHMOD 666 the following files
    • /libs/dbconnect.php
    • settings.php
  6. Open /install/index.php in your web browser. If you are reading this document after you uploaded it to your server, click on the install link at the top of the page.
    • Select a language from the list.
    • Fill out your database name, username, password, host, and your desired table prefix.
    • Create an admin account. Please write down the login credentials for future reference.
    • Make sure there are no error messages!
  7. Delete your /install folder.
  8. CHMOD 644 libs/dbconnect.php
  9. Open /index.php
  10. Log in to the admin account using the credentials generated during the install process.
  11. Log in to the admin panel ( /admin ) and you will then be presented with information intruducing you to Pligg.
  12. Configure your Pligg site to your liking. Don't forget to use the Modify Language page to change your site's name.

Once you are done with these steps you'll have a basic Pligg site running. Next time I'll explain how to change the language features and install modules.

Having Fun with Pligg

Tagged:  

Pligg is a content management system that has evolved from a Digg clone to a full feature content management system. I've been working on some on-line video games and have been working on a site to host them. After some thought about the site, I decided to use Pligg and to allow users to submit their own game content as well as post my games.

The Pligg install is very easy to get up and running. So, my next few posts will be about the Pligg install and how I will modify the template and add modules to the site.

You can see the site that I've setup at wastingtimegames.com. The site is fully functional although I will be adding new features over the next few weeks and will be posting my games soon. So, stay tuned to see how to get your own Pligg site running quickly.

You can learn more about Pligg here.

Eclipse Announces PDT 2.0 Release

Tagged:  

The Eclipse Foundation has announced the 2.0 release of the Eclipse PHP Development Tools project (PDT). The project is sponsored by Zend and forms the basis of the commercial product Zend Studio.

Major features of this release include:

  • A Hierarchy view for navigating the PHP object hierarchy.
  • Easy searching for PHP types.
  • Override indicators for PHP methods that override other methods.
  • Performance improvements from using a new indexing and caching engine from the DLTK project.
  • Improved code completion.

The PDT project is one of Eclipse's most popular downloads, with more than 1 million downloads to date. The plug-ins are available from the download page or through the download site at:

http://download.eclipse.org/tools/pdt/updates

Aptana PHP Development Environment Released

Tagged:  

You may have used Aptana's IDE for Ajax development. The IDE is a very good one and it just got better for us PHP developers. Aptana has announced the release of a PHP plugin for their IDE.

Below is an excerpt from the announcement.

PHP development and deployment just got way easier. Today, we're pleased to announce the 1.0 availability of the Aptana PHP development environment. It's got all the things you'd expect from a PHP IDE, plus all the Ajax tooling and other power tools from Aptana Studio. Combine that with the integrated PHP app hosting, staging and management features in Aptana Cloud and you've got an end-to-end PHP development and deployment environment with unprecedented ease of use.

You can read the full post here.

It's always good to see one of my favorite languages get more support in tools that many of us already use. Thanks Aptana, you gave me something to play with this weekend.

Netbeans 6.5 Released

Tagged:  

In the tradition of "Release early, release often", the Netbeans team has released version 6.5, continuing the rapid release cycle the project set with 5.5, 6.0, and 6.1. There many new features, most notably support for Groovy /Grails and PHP. Here's a short list of the other "new and notables":

  • A new "Compile and Deploy on Save" feature for Java applications.
  • Support for the Nimbus look and feel in the Swing GUI builder (Matisse)
  • Big improvements in the JavaScript support, particularly in the area of debugging.
  • Support for Ruby on Rails 2.1 (JRuby 1.1.4 is bundled)
  • Improved SQL support, including SQL history and editor auto-completion.

There is also an early access release of Python support in Netbeans that is available as a separate download.

Get Netbeans 6.5 here.

Vista-like [not in a buggy way] JavaScript/PHP Datepicker

Tagged:  

Over at dev.base86, they've released version 2 of their Vista-like Ajax Calendar (vlaCalendar). The vlaCalendar is an unobtrusive JavaScript library that ports the UI functionality of the Windows Vista datepicker control to the web. The library requires the MooTools JavaScript framework as well as PHP.

In their own words:
Key features:

  • Authentic Vista look-and-feel
    • Quick navigation by jumping back and forth between months, years and decades without drop-down boxes
    • Smooth transition animations
  • Customizable features
  • Lightweight (compressed 8,50kB)

New features in version 2:

  • Cleaner and more developer centered - easily editable - CSS, PHP and javascript code
    • Easily changeable date labels (e.g. different languages)
    • Easily stylable. Styles are created on top of the general style; the download include two example styles
    • Both normal and datepicker calendar can be instantiated multiple times

The vlaCalendar has been tested on:

YouTube Data API Changes and Player API

If you haven't heard the big news yet, the YouTube Data API has been updated and the YouTube Player APIs have been released. The APIs look very interesting with some much wanted features.

The below is the big news from the YouTube Blog.

Here's the sound byte: We now support upload, other write operations, and internationalized standard feeds. (And there was much rejoicing!) We're also introducing player APIs and a chromeless player -- a barebones player SWF that's fully customizable and controllable using the player APIs.

The Data API now allows for reading (nothing new), writing and uploading of data (the latter two are the big news). The API allows for you to do many things that can be done in YouTube, such as add comments about a video or upload videos to YouTube. Libraries for the API are available for Java and PHP (sorry Ruby developers at least for now).

You can read more about the Data API here.

The Player APIs now offer a Flash (Actionscript 2.0) API and a JavaScript API to allow more control over the player. The JavaScript API and Flash API are very similar (which makes since as they are both based on ECMA Script). The APIs have some very powerful hooks into the videos. My personal favorite hook is player.getPlayerState() which returns the state of the player. Possible values are unstarted (-1), ended (0), playing (1), paused (2), buffering (3), video cued (5).

You can read about the JavaScript API here and the Flash API here (note that the Flash API is almost exactly the same as the JavaScript API, so you will need to read both references if you are going to use the Flash API).

Perhaps Even bigger news is the release of the chromeless player. Below is an excerpt about the chromeless player from reference.

Getting Started

First off, you need a developer key. To register for one, visit the registration page.

The chromeless player consists of two SWF files. apiplayer.SWF contains the actual video playing functionality. cl.SWF is a loader SWF that loads apiplayer.SWF and exposes the player's API functions. It also provides security sandbox restrictions for the apiplayer.SWF, so loading SWFs cannot access elements inside the player directly.

The player can be controlled via two methods — by loading the SWF into another SWF (or Flash website, etc.), or by embedding it directly in an HTML page and using JavaScript to control the player. The JavaScript controls are identical to the embedded player's JavaScript API.

The URL to load the chromeless player SWF is:

http://gdata.youtube.com/apiplayer?key=DEV_KEY

Functions

The following operations are available in addition to the ones listed in the JavaScript API documentation.

loadVideoById(videoId:String, startSeconds:Number):Void
Load the specified video and starts playing the video. If startSeconds (number can be a float) is specified, the video will start from the closest keyframe to the specified time.
cueVideoById(videoId:String, startSeconds:Number):Void
Loads the specified video's thumbnail and prepares the player to play the video. The player does not request the FLV until playVideo() or seekTo() is called. startSeconds accepts a float/integer and specifies the time that the video should start playing from when playVideo() is called. If you specify startSeconds and then call seekTo(), the startSeconds is forgotten and the player plays from the time specified in the seekTo() call. When the video is cued and ready to play, the player will broadcast a video cued event (5).
setSize(width:Number, height:Number):Void
Sets the size of the chromeless player. This method should be used in favor of setting the width + height of the MovieClip directly. Note that this method does not constrain the proportions of the video player, so you will need to maintain a 4:3 aspect ratio. When embedding the player directly in HTML, the size is updated automatically to the Stage.width and Stage.height values, so there is no need to call setSize() when embedding the chromeless player directly into an HTML page. The default size of the SWF when loaded into another SWF is 320px by 240px.

You can read more about the new features at the YouTube API Blog.

I think that these new feature really make it possible to make some great mash-ups with YouTube. If you create a cool mash-up using some of the new features of the API or use the the Player APIs or use the chromeless player then I would love to hear about it (you can leave it in the comments or you can write a blog post about it using your free Ajaxonomy account.

Creating a Simple JavaScript Game Board

Over at the Web Cash blog they have posted two tutorials on Game development in JavaScript, Ajax and PHP. The first tutorial explains the concept and describes how to make a game board.

Below is an excerpt from the first tutorial.

Game Development with JS, AJAX, and PHP

How can we use JS and PHP - connected through AJAX - to develop an online game?

Javascript’s main use for us is to create an interface for the game. Through Javascript we can capture user input - i.e. mouse clicks and text. We can also alter the game’s output - changing the HTML of the page, adding images, and moving things around. Javascript will provide a lot of the front end work.

PHP, on the other hand, is a more robust language for dealing with the logic of the game. PHP could be useful for developing an AI and evaluating winning conditions. It also offers a great way to store information for later use through flat files or database integration.

If we’re going to use both Javascript and PHP, we’ll need to use AJAX. This is the glue that holds the whole thing together. It will send input from the main Javascript to the PHP processing scripts. The PHP script will then send info back to the Javascript and it will alter the page’s layout accordingly.

Read the full first tutorial here.

The second tutorial goes into more detail as to how you would start creating a simple game. By the end of the tutorial you have a complete simple tic-tac-toe game (the game needs more logic added to be finished, but the concept is there).

Below is an excerpt from the second tutorial.

Creating Graphics

Tic Tac Toe Circle ImageI created two images in Inkscape to use for this board. Each is a 50×50 png file - with a gray background and a black border. The actual token (the circle or cross) is red and laid on top of the gray background.

Tic Tac Toe Cross ImageI’m no great artist, but these should work for a functional demo. We can worry about making nice circle and cross tokens later. I think getting the game working is more important than making it pretty from the get-go.

Turning Our .js Script into a Class

In making this a functional board, I also converted the script into an actual class. The script may end up being somewhat large and unwieldy - and an object oriented approach may help us keep it tidy and clean. Or it may add a lot of overhead… but I like objects.

In our HTML file, we’ll create the object like this.

<script type="text/javascript">
var tictactoe = new game();
</script>

In the attached .js file, we actually define the game object. Here’s part of the object definition.

function game() {
  //  Array to hold the bgImgs
  this.bgImgs = new Array();
    this.bgImgs[0] = 'tttcircle.png';
    this.bgImgs[1] = 'tttcross.png';

 
  //  Player information			
  this.currentPlayer = 0;
  this.players = new Array();
    this.players[0] = "Player One";
    this.players[1] = "Player Two";

 
   return true;

This class constructor does some of the initialization for us.

First, it creates an array with background images. At the moment we’re only using two images. However, this technique would be useful if you had a more complex map - with 10-15 images you could lay over a div.

Second, we create some player information variables. The ‘currentPlayer’ property is going to track whether the ‘cross’ or ‘circle’ player is currently taking a turn. The ‘players’ array will just hold the names of those players for now.

The Background Image Changing Function

One of the major methods of this class will be changeBackground(). Just like in the previous example, this method will change the background style of a given div tag. This way we can change it from an open square to a circle or cross token.

  this.changeBackground = function (boxId) {
    var box = document.getElementById('box-' + boxId);
    box.style.background = 'transparent url(' + 
      this.bgImgs[this.currentPlayer] + ') top left no-repeat';

 
    box.removeAttribute('onClick');
 
    this.changePlayer();
  }

This should be pretty straightforward. We’re storing the ‘div’ element in the ‘box’ variable. We’re then setting the ‘background’ style as we would in a css style. Remember that we stored the background images in an array (this.bgImgs) and this.currentPlayer corresponds to a key in the this.bgImgs array (either 0 or 1).

The ‘box.removeAttribute()’ method is removing ‘onClick’ from that div. We can’t use a square a second time, so we might as well eliminate the onClick handler altogether.

Finally, this.changePlayer() is calling a new method. This is going to help us switch from Player One’s turn to Player Two’s turn.

One Turn to Another - this.changePlayer()

The last method we need to declare for this class at the moment is changePlayer.

This will toggle the active player - which in turn affects whether a circle or cross is placed on the board. For some added effect, we’ll also create a new html element to display a message that says who’s turn it is.

  this.changePlayer = function () {
    //  Switch the active player

    if (this.currentPlayer == 0) {
      this.currentPlayer = 1;
    } else {

      this.currentPlayer = 0;
    }
 
    //  Get a reference to our 'message' element and create the message
    var box = document.getElementById('message');
    var msg = "It is " + this.players[this.currentPlayer] + "'s turn.";
    var txt = document.createTextNode(msg);

 
    //  Erase any existing text
    while (box.hasChildNodes()) {
      box.removeChild(box.lastChild);
    }

 
    //  Add the text node (our message) to our element
    box.appendChild(txt);
  }

Again, this is pretty straightforward. The DOM functions are amazingly simple - once you see how they work.

‘box’ is a reference to our element (id = message). The msg variable is a temp variable I created to hold the string. The ‘createTextNode’ method creates a new block of text (with our msg) that we can then insert into an HTML element.

The while() loop is simply there to erase any old text. As long as our ‘box’ element has any child nodes inside of it (text or other HTML tags), the loop will execute and delete one of those child nodes each time. This way we have a clean slate on which to write down who’s turn it is.

Read the full second tutorial here.

Although the tutorial only shows a simplistic tic-tac-toe game you could use the concepts as a starting point to build your own web games. As always if you have made any cool games we would love to hear about them either in the comments or you can write a blog post about it using your free Ajaxonomy account.

Simple AJAX chat in PHP

Tagged:  

Over at the .NET Butchering (and JAVA messes) blog they have posted a very good tutorial on creating a Chat application in PHP using Ajax. In Web 2.0 social applications chat is very often a desired feature.

Below is an excerpt from the tutorial.

The first thing to be done is creating MySQL tables:



CREATE TABLE `db_name`.`chat_rooms` (

`id` int(10) unsigned NOT NULL auto_increment,

`name` varchar(45) NOT NULL,

`description` text NOT NULL,

`table_name` varchar(45) NOT NULL,

PRIMARY KEY (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=latin1;



CREATE TABLE `db_name`.`roomX` (

`id` int(10) unsigned NOT NULL auto_increment,

`date` datetime NOT NULL,

`message` text NOT NULL,

`user` varchar(45) NOT NULL,

PRIMARY KEY (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=latin1;

The first table, chat_rooms, contains a list of all available chat rooms, used to know wich table name will be used for each room. The second one, roomX is a template for a "chat room-like" table: it contains the date (date+time) of each message, the message itself and the user that inputed it (actually it should be an integer, that refers to an appropriate users table, but this is simple version of the script without logging features).

The first thing we're gonna do is execute those SQL scripts (we will be using MySQL and PHP native methods) replacing "roomX" with i.e. "friends_table", and after that we're going to populate the first table, to add an available chat room:



INSERT INTO chat_rooms(name,description,table_name)

VALUES("Friends chat","Comment...","friends_table");

The next step is to compose the "web application". Let's see this picture:

We will use a main page, chat.php, a dinamically reloaded page, room.php and a simple iframe with inside the page sender.php with some controls to post a message.

Let's see chat.php, removing all HTML stuff (like header and formatting, that's up to you):



<?php

session_start();

/* probabily login stuff */

$_SESSION['chat_time'] = $date;

?>

<script type="text/javascript" src="timer.js"></script>

<script type="text/javascript" src="httpRequest.js"></script>

<script language="javascript">

var chatRoomId=<?=$charRoomChoosen?>;

</script>

<body onload="InitializeTimer(); StartTheTimer();">

<div id="chatText" style="overflow:auto;"></div>

<iframe src="sender.php" name="msgFrame"></iframe>

</body>

We'll talk further about the session variable chat_time; I've added 2 javascript scripts: the first one is a simple timer, the second one contains some methods to make HTTP requests.
This is httpRequest.js:



var xmlHttp;



function loadURL()

{

xmlHttp=GetXmlHttpObject()

if (xmlHttp==null)

{

alert ("Browser does not support HTTP Request")

return

}

var url="room.php?chatRoomId="+charRoomId;

xmlHttp.onreadystatechange=stateChanged;

xmlHttp.open("GET",url,true);

xmlHttp.send(null)

}



function stateChanged()

{

if (xmlHttp.readyState==4 xmlHttp.readyState=="complete")

{

/* trim message */

var newlines = xmlHttp.responseText.replace(/^\s+\s+$/g,"");

if(newlines!='')

{

var html = document.getElementById("chatText").innerHTML;

document.getElementById("chatText").innerHTML = html + newlines;

document.getElementById("chatText").scrollTop=20000000;

}



}

}



function GetXmlHttpObject()

{

var xmlHttp=null;

try

{

// Firefox, Opera 8.0+, Safari

xmlHttp=new XMLHttpRequest();

}

catch (e)

{

//Internet Explorer

try

{xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");}

catch (e){xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");}

}

return xmlHttp;

}

This class does an HTTP request (using Firefox, Explorer and other browser Request objects), as I explained in the [Javascript]XML Loading post, and writes the result inside the DIV with id chatText, calling the room.php script (that actually outputs last message sent to the room). The charRoomId used as a parameter of the calling method, is a global variable defined in the chat.php header using a PHP variabile (it should be a $_REQUEST variable).

As we are using asyncronous calls, we need a component that recalls this request periodically. This is the code below (timer.js):



var secs;

var timerID = null;

var timerRunning = false;

var delay = 500;



function InitializeTimer()

{

// Set the length of the timer, in seconds

secs = 1;

StopTheClock();

StartTheTimer();

}



function StopTheClock()

{

if(timerRunning)

clearTimeout(timerID);

timerRunning = false;

}



function StartTheTimer()

{

if (secs==0)

{

StopTheClock();

// Here's where you put something useful that's

// supposed to happen after the allotted time.

// For example, you could display a message:

loadURL();

secs = 1;

timerRunning = true;

timerID = self.setTimeout("StartTheTimer()", delay);

}

else

{

self.status = secs;

secs = secs - 1;

timerRunning = true;

timerID = self.setTimeout("StartTheTimer()", delay);

}

}

This is a timer, called from the chat.php page with onLoad method, that recalls each delay milliseconds the function loadURL() function, defined inside the previous js file.

Now let's see what is inside the chat.php file:



<?php



/* **************** SESSION VARIABLES **************************** */

session_start();



if(!isset($_SESSION['chat_time']))

{

$_SESSION['chat_time'] = date("Y-m-d H:i:s");

$_SESSION['chat_time_delete'] = time();

}





/************** DB connection ********************+*/

$db_user = "root";

$db_password = "root1";

$db_host ="localhost";

$connection = mysql_connect($db_host,$db_user,$db_password);

mysql_select_db("test",$connection);



/********** RETRIEVES THE NAME OF THE CHAT ROOM TABLE NAME **********/

function getChatTableName($connection,$chatRoomId)

{

/* recupera il nome della tabella della chat room */

$query = "SELECT table_name FROM chat_rooms WHERE id = '".$chatRoomId."'";

$result = mysql_query($query, $connection);

$tableName = NULL;

while($row=mysql_fetch_array($result))

{

$tableName = $row['table_name'];

}



if($tableName==NULL)

{

return NULL;

}



return $tableName;

}



/******************* MESSAGE VISUALIZATION ********************************/





$tableName = getChatTableName($connection,$_REQUEST['chatRoomId']);



if($tableName==NULL)

{

echo "Error selection char room.";

exit();

}

$login_date = $_SESSION['chat_time'];



/* load messages */

$query = "SELECT c.message, c.date, c.user FROM ".$tableName." c WHERE c.date > '".$login_date

."' ORDER BY c.date ASC ";

$result = mysql_query($query,$connection);



$last = "";

while($row=mysql_fetch_array($result))

{

$message = html_entity_decode($row['message']);

echo "[".$row['user']."][".$row['date']."] ".$message." <br/>";

$_SESSION['chat_time'] = $row['date'];

}



/* delete messages older that 60 seconds*/

if((time()-$_SESSION['chat_time_delete'])>60 )

{

$query = "DELETE FROM ".$tableName." WHERE (NOW()-date)>60";

mysql_query($query,$connection);

$_SESSION['chat_time_delete']=time();

}



mysql_close($connection);

?>

We can see session variables initialization: chat_time is the time in which you entered the chat room or of the last message received, while chat_time_delete is the time in which you last deleted a message.
The scripts work this way:

  • connect to the database
  • retrieve the chat room table name using the chatRoomId request variable and the getChatTableName() function
  • query the DB searching for messages not yet received (basing unpon the time of last message received, and at the end of the loop we have a new value for chat_time, that is the last received message time
  • (because) once received messages are useless (a user after connection never received messages of the past), the script delete messages older than 60 seconds

Of course you can format as you like the message board.

At the end we find the sender.php page, that is wrapped in an HTML iframe (because every submission must not cause the entire page reload):



<?php



/***************+ DB variables *****************+*/

$db_user = "root";

$db_password = "root1";

$db_host ="localhost";

$connection = mysql_connect($db_host,$db_user,$db_password);

mysql_select_db("test",$connection);



/********************* NOME TABDELLA CHAT ROOM **************************+*/

function getChatTableName($connection,$chatRoomId)

{

$query = "SELECT table_name FROM chat_rooms WHERE id = '".$chatRoomId."'";

$result = mysql_query($query, $connection);

$tableName = NULL;

while($row=mysql_fetch_array($result))

{

$tableName = $row['table_name'];

}



if($tableName==NULL)

{

return NULL;

}



return $tableName;

}





if($_POST['action']=="send")

if($_SESSION['userid']!="")

{

$tableName = getChatTableName($connection,$_REQUEST['chatRoomId']);



if($tableName==NULL)

{

echo "Error selecting chat room.";

exit();

}



$query = "INSERT INTO ".$tableName."(user,message,date) VALUES(\""

.$_POST['userid']."\",\""

.htmlentities(htmlspecialchars($_POST['message']))."\",NOW())";



mysql_query($query,$connection);



}

?>



<body onload="document.msgForm.message.focus();">



<form name="msgForm" action="sender.php" method="post">

<input type="hidden" value="send" name="action"/>

<input type="hidden" value="1" name="chatRoomId"/>

<input type="text" name="userid" value="<?=($_POST['userid']=="")?"guest":$_POST['userid']?>" size="10" />

<input type="text" name="message" style="width:400px" maxlength="1500"/>

<input type="submit" value="invia"/>

</form>

</body>



<?php

mysql_close($connection);

?>

This page simply prints out a web form (in which users insert their nick name -in this version without a check- and the message) and -consequently to the submission- insert the message in the DB, that will be outputted by the timer.js routine.

This will be your final result:

You can read the full tutorial here.

Hopefully this tutorial will be useful to you.

Syndicate content