diff options
author | Eudyptula <eitan@mosenkis.net> | 2009-07-07 17:19:21 -0400 |
---|---|---|
committer | Eudyptula <eitan@mosenkis.net> | 2009-07-07 17:19:21 -0400 |
commit | 2b92850a6aaa28074cddba730b11ab606a3adcd9 (patch) | |
tree | 43c29ba3cf393cc7d541af1cb824388cea6def00 | |
parent | Fix blip with favicon.ico (diff) | |
download | ingenue-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-x | backend/backend.php | 2 | ||||
-rw-r--r-- | depend | 2 | ||||
-rw-r--r-- | frontend/classes/wizard_api.php | 171 | ||||
-rw-r--r-- | frontend/css/pkgs.css | 22 | ||||
-rw-r--r-- | frontend/js/debug.js.php | 3 | ||||
-rw-r--r-- | frontend/js/pkgsearch.js | 75 | ||||
-rw-r--r-- | frontend/modules/gentoo/step1.php | 30 | ||||
-rw-r--r-- | frontend/modules/gentoo/step2.php | 110 | ||||
-rw-r--r-- | frontend/modules/gentoo/step3.php | 29 | ||||
l--------- | frontend/modules/gentoo_catalyst | 1 | ||||
l--------- | frontend/modules/gentoo_portage | 1 | ||||
-rw-r--r-- | frontend/pages/configurations/wizard.php | 160 | ||||
-rw-r--r-- | frontend/pages/upload.php | 2 | ||||
-rw-r--r-- | shared/classes/1conf_build_common.php | 92 | ||||
-rw-r--r-- | shared/classes/build.php | 34 | ||||
-rw-r--r-- | shared/classes/configuration.php | 62 | ||||
-rw-r--r-- | shared/config.php | 3 |
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) { @@ -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, ' '); 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 |