summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEudyptula <eitan@mosenkis.net>2009-07-07 17:19:21 -0400
committerEudyptula <eitan@mosenkis.net>2009-07-07 17:19:21 -0400
commit2b92850a6aaa28074cddba730b11ab606a3adcd9 (patch)
tree43c29ba3cf393cc7d541af1cb824388cea6def00
parentFix blip with favicon.ico (diff)
downloadingenue-2b92850a6aaa28074cddba730b11ab606a3adcd9.tar.gz
ingenue-2b92850a6aaa28074cddba730b11ab606a3adcd9.tar.bz2
ingenue-2b92850a6aaa28074cddba730b11ab606a3adcd9.zip
Major restructuring of frontend modules (package selection not done yet); created conf_build_common class for shared code among configurations and builds
-rwxr-xr-xbackend/backend.php2
-rw-r--r--depend2
-rw-r--r--frontend/classes/wizard_api.php171
-rw-r--r--frontend/css/pkgs.css22
-rw-r--r--frontend/js/debug.js.php3
-rw-r--r--frontend/js/pkgsearch.js75
-rw-r--r--frontend/modules/gentoo/step1.php30
-rw-r--r--frontend/modules/gentoo/step2.php110
-rw-r--r--frontend/modules/gentoo/step3.php29
l---------frontend/modules/gentoo_catalyst1
l---------frontend/modules/gentoo_portage1
-rw-r--r--frontend/pages/configurations/wizard.php160
-rw-r--r--frontend/pages/upload.php2
-rw-r--r--shared/classes/1conf_build_common.php92
-rw-r--r--shared/classes/build.php34
-rw-r--r--shared/classes/configuration.php62
-rw-r--r--shared/config.php3
17 files changed, 461 insertions, 338 deletions
diff --git a/backend/backend.php b/backend/backend.php
index 78852e4..d078191 100755
--- a/backend/backend.php
+++ b/backend/backend.php
@@ -65,7 +65,7 @@ while (true) {
$opt->write();
unset($opt);
}
- $opts=$build->get_buildopts();
+ $opts=$build->get_opts();
$module=$opts['backend_module'];
$build_proc=$module.'_build';
foreach (glob(BACKEND."/modules/$module/*.php") as $inc) {
diff --git a/depend b/depend
index 9a48688..00ef6d6 100644
--- a/depend
+++ b/depend
@@ -1,4 +1,4 @@
->=dev-lang/php-5.2.2 USE=pdo hash pcntl pcre cli pdo mysqli apache2 curl
+>=dev-lang/php-5.2.2 USE=pdo hash pcntl pcre cli pdo mysqli apache2 curl ctype
sys-apps/fakeroot ?
sys-apps/portage # In case you use paludis
www-servers/apache APACHE2_MODULES=rewrite?
diff --git a/frontend/classes/wizard_api.php b/frontend/classes/wizard_api.php
new file mode 100644
index 0000000..95ed57a
--- /dev/null
+++ b/frontend/classes/wizard_api.php
@@ -0,0 +1,171 @@
+<?php
+class wizard_step {
+ var $module, $step, $title, $next, $data=array();
+ function __construct($mod, $step) {
+ $this->module=$mod;
+ $this->step=$step;
+ $file=FRONTEND."/modules/$mod/step$step.php";
+ if (!is_readable($file)) {
+ throw_exception("$mod step $step doesn't exist!");
+ }
+ require($file);
+ $this->title="Step $step".($title?" - $title":'');
+ $this->next=$next;
+ }
+ public function output() {
+ echo "<h3>$this->title</h3>\n";
+ echo '<form action="'.url('config/'.wizard::$configuration->id).'" method="post">';
+ foreach ($this->data as $obj) {
+ if (!$obj->status) {
+ echo print_warning('Please complete this field.');
+ }
+ $obj->output();
+ }
+ echo '<br/><input type="submit" name="wizard_submit['.$this->step.']" value="Continue" />'."\n";
+ }
+ public function process() {
+ global $request;
+ if (isset($request['wizard_submit_'.$this->step])) {
+ return $this->step;
+ }
+ $result=$this->next;
+ foreach ($this->data as $obj) {
+ if (!$obj->status=$obj->process()) {
+ $result=$this->step;
+ }
+ }
+ return $result;
+ }
+ private function text($text) {
+ $this->data[]=new wizard_text($text);
+ }
+ private function text_input($optname, $htmlname, $label) {
+ $this->data[]=new wizard_text_input($optname, $htmlname, $label);
+ }
+ private function select($optname, $htmlname, $label, $options) {
+ $this->data[]=new wizard_select($optname, $htmlname, $label, $options);
+ }
+ private function query($q) {
+ return $GLOBALS['S']['pdo']->query($q);
+ }
+}
+abstract class wizard {
+ public $status=true;
+ public static $configuration;
+ public static function set_configuration(&$c) {
+ self::$configuration=&$c;
+ }
+ abstract public function output();
+ abstract public function process();
+ protected static function get_opt($name) {
+ $opts=self::$configuration->get_opts();
+ return isset($opts[$name])?$opts[$name]:null;
+ }
+ protected static function set_opt($name, $val) {
+ if (substr($name, 0, 1) == ':') {
+ self::$configuration->$name=$val;
+ self::$configuration->write();
+ } else {
+ self::$configuration->set_opt($name, $val);
+ }
+ }
+ protected static function opt_is($name, $val) {
+ $opts=self::$configuration->get_opts();
+ if (isset($opts[$name]) && $opts[$name] === $val) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+}
+class wizard_text extends wizard {
+ protected $text;
+ function __construct($text) {
+ $this->text=$text;
+ }
+ public function output() {
+ echo $this->text;
+ }
+ public function process() {
+ return true;
+ }
+}
+abstract class wizard_input extends wizard {
+ protected $optname, $htmlname, $label;
+ function __construct($optname, $htmlname, $label) {
+ $this->optname=$optname;
+ $this->htmlname=htmlentities($htmlname);
+ $this->label=htmlentities($label);
+ }
+ public function output() {
+ echo "$this->label ";
+ }
+ public function process() {
+ global $request;
+ if (isset($request[$this->optname])) {
+ self::set_opt($this->optname, $request[$this->optname]);
+ return true;
+ } else {
+ return false;
+ }
+ }
+}
+class wizard_text_input extends wizard_input {
+ public function output() {
+ parent::output();
+ }
+}
+class wizard_select extends wizard_input {
+ private $options;
+ function __construct($optname, $htmlname, $label, $options) {
+ parent::__construct($optname, $htmlname, $label);
+ $this->options=$options;
+ }
+ public function output() {
+ parent::output();
+ echo '<select name="'.$this->htmlname.'">'."\n";
+ foreach ($this->options as $val => $label) {
+ echo "\t".'<option value="'.htmlentities($val).'"'.(self::opt_is($this->optname, $val)?' selected="selected"':'').'>'.htmlentities($label).'</option>'."\n";
+ }
+ echo '</select>'."\n";
+ }
+}
+class wizard_radio extends wizard_select {
+ public function output() {
+ echo "$this->label:<br/>\n";
+ $i=0;
+ foreach ($this->options as $val => $label) {
+ echo "\t<input type=\"radio\" id=\"$this->htmlname-$i\" name=\"$this->htmlname\" value=\"".htmlentities($val)."\"".(self::opt_is($this->optname, $val)?' checked="checked"':'')."\" /><label for=\"$this->htmlname-$i\">".htmlentities($label)."</label>\n";
+ }
+ }
+}
+class wizard_checkbox_array extends wizard_input {
+ private $boxes;
+ function __construct($optname, $htmlname, $label, $boxes, $delim=' ') {
+ parent::__construct($optname, $htmlname, $label);
+ $this->boxes=$boxes;
+ $this->delim=$delim;
+ }
+ public function output() {
+ echo "$this->label:<br/>\n";
+ $i=0;
+ foreach ($this->boxes as $val => $label) {
+ echo "\t<input type=\"checkbox\" id=\"$this->htmlname-$i\" name=\"$this->htmlname[$i]\"".(self::opt_has($this->optname, $val, $this->delim)?' checked="checked"':'')." /><label for=\"$this->htmlname-$i\">$label</label><br/>\n";
+ $i++;
+ }
+ }
+ public function process() {
+ global $request;
+ $val=array();
+ // FIXME we're assuming that array_keys order is determinate and the same as the foreach in output()
+ $vals=array_keys($this->boxes);
+ foreach ($request[$this->htmlname] as $i) {
+ $val[]=$vals[$i];
+ }
+ self::set_opt($this->optname, implode($this->delim, $vals));
+ }
+ protected static function opt_has($name, $val, $delim=' ') {
+ return (array_search($val, explode($delim, self::get_opt($name))) !== false);
+ }
+}
+?>
diff --git a/frontend/css/pkgs.css b/frontend/css/pkgs.css
new file mode 100644
index 0000000..f9251da
--- /dev/null
+++ b/frontend/css/pkgs.css
@@ -0,0 +1,22 @@
+#plist {
+ height: 25em;
+ overflow: auto;
+}
+#plist a {
+ text-decoration: none;
+}
+#plist div.masked {
+ color: red;
+}
+#plist div.bct {
+ font-size: 125%;
+}
+#plist div.lct {
+ font-size: 110%;
+}
+#plist div.bc, div.lc {
+ padding-left: 2em;
+}
+#plist .pd {
+ cursor: pointer;
+}
diff --git a/frontend/js/debug.js.php b/frontend/js/debug.js.php
index 5e33ce8..cc28959 100644
--- a/frontend/js/debug.js.php
+++ b/frontend/js/debug.js.php
@@ -14,13 +14,14 @@ function debug (subtype, text) {
}
text+="";
text=text.replace(/(\r\n|\r|\n)/g,'<br/>');
+ text=text.replace(/ /g, '&nbsp;');
if (debugrow > 0) {
hidedebug(debugrow);
}
div=document.createElement('div');
div.className='debug '+(++debugrow%2?'odd':'even');
div.id='debug'+debugrow;
- big=text.match('<br') || text.length > 100;
+ big=text.match('<br') || text.length > 150;
div.innerHTML='<span class="type'+(big?' pointer" onclick="toggledebug('+debugrow+')':'')+'">'+(big?'<img id="debugmanager'+debugrow+'" src="'+url('images/minusbox.gif')+'" alt="[Hide]" /> ':'')+(subtype!=null?subtype+':':'')+'</span><span> '+text+'</span>';
document.getElementById("debugbox").appendChild(div);
document.getElementById("debugcount").childNodes[0].nodeValue=debugrow;
diff --git a/frontend/js/pkgsearch.js b/frontend/js/pkgsearch.js
new file mode 100644
index 0000000..86dc1c3
--- /dev/null
+++ b/frontend/js/pkgsearch.js
@@ -0,0 +1,75 @@
+function tog_show_pkgs(lc) {
+ var div=document.getElementById('lc-'+lc);
+ if (div.style.display == "none") {
+ div.style.display="";
+ } else {
+ div.style.display="none";
+ }
+}
+var oldq=null;
+function packagesearch(entry) {
+ var q=entry.value;
+ if (q !== oldq) {
+ filter_packages_by(q);
+ }
+ oldq=q;
+}
+function filter_packages_by(q) {
+ var plist=document.getElementById('plist');
+ var tfound=0;
+ for (i=0; i<plist.childNodes.length; i++) {
+ var bc=plist.childNodes[i];
+ if (bc.className !== 'bc') {
+ continue;
+ }
+ var bcid=bc.id.substr(3);
+ var bfound=0;
+ for (j=0; j<bc.childNodes.length; j++) {
+ var lc=bc.childNodes[j];
+ if (lc.className !== 'lc') {
+ continue;
+ }
+ var lcid=lc.id.substr(3, lc.id.length-3);
+ var found=0;
+ for (k=0; k<lc.childNodes.length; k++) {
+ var p=lc.childNodes[k];
+ if (!p.className || p.className.substr(0,3) !== 'pkg') {
+ continue;
+ }
+ if (q == '') {
+ p.style.display="";
+ } else {
+ var name='';
+ for (l=0; l<p.childNodes.length; l++) {
+ var d=p.childNodes[l];
+ if (d.className == 'pd') {
+ name=d.innerHTML;
+ break;
+ }
+ }
+ if (name && name.toLowerCase().indexOf(q.toLowerCase()) != -1) {
+ p.style.display="";
+ found++;
+ } else {
+ p.style.display="none";
+ }
+ }
+ }
+ if (q == "" || found == 0) {
+ lc.style.display="none";
+ document.getElementById('lct-'+lcid).style.display=(q == ''?"":"none");
+ } else {
+ bfound+=found;
+ lc.style.display="";
+ document.getElementById('lct-'+lcid).style.display="";
+ }
+ }
+ if (q=="" || bfound > 0) {
+ document.getElementById('bct-'+bcid).style.display="";
+ } else {
+ document.getElementById('bct-'+bcid).style.display="none";
+ }
+ tfound+=bfound;
+ }
+ document.getElementById('zero').style.display=(tfound || !q.length?'none':'');
+}
diff --git a/frontend/modules/gentoo/step1.php b/frontend/modules/gentoo/step1.php
index 20899bb..d3ee3b9 100644
--- a/frontend/modules/gentoo/step1.php
+++ b/frontend/modules/gentoo/step1.php
@@ -1,24 +1,12 @@
<?php
-function gentoo_init_step1() {
- return array('title' => 'Step 1 - Choose Profile');
-}
-function gentoo_body_step1() {
- global $S;
- $configuration=&$S['wizard.configuration'];
- //$opts=$configuration->get_configopts(); // TODO use this to set selected="selected" on the current profile
- echo 'Profile: <select name="profileid">';
- $r=$S['pdo']->query('SELECT * FROM `gentoo_profiles` WHERE `flags` NOT LIKE "%d%"'); // d for disabled
- while ($profile=$r->fetch(PDO::FETCH_ASSOC)) {
- $profile=new sql_gentoo_profile($profile);
- $display=$profile->name?$profile->name:($profile->pkgdir?$profile->pkgdir:'/');
- echo '<option value="'.$profile->id.'">'.htmlentities($display).'</option>';
- }
- echo '</select><br/>';
-}
-function gentoo_process_step1() {
- global $S, $request;
- $profile=new sql_gentoo_profile($request['profileid']);
- $profileopt=new sql_configopt($S['wizard.configuration']->id, 'profile', $profile->id);
- $profileopt->write();
+$title='Choose Profile';
+$opts=array();
+$r=$this->query('SELECT * FROM `gentoo_profiles` WHERE `flags` NOT LIKE "%d%"');
+while ($profile=$r->fetch(PDO::FETCH_ASSOC)) {
+ $profile=new sql_gentoo_profile($profile);
+ $display=$profile->name?$profile->name:($profile->pkgdir?$profile->pkgdir:'/');
+ $opts[$profile->id]=$display;
}
+$this->select('profile', 'profile', 'Profile', $opts);
+$next=2;
?>
diff --git a/frontend/modules/gentoo/step2.php b/frontend/modules/gentoo/step2.php
index c800a5d..9ca5ee7 100644
--- a/frontend/modules/gentoo/step2.php
+++ b/frontend/modules/gentoo/step2.php
@@ -1,111 +1,9 @@
<?php
-function gentoo_init_step2() {
- $js=<<<JS
-function tog_show_pkgs(lc) {
- var div=document.getElementById('lc-'+lc);
- if (div.style.display == "none") {
- div.style.display="";
- } else {
- div.style.display="none";
- }
-}
-var oldq=null;
-function packagesearch(entry) {
- var q=entry.value;
- if (q !== oldq) {
- filter_packages_by(q);
- }
- oldq=q;
-}
-function filter_packages_by(q) {
- var plist=document.getElementById('plist');
- var tfound=0;
- for (i=0; i<plist.childNodes.length; i++) {
- var bc=plist.childNodes[i];
- if (bc.className !== 'bc') {
- continue;
- }
- var bcid=bc.id.substr(3);
- var bfound=0;
- for (j=0; j<bc.childNodes.length; j++) {
- var lc=bc.childNodes[j];
- if (lc.className !== 'lc') {
- continue;
- }
- var lcid=lc.id.substr(3, lc.id.length-3);
- var found=0;
- for (k=0; k<lc.childNodes.length; k++) {
- var p=lc.childNodes[k];
- if (!p.className || p.className.substr(0,3) !== 'pkg') {
- continue;
- }
- if (q == '') {
- p.style.display="";
- } else {
- var name='';
- for (l=0; l<p.childNodes.length; l++) {
- var d=p.childNodes[l];
- if (d.className == 'pd') {
- name=d.innerHTML;
- break;
- }
- }
- if (name && name.toLowerCase().indexOf(q.toLowerCase()) != -1) {
- p.style.display="";
- found++;
- } else {
- p.style.display="none";
- }
- }
- }
- if (q == "" || found == 0) {
- lc.style.display="none";
- document.getElementById('lct-'+lcid).style.display=(q == ''?"":"none");
- } else {
- bfound+=found;
- lc.style.display="";
- document.getElementById('lct-'+lcid).style.display="";
- }
- }
- if (q=="" || bfound > 0) {
- document.getElementById('bct-'+bcid).style.display="";
- } else {
- document.getElementById('bct-'+bcid).style.display="none";
- }
- tfound+=bfound;
- }
- document.getElementById('zero').style.display=(tfound || !q.length?'none':'');
-}
-JS;
- $css=<<<CSS
-#plist {
- height: 25em;
- overflow: auto;
-}
-#plist a {
- text-decoration: none;
-}
-div.masked {
- color: red;
-}
-div.bct {
- font-size: 125%;
-}
-div.lct {
- font-size: 110%;
-}
-div.bc, div.lc {
- padding-left: 2em;
-}
-.pd {
- cursor: pointer;
-}
-CSS;
- return array('title' => 'Step 2 - Choose Extra Packages', 'head_scripts' => array($js), 'head_css' => array($css));
-}
+$title='Choose Extra Packages';
+$scripts='pkgsearch';
function gentoo_body_step2() {
global $S;
- $configuration=&$S['wizard.configuration'];
+ $configuration=&$S['wizard']['configuration'];
$opts=$configuration->get_configopts();
$profile=new sql_gentoo_profile($opts['profile']);
$bcs=$profile->get_packages();
@@ -136,7 +34,7 @@ function gentoo_process_step2() {
$packages[]='='.$name;
}
$packages=implode(' ', $packages);
- $opt=new sql_configopt($S['wizard.configuration']->id, 'install_packages', $packages);
+ $opt=new sql_configopt($S['wizard']['configuration']->id, 'install_packages', $packages);
$opt->write();
}
}
diff --git a/frontend/modules/gentoo/step3.php b/frontend/modules/gentoo/step3.php
index 2f66325..9dd523a 100644
--- a/frontend/modules/gentoo/step3.php
+++ b/frontend/modules/gentoo/step3.php
@@ -1,18 +1,13 @@
<?php
-function gentoo_init_step3() {
- return array('title' => 'Step 3 - Image Format');
-}
-function gentoo_body_step3() {
- echo 'Image type: <select name="image_type"><option value="tgz">Tar/Gzip</option><option value="tbz2">Tar/Bzip2</option><option value="installcd">Installer CD with Tar/Bzip2 image</option><option value="livecd">LiveCD</option><option value="ext2">ext2</option><option value="jffs2">jffs2</option></select><br/>';
-}
-function gentoo_process_step3() {
- global $S, $request;
- if (isset($request['image_type'])) {
- debug('wizard', 'step3: image type='.$request['image_type']);
- $opt=new sql_configopt($S['wizard.configuration']->id, 'image_type', $request['image_type']);
- $opt->write();
- } else {
- debug('wizard', 'step3: no image_type variable');
- }
- return true;
-}
+// TODO This shouldn't be a step at all, it should be in wizard.php to choose between output modules
+$title='Image Format';
+$this->select('image_type', 'image_type', 'Image type', array(
+ 'tgz' => 'Tar/Gzip',
+ 'tbz2' => 'Tar/Bzip2',
+ 'installcd' => 'Installer CD with Tar/Bzip2',
+ 'livecd' => 'LiveCD',
+ 'ext2' => 'ext2',
+ 'jffs2' => 'jffs2'
+));
+$next=null;
+?>
diff --git a/frontend/modules/gentoo_catalyst b/frontend/modules/gentoo_catalyst
new file mode 120000
index 0000000..0c0273e
--- /dev/null
+++ b/frontend/modules/gentoo_catalyst
@@ -0,0 +1 @@
+gentoo \ No newline at end of file
diff --git a/frontend/modules/gentoo_portage b/frontend/modules/gentoo_portage
new file mode 120000
index 0000000..0c0273e
--- /dev/null
+++ b/frontend/modules/gentoo_portage
@@ -0,0 +1 @@
+gentoo \ No newline at end of file
diff --git a/frontend/pages/configurations/wizard.php b/frontend/pages/configurations/wizard.php
index 3931363..de35c65 100644
--- a/frontend/pages/configurations/wizard.php
+++ b/frontend/pages/configurations/wizard.php
@@ -4,129 +4,81 @@ function init_configurations_wizard() {
if (!isset($S['user'])) {
return 'login';
}
- // Make it so you can just pop over to config configuration=x and it will go to the right step
- if (isset($request['configuration']) && preg_match('/^[a-zA-Z0-9]{6}$/', $request['configuration'])) {
- $r=$S['pdo']->query('SELECT * FROM `configurations` WHERE `owner`='.$S['user']->id.' AND `id`="'.$request['configuration'].'"');
- if ($r->rowCount()) {
- $S['wizard.configuration']=new sql_configuration($r->fetch(PDO::FETCH_ASSOC));
- $configuration=&$S['wizard.configuration'];
- $opts=$configuration->get_configopts();
- $S['wizard.module']=$opts['frontend_module'];
- $module=&$S['wizard.module'];
- if (!preg_match('#^config/step([0-9]+)$#', $configuration->status, $match)) {
- debug('wizard', 'configuration not in config stage (status '.$configuration->status.') - PANIC!');
- throw_exception('We haven\'t implemented this yet.');
- }
- $S['wizard.step']=$match[1];
- $step=&$S['wizard.step'];
- debug('wizard', 'Build '.$configuration->id." is at step $step");
- if (isset($request['wizard_submit'])) {
- debug('wizard', "Processing step $step");
- if (!is_file(FRONTEND."/modules/$module/step$step.php")) {
- throw_exception("$modules step $step doesn't exist!");
- }
- require_once(FRONTEND."/modules/$module/step$step.php");
- $proc=$module.'_process_step'.$step;
- if (function_exists($proc)) {
- if ($proc() === true) {
- debug('wizard', "Step $step returned <i>true</i> - config finished!");
- $configuration->status='config/done';
- $configuration->write();
- $S['wizard.done']=true;
- return array('title' => 'Config Finished');
- }
- } else {
- debug('wizard', "No processing function for $wizard step $step");
- }
- $configuration->status='config/step'.++$step;
+ if (isset($request['configuration']) && strlen($request['configuration']) == 6 && ctype_alnum($request['configuration'])) {
+ $S['wizard']['configuration']=new sql_configuration($request['configuration']);
+ wizard::set_configuration($S['wizard']['configuration']);
+ $configuration=&$S['wizard']['configuration'];
+ if ($configuration->owner != $S['user']->id) {
+ return '404';
+ }
+ if (isset($request['wizard_submit'])) {
+ $steps=array_keys($request['wizard_submit']);
+ $step=$steps[0];
+ wizard_load_step($step);
+ debug('wizard', "processing $configuration->module step $step");
+ $result=$S['wizard']['step']->process();
+ if ($result === $step) {
+ debug('wizard', "$configuration->module step $step not finished - staying put");
+ } elseif ($result === null) {
+ debug('wizard', "$configuration->module step $step returned <i>null</i> - config finished");
+ $configuration->status=0;
$configuration->write();
- debug('wizard', "Continuing to step $step");
} else {
- debug('wizard', "Not ready for processing... staying at step $step");
+ $configuration->status=$result;
+ $configuration->write();
+ wizard_load_step($result);
}
- } else {
- throw_exception('Build not found');
+ } elseif (isset($request['step']) && ctype_alnum($request['step'])) {
+ wizard_load_step($request['step']);
+ } elseif ($configuration->status > 0) {
+ wizard_load_step($configuration->status);
}
} elseif (isset($request['init'])) {
- $r=$S['pdo']->query('SELECT * FROM `configurations` WHERE `owner`='.$S['user']->id.' AND `status`="config/step1"');
- if ($r->rowCount()) {
- $S['wizard.configuration']=new sql_configuration($r->fetch(PDO::FETCH_ASSOC));
- } else {
- $S['wizard.configuration']=new sql_configuration();
- $S['wizard.configuration']->init();
- }
- $configuration=&$S['wizard.configuration'];
- $S['wizard.configuration']->name=$request['name'];
- $S['wizard.configuration']->write();
- $femods=explode(' ', $conf['frontend_modules']);
- $bemods=explode(' ', $conf['backend_modules']);
- $femod=isset($request['femod']) && isset($femods[$request['femod']])?$femods[$request['femod']]:$femods[0];
- $bemod=isset($request['bemod']) && isset($bemods[$request['bemod']])?$bemods[$request['bemod']]:$bemods[0];
- $beopt=new sql_configopt($configuration->id, 'backend_module', $bemod);
- $feopt=new sql_configopt($configuration->id, 'frontend_module', $femod);
- debug('wizard', "Backend: $bemod; Frontend: $femod");
- $beopt->write();
- $feopt->write();
- $S['wizard.module']=$femod;
- $module=&$S['wizard.module'];
- $S['wizard.step']=1;
+ $S['wizard']['configuration']=new sql_configuration();
+ wizard::set_configuration($S['wizard']['configuration']);
+ $configuration=&$S['wizard']['configuration'];
+ $configuration->name=$request['name'];
+ $mods=explode(' ', $conf['modules']);
+ $mod=isset($request['mod']) && isset($mods[$request['mod']])?$mods[$request['mod']]:$mods[0];
+ $configuration->module=$mod;
+ $configuration->init();
+ debug('wizard', "Module: $mod");
+ wizard_load_step(1);
}
- if (isset($S['wizard.configuration'], $S['wizard.step'])) {
- $step=&$S['wizard.step'];
- if (is_file(FRONTEND."/modules/$module/step$step.php")) {
- require_once(FRONTEND."/modules/$module/step$step.php");
- $S['title']='Create - Step '.$step;
- $proc=$module.'_init_step'.$step;
- if (function_exists($proc)) {
- return $proc();
- } else {
- debug('wizard', 'No init function for step '.$step);
- return;
- }
- } else {
- throw_exception("$module step $step doesn't exist");
- }
+ if (isset($S['wizard']['step'])) {
+ return array('title' => $S['wizard']['step']->title);
+ } else {
+ return array('title' => 'Create');
}
- return array('title' => 'Create');
}
function body_configurations_wizard() {
global $S, $conf;
- if (isset($S['wizard.configuration'])) {
- if (isset($S['wizard.done'])) {
- echo print_success('Config finished!', '<form action="'.url('configurations').'" method="post"><input type="hidden" name="configuration" value="'.$S['wizard.configuration']->id.'" />Name (optional): <input name="name" value="'.($S['wizard.configuration']->name?htmlentities($S['wizard.configuration']->name):'').'" /> <input type="submit" name="build" value="Build" /></form>');
+ if (isset($S['wizard']['configuration'])) {
+ $configuration=&$S['wizard']['configuration'];
+ if ($configuration->status == 0) {
+ echo print_success('Config finished!', '<form action="'.url('configurations').'" method="post"><input type="hidden" name="configuration" value="'.$configuration->id.'" />Name (optional): <input name="name" value="'.($configuration->name?htmlentities($configuration->name):'').'" /> <input type="submit" name="build" value="Build" /></form>');
} else {
- $configuration=&$S['wizard.configuration'];
- $module=&$S['wizard.module'];
- $step=&$S['wizard.step'];
- echo '<h3>'.$S['title'].'</h3>';
- echo '<form action="'.url('config/'.$configuration->id).'" method="post">';
- require_once(FRONTEND."/modules/$module/step$step.php");
- $proc=$module.'_body_step'.$step;
- if (!function_exists($proc)) {
- throw_exception("Body function doesn't exist for $module step $step");
- }
- $proc();
- echo '<input type="submit" name="wizard_submit" value="Continue" /></form>';
+ $S['wizard']['step']->output();
}
} else {
echo '<form action="'.url('create').'" method="post"><h3>Request an image built</h3>Name of your configuration (optional): <input name="name" /><br/>';
- $femods=explode(' ', $conf['frontend_modules']);
- $bemods=explode(' ', $conf['backend_modules']);
- if (count($femods) > 1) {
- echo 'Frontend module: <select name="femod">';
+ $mods=explode(' ', $conf['modules']);
+ if (count($mods) > 1) {
+ echo 'Module: <select name="mod">';
$i=0;
- foreach ($femods as $mod)
- echo '<option value="'.$i++."\">$mod</option>";
- echo '</select><br/>';
- }
- if (count($bemods) > 1) {
- echo 'Backend module: <select name="bemod">';
- $i=0;
- foreach ($bemods as $mod)
+ foreach ($mods as $mod)
echo '<option value="'.$i++."\">$mod</option>";
echo '</select><br/>';
}
echo '<input type="submit" name="init" value="Start" /></form>';
}
}
+function &wizard_load_step($step) {
+ global $S;
+ if (!isset($S['wizard']['steps'][$step])) {
+ $S['wizard']['steps'][$step]=new wizard_step($S['wizard']['configuration']->module, $step);
+ }
+ $S['wizard']['step']=&$S['wizard']['steps'][$step];
+ return $S['wizard']['steps'];
+}
?>
diff --git a/frontend/pages/upload.php b/frontend/pages/upload.php
index 0c5ceb3..04f8036 100644
--- a/frontend/pages/upload.php
+++ b/frontend/pages/upload.php
@@ -11,7 +11,7 @@ function init_upload() {
return '404';
}
$build=new sql_build($r->fetch(PDO::FETCH_ASSOC));
- $opts=$build->get_buildopts();
+ $opts=$build->get_opts();
if (!(isset($opts['uploadkey']) && $opts['uploadkey'] == $request['key'])) {
debug('upload', 'invalid upload key');
return '404';
diff --git a/shared/classes/1conf_build_common.php b/shared/classes/1conf_build_common.php
new file mode 100644
index 0000000..4e74d09
--- /dev/null
+++ b/shared/classes/1conf_build_common.php
@@ -0,0 +1,92 @@
+<?php
+abstract class conf_build_common extends sql_row_obj {
+ private $info;
+ private function set_vars() {
+ if (isset($this->info)) {
+ return;
+ }
+ $array=array(
+ 'sql_configuration' => array(
+ 'optsclass' => 'sql_configopt',
+ 'optstable' => 'configopts',
+ 'self' => 'configuration',
+ ),
+ 'sql_build' => array(
+ 'optsclass' => 'sql_buildopt',
+ 'optstable' => 'buildopts',
+ 'self' => 'build'
+ )
+ );
+ $this->info=$array[get_class($this)];
+ }
+ // Fetches all available configopts pertaining to this configuration in a nice array (cached)
+ private $opt_cache;
+ public function &get_opts($get_objs=false) {
+ $this->set_vars();
+ global $S;
+ if (!isset($this->opt_cache)) {
+ $this->opt_cache=array();
+ $r=$S['pdo']->query('SELECT * FROM `'.$this->info['optstable'].'` WHERE `'.$this->info['self'].'`="'.$this->id.'"');
+ while ($opt=$r->fetch(PDO::FETCH_ASSOC)) {
+ $this->opt_cache[$opt['name']]=new $this->info['optsclass']($opt);
+ }
+ }
+ if ($get_objs) {
+ return $this->opt_cache;
+ } else {
+ $opts=array();
+ foreach ($this->opt_cache as $opt) {
+ $opts[$opt->name]=$opt->value;
+ }
+ }
+ return $opts;
+ }
+ // Generates a unique id and sets status to 1, writes self to db and returns id
+ public function init() {
+ global $S;
+ $this->owner=$S['user']->id;
+ $this->status=1;
+ $fails=0;
+ while (true) {
+ $id=randstring(6);
+ debug("Trying id=$id...");
+ $r=$S['pdo']->query('SELECT `id` FROM `'.$this->table.'` WHERE `id`="'.$id.'"');
+ if ($r->rowCount() == 0) {
+ break;
+ }
+ if (++$fails == 10) {
+ throw_exception('Failed 10 times to find a unique id in table `'.$this->table.'`... this shouldn\'t happen.');
+ }
+ }
+ $this->id=$id;
+ $this->write();
+ return $this->id;
+ }
+ public function summary() {
+ $opts=$this->get_opts();
+ $r=array();
+ foreach($opts as $name => $val) {
+ $name=htmlentities($name);
+ $val=htmlentities($val);
+ $r[]="$name</td><td class=\"val\">$val";
+ }
+ if ($r) {
+ return '<table class="configsummary"><tr><td class="name">'.implode('</td></tr><tr><td class="name">', $r).'</td></tr></table>';
+ } else {
+ return '<i>No options set</i>';
+ }
+ }
+ // Sets a particular config/buildopt, using either UPDATE or INSERT
+ public function set_opt($name, $val) {
+ $this->set_vars();
+ $opts=$this->get_opts(true);
+ if (isset($opts[$name])) {
+ $opts[$name]->value=$val;
+ $opts[$name]->write();
+ } else {
+ $this->opt_cache[$name]=new $this->info['optsclass']($this->id, $name, $val);
+ $this->opt_cache[$name]->write();
+ }
+ }
+}
+?>
diff --git a/shared/classes/build.php b/shared/classes/build.php
index 9b2decc..b13ac29 100644
--- a/shared/classes/build.php
+++ b/shared/classes/build.php
@@ -1,5 +1,5 @@
<?php
-class sql_build extends sql_row_obj {
+class sql_build extends conf_build_common {
protected $table='builds', $primary_key=array('id'), $columns=array(
'id' => array (
'type' => 'CHAR',
@@ -41,38 +41,6 @@ class sql_build extends sql_row_obj {
'unsigned' => true
)
);
- // Generates a unique id and sets status to config/step0, writes self to db and returns id
- public function init() {
- global $S;
- $this->owner=$S['user']->id;
- $this->status='config/step1';
- $fails=0;
- while (true) {
- $id=randstring(6);
- debug("Trying id=$id...");
- $r=$S['pdo']->query('SELECT `id` FROM `builds` WHERE `id`="'.$id.'"');
- if ($r->rowCount() == 0) {
- break;
- }
- if (++$fails == 10) {
- throw_exception('Failed 10 times to find a unique build id... this shouldn\'t happen.');
- }
- }
- $this->id=$id;
- $this->write();
- return $this->id;
- }
- // Fetches all available buildopts pertaining to this build in a nice array
- function &get_buildopts() {
- global $S;
- $r=$S['pdo']->query('SELECT * FROM `buildopts` WHERE `build`="'.$this->id.'"');
- $opts=array();
- while ($opt=$r->fetch(PDO::FETCH_ASSOC)) {
- $opt=new sql_buildopt($opt);
- $opts[$opt->name]=$opt->value; // TODO maybe we should return the actual objects
- }
- return $opts;
- }
// Returns HTML code describing this build's status (for human consumption)
function display() {
global $S;
diff --git a/shared/classes/configuration.php b/shared/classes/configuration.php
index 088908f..fedef12 100644
--- a/shared/classes/configuration.php
+++ b/shared/classes/configuration.php
@@ -1,5 +1,5 @@
<?php
-class sql_configuration extends sql_row_obj {
+class sql_configuration extends conf_build_common {
protected $table='configurations', $primary_key=array('id'), $columns=array(
'id' => array (
'type' => 'CHAR',
@@ -19,51 +19,25 @@ class sql_configuration extends sql_row_obj {
'type' => 'VARCHAR',
'length' => 255
),
- 'status' => array (
+ 'module' => array (
'type' => 'VARCHAR',
'length' => 255,
'not_null' => true,
'default' => ''
+ ),
+ 'status' => array (
+ 'type' => 'TINYINT',
+ 'length' => 4,
+ 'not_null' => true,
+ 'default' => 0
)
);
- // Generates a unique id and sets status to config/step0, writes self to db and returns id
- public function init() {
- global $S;
- $this->owner=$S['user']->id;
- $this->status='config/step1';
- $fails=0;
- while (true) {
- $id=randstring(6);
- debug("Trying id=$id...");
- $r=$S['pdo']->query('SELECT `id` FROM `configurations` WHERE `id`="'.$id.'"');
- if ($r->rowCount() == 0) {
- break;
- }
- if (++$fails == 10) {
- throw_exception('Failed 10 times to find a unique configuration id... this shouldn\'t happen.');
- }
- }
- $this->id=$id;
- $this->write();
- return $this->id;
- }
- // Fetches all available configopts pertaining to this configuration in a nice array
- function &get_configopts() {
- global $S;
- $r=$S['pdo']->query('SELECT * FROM `configopts` WHERE `configuration`="'.$this->id.'"');
- $opts=array();
- while ($opt=$r->fetch(PDO::FETCH_ASSOC)) {
- $opt=new sql_configopt($opt);
- $opts[$opt->name]=$opt->value; // TODO maybe we should return the actual objects
- }
- return $opts;
- }
- function build($name=null) {
+ public function build($name=null) {
$build=new sql_build();
$build->init();
$build->name=$name;
- $opts=$this->get_configopts();
+ $opts=$this->get_opts();
$opts['configuration']=$this->id;
foreach ($opts as $name => $val) {
$opt=new sql_buildopt($build->id, $name, $val);
@@ -74,22 +48,8 @@ class sql_configuration extends sql_row_obj {
$build->write();
return $build;
}
- function summary() {
- $opts=$this->get_configopts();
- $r=array();
- foreach($opts as $name => $val) {
- $name=htmlentities($name);
- $val=htmlentities($val);
- $r[]="$name</td><td class=\"val\">$val";
- }
- if ($r) {
- return '<table class="configsummary"><tr><td class="name">'.implode('</td></tr><tr><td class="name">', $r).'</td></tr></table>';
- } else {
- return '<i>No options set</i>';
- }
- }
// Returns an array of the IDs of all the builds that report this configuration as their source
- function get_builds() {
+ public function get_builds() {
global $S;
$r=$S['pdo']->query('SELECT `build` FROM `buildopts` WHERE `name`="configuration" AND `value`="'.$this->id.'"');
if ($r->rowCount()) {
diff --git a/shared/config.php b/shared/config.php
index d48d17e..b42cb8a 100644
--- a/shared/config.php
+++ b/shared/config.php
@@ -6,8 +6,7 @@ $conf['sqlpass']='socpassword'; // MySQL password
$conf['sqldb']='soc'; // MySQL database
$conf['debug']=true; // Whether to print debugging information
$conf['cache']=true; // Whether to enable built-in caching
-$conf['backend_modules']='gentoo_portage gentoo_catalyst'; // Space-separated list of backend modules to offer the user
-$conf['frontend_modules']='gentoo'; // Space-separated list of frontend modules to offer the user
+$conf['modules']='gentoo_portage x gentoo_catalyst'; // Space-separated list of modules to offer the user
$conf['cookiename']='ingenueid'; // Name of the cookie to send for keeping sessions
$conf['sessionlength']=1814400; // Time in seconds before sessions are purged
$conf['timezone']=10800; // Time difference in seconds between UTC and the default timezone