We have completed a working and functional beta version of Ngashint with basic core features. Now uploading screenshot of deployment process in Ngashint. Enjoy!
From the day one I conceived the idea of creating release management system, I have been thinking about how to make our life easier, especially we developers and QA or people in general of software industry. This very fact of making things easier and manageable is the reason why I started this project; when I was looking for an easy way to deploy the code changes I want from SVN repository to our production server FloFeed.com, while also being able to rollback to any point in release history with a single click.
Therefore, now throughout the design and implementation phase, I pay a very close attention what user expects for a particular page or functionality and how user will or can interact easily with the prior knowledge they have before. It is the belief that I strongly hold that we should work our ass off for a great product without requiring the customers to change very much to use our solutions.
Yes, with these beliefs and convictions, I have been building up a great and easy to use release management tool. I believe at the end of the development, Ngashint will turn your boring release management into a fun process to enjoy. Well, let’s see how it comes out. I can’t wait to share it when it is ready. Stay tuned!
One of the main tasks Ngashint as a release management application is to have a build automation system for code deployment from SVN repository tags to production/test/dev servers. I used Phing for building software release/deployment like people use Ant for Java projects.
Phing is XML based build tool that allows you to easily write build recipe. While using Phing, at one point I needed to dynamically build “build” XML file for automation.That means having to edit or create XML file on the fly. One way to do is to use native XML library or functions supported by PHP traverse through DOM tree and modify or creating nodes and attributes. I find that path boring or tedious. I wonder what if we can update data like an array. So I decided to write code to convert from XML to associative array (yeah …one nice thing about PHP) and then being able to convert generated array into same XML file, back and forth maintaining symmetric relationship.
Here is how an associative array is used to represent XML nodes and attributes conceptually.
Here is now to use:
$obj = new XmlArray();
$xmlString = '<root id="test">Hello World</root>';
$array = $obj->getArray($xmlString);
var_dump($array);
$xml = $obj->getXML($array);
echo $xml;
Output will be like
array(1) {
["root"]=>
array(2) {
["id"]=>
string(4) "test"
[0]=>
string(11) "Hello World"
}
}
<root id="test">Hello World</root>
Following is the complete class code you can use.
class XmlArray {
/**
* @desc : "key" => "text value" is for attribute
* [0-9] => "text value" is for text node
* "key" => array() for child node
* [0-9] => array() for child node to have same name of child node at the same tree depth level
* @param array $A
* @return unknown_type
*/
public function getXML(array $A) {
if (count($A) != 1)
throw new Exception('There can be only one root for XML document');
$dom = new DOMDocument('1.0', 'UTF-8');
if ($this->is_assoc($A)) {
foreach ($A as $key => $value) {
$rootNode = $dom->createElement($key);
if (is_array($value) && !empty($value)) {
$this->processNode($value, $rootNode, $dom);
} else if (is_array($value) && empty($value)) {
$text = $dom->createTextNode($key);
$rootNode->appendChild($text);
} else {
throw new Exception('Malformed array for XML representation!');
}
}
} else {
$rootNode = $dom->createElement($A[0]);
}
return $dom->saveXML($rootNode);
}
public function getArray($xmlString) {
if (empty($xmlString))
throw new Exception('Empty XML string');
$doc = new DOMDocument();
$doc->loadXML($xmlString);
$A = array($doc->documentElement->nodeName => array());
$this->processArray($A[$doc->documentElement->nodeName], $doc->documentElement);
return $A;
}
private function processNode(array $A, &$parent, $dom) {
if ($this->is_assoc($A)) {
foreach ($A as $key => $value) {
if (is_numeric($key) && is_array($value)) {
if ($this->is_assoc($value)) {
$this->processNode($value, $parent, $dom);
} else {
foreach ($value as $each)
$this->processNode($each, $parent, $dom);
}
} else if (is_numeric($key) && !is_array($value)) {
$text = $dom->createTextNode($value);
$parent->appendChild($text);
} else if (is_array($value) && !empty($value)) {
$node = $dom->createElement($key);
$parent->appendChild($node);
$this->processNode($value, $node, $dom);
} else {
$parent->setAttribute($key, $value);
}
}
} else {
foreach ($A as $a) {
if (is_array($a)) {
$this->processNode($a, $parent, $dom);
}
else
$parent->appendChild($dom->createTextNode($a));
}
}
}
private function processArray(&$currentA, $currentNode) {
$numericKey = 0;
if ($currentNode->hasAttributes()) {
foreach ($currentNode->attributes as $attr) {
$currentA[$attr->nodeName] = $attr->nodeValue;
}
}
if ($currentNode->hasChildNodes()) {
foreach ($currentNode->childNodes as $child) {
if ($child->nodeType === XML_TEXT_NODE) {
//Text Node
if (!empty($child->wholeText)) {
$currentA[$numericKey] = $child->wholeText;
$numericKey++;
}
} else {
if (isset($currentA[$child->nodeName])) {
$currentA[$numericKey] = array($child->nodeName => array());
$this->processArray($currentA[$numericKey][$child->nodeName], $child);
$numericKey++;
} else {
$currentA[$child->nodeName] = array();
$this->processArray($currentA[$child->nodeName], $child);
}
}
}
}
}
protected function is_assoc($array) {
return (is_array($array) && 0 !== count(array_diff_key($array, array_keys(array_keys($array)))));
}
}
Download link for the class : http://www.megaupload.com/?d=EIBGVAIO
Your browser does not support iframes.
Hello everyone!
This is the first post after setting up a website for Ngashint project. The project is about creating a release management system written in PHP to easily create releases from code repository such as SVN and roll out or roll back releases to staging and production environments with no hassle.
I will post updates about the project here on this site. Stay tuned!
Thanks,
Kevin Thant