11
redheadedrod
Re: Inserting multiple rows in database table

After briefly looking at your code....
For starters You need to put the foreach loop inside of the for loop instead of outside of it.

As is $datas is only going to contain the last copy of the array and you will only load the database with this last entry.

You need to place it inside the for loop in order for you to properly step through all of the entries.

Your foreach loop looks ok otherwise to me but I might be missing something.

You really need to first get your code in the right place and if it still isn't working you need to step through the code.

As zyspec mentioned you also need to make sure the database isn't setup with a unique field because if you keep running your code and you are only seeing one entry this is because you are only updating the entry you have instead of making a new one due to the unique field.

Your first $datas = array(); line is unnecessary because you are doing it a couple of lines later. Although this shouldn't cause any issues as is otherwise.

I also agree with Zyspecs comments about creating the object and deleting it afterwards. Otherwise your object could contain items you don't expect.
Rodney

12
zyspec
Re: Inserting multiple rows in database table
  • 2014/4/21 16:04

  • zyspec

  • Module Developer

  • Posts: 1095

  • Since: 2004/9/21


Rodney's correct... I didn't notice that $datas was only being filled with the latest copy of the array.

You can also accomplish this by changing the following line:
$datas = array('field_mid' => $table_mid[$i],


with:
$datas[] = array('field_mid' => $table_mid[$i],

13
Mamba
Re: Inserting multiple rows in database table
  • 2014/4/21 17:07

  • Mamba

  • Moderator

  • Posts: 11409

  • Since: 2004/4/23


Quote:
You can also accomplish this by changing the following line:
$datas = array('field_mid' => $table_mid[$i],

with:
$datas[] = array('field_mid' => $table_mid[$i],

Yep, that was I was looking for:

$datas[] = array('field_mid' => $table_mid[$i],

Thanks guys for providing the fix for it. Hopefully Timgno can use it now...
Support XOOPS => DONATE
Use 2.5.11 | Docs | Modules | Bugs

14
timgno
Re: Inserting multiple rows in database table
  • 2014/4/21 17:45

  • timgno

  • Module Developer

  • Posts: 1504

  • Since: 2007/6/21


I'm glad of your help, but it did not work either as you say

Meanwhile, I found some very interesting tools:

http://marcelog.github.io/articles/ci_jenkins_hudson_continuous_integration_php_phing.html

And look the modifies:
Admin/fields.php
case 'save':
        if ( !
$GLOBALS['xoopsSecurity']->check() ) {
            
redirect_header('fields.php'3implode(','$GLOBALS['xoopsSecurity']->getErrors()));
        } 
        
        if (isset(
$field_id)) {
            
$obj =& $fieldsHandler->get($field_id);
        } else {
            
$obj =& $fieldsHandler->create();
        }
        if (
$table_nbfields 0) {
            for( 
$i 0$i $table_nbfields$i++ ) {                    
                
$datas[] = array('field_mid' => $table_mid[$i], 
                                
'field_tid' => $table_id[$i],                                
                                
'field_numb' => $table_nbfields[$i], 
                                
'field_name' => $_POST['field_name'][$i], 
                                
'field_type' => $_POST['field_type'][$i], 
                                
'field_value' => $_POST['field_value'][$i], 
                                
'field_attribute' => $_POST['field_attribute'][$i], 
                                
'field_null' => $_POST['field_null'][$i], 
                                
'field_default' => $_POST['field_default'][$i], 
                                
'field_key' => $_POST['field_key'][$i],    
                                
'field_autoincrement' => (($_REQUEST['field_autoincrement'][$i] == 1) ? '1' '0'),
                                
'field_element' => $_POST['field_element'][$i],                            
                                
'field_inlist' => (($_REQUEST['field_inlist'][$i] == 1) ? '1' '0'),
                                
'field_inform' => (($_REQUEST['field_inform'][$i] == 1) ? '1' '0'),
                                
'field_admin' => (($_REQUEST['field_admin'][$i] == 1) ? '1' '0'),
                                
'field_user' => (($_REQUEST['field_user'][$i] == 1) ? '1' '0'), 
                                
'field_block' => (($_REQUEST['field_block'][$i] == 1) ? '1' '0'), 
                                
'field_main' => (($i == $_REQUEST['field_main']) ? '1' '0'), 
                                
'field_search' =>  (($_REQUEST['field_search'][$i] == 1) ? '1' '0'), 
                                
'field_required' => (($_REQUEST['field_required'][$i] == 1) ? '1' '0')
                                );        
                foreach (
$datas as $value) {                
                    
$obj->setVars$value );
                    
$fieldsHandler->insert($obj);                        
                }                                            
            }                
        }
        if (
$obj->isNew()) {            
            
redirect_header('fields.php'2sprintf(_AM_TDMCREATE_FIELD_FORM_SAVED_OK$_REQUEST['table_name']));
        } else {
            
redirect_header('fields.php'2sprintf(_AM_TDMCREATE_FIELD_FORM_UPDATED_OK$_REQUEST['table_name']));
        }        
        
//
        
$GLOBALS['xoopsTpl']->assign('error'$obj->getHtmlErrors());               
        
$form $obj->getForm($field_mid$field_tid$field_numb$field_name);
        
$GLOBALS['xoopsTpl']->assign('form'$form->render());
    break;


class/fields.php
public function getForm($f_mid null$f_tid null$f_numb null$f_name null$action false)
    {
        if (
$action === false) {
            
$action XOOPS_URL.'/modules/TDMCreate/admin/fields.php'//$_SERVER['REQUEST_URI'];
        
}
        
$isNew $this->isNew();
        
$title $isNew sprintf(_AM_TDMCREATE_FIELD_ADD) : sprintf(_AM_TDMCREATE_FIELD_EDIT);
        
        
$field_mid $isNew $f_mid $this->getVar('field_mid');
        
$field_tid $isNew $f_tid $this->getVar('field_tid');
        
$field_numb $isNew $f_numb $this->getVar('field_numb');
        
        
$form = new TDMCreateThemeForm(null'form'$action'post'true);
        
$form->setExtra('enctype="multipart/form-data"');            

        
$tablesHandler xoops_getModuleHandler('tables');
        
//$fieldsHandler = xoops_getModuleHandler('fields');
        
$fieldelementsHandler =& xoops_getModuleHandler('fieldelements');    
        
$fieldtypeHandler =& xoops_getModuleHandler('fieldtype');
        
$fieldattrsHandler =& xoops_getModuleHandler('fieldattributes');
        
$fieldnullHandler =& xoops_getModuleHandler('fieldnull');    
        
$fieldkeyHandler =& xoops_getModuleHandler('fieldkey');        
        
// New Object HtmlTable           
        
$form->addElement(new TDMCreateFormLabel(''));
        
$form->addElement(new TDMCreateFormLabel(''));    
        
$form->addElement(new TDMCreateFormLabel(''.$title.''));
        
$form->addElement(new TDMCreateFormLabel(''));                
        
$form->addElement(new TDMCreateFormLabel(''._AM_TDMCREATE_FIELD_NUMBER.''));
        
$form->addElement(new TDMCreateFormLabel(''._AM_TDMCREATE_FIELD_NAME.''));                                                        
        
$form->addElement(new TDMCreateFormLabel(''._AM_TDMCREATE_FIELD_TYPE.''));
        
$form->addElement(new TDMCreateFormLabel(''._AM_TDMCREATE_FIELD_VALUE.''));
        
$form->addElement(new TDMCreateFormLabel(''._AM_TDMCREATE_FIELD_ATTRIBUTE.''));
        
$form->addElement(new TDMCreateFormLabel(''._AM_TDMCREATE_FIELD_NULL.''));
        
$form->addElement(new TDMCreateFormLabel(''._AM_TDMCREATE_FIELD_DEFAULT.''));
        
$form->addElement(new TDMCreateFormLabel(''._AM_TDMCREATE_FIELD_KEY.''));
        
$form->addElement(new TDMCreateFormLabel(''._AM_TDMCREATE_FIELD_PARAMETERS.''));    
        
$form->addElement(new TDMCreateFormLabel(''));    
        
$form->addElement(new TDMCreateFormLabel(''));
                
        
//$fields = $fieldsHandler->getObjects(null);
        
        
$class '';
        for(
$i 1$i <= $field_numb$i++)
        {        
            
$class = ($class == 'even') ? 'odd' 'even';                        
            
$form->addElement(new TDMCreateFormLabel('.$class.'">'));
            
// Index ID
            
$form->addElement(new TDMCreateFormLabel(''.$i.''));
             
// Field Name
            
$this_field_name $isNew ? (!empty($f_name) ? $f_name '_' '') : $this->getVar('field_name');
            
$field_name = new XoopsFormText(_AM_TDMCREATE_FIELD_NAME'field_name['.$i.']'15255$this_field_name);            
            
$form->addElement(new TDMCreateFormLabel(''.$field_name->render().''));
            
// Field Type            
            
$fieldtype_select = new XoopsFormSelect(_AM_TDMCREATE_FIELD_TYPE'field_type['.$i.']'$this->getVar('field_type'));
            
$fieldtype_select->addOptionArray($fieldtypeHandler->getList()); 
            
$form->addElement(new TDMCreateFormLabel(''.$fieldtype_select->render().''));
            
// Field Value            
            
$field_value = new XoopsFormText(_AM_TDMCREATE_FIELD_VALUE'field_value['.$i.']'520$this->getVar('field_value'));
            
$form->addElement(new TDMCreateFormLabel(''.$field_value->render().''));
            
// Field Attributes                        
            
$field_attributes_select = new XoopsFormSelect(_AM_TDMCREATE_FIELD_TYPE'field_attribute['.$i.']'$this->getVar('field_attribute'));  
            
$field_attributes_select->addOptionArray($fieldattrsHandler->getList());
            
$form->addElement(new TDMCreateFormLabel(''.$field_attributes_select->render().''));
            
// Field Null            
            
$field_null_select = new XoopsFormSelect(_AM_TDMCREATE_FIELD_NULL'field_null['.$i.']'$this->getVar('field_null'));
            
$field_null_select->addOptionArray($fieldnullHandler->getList());            
            
$form->addElement(new TDMCreateFormLabel(''.$field_null_select->render().''));
            
// Field Default
            
$field_default = new XoopsFormText(_AM_TDMCREATE_FIELD_DEFAULT'field_default['.$i.']'1525$this->getVar('field_default'));
            
$form->addElement(new TDMCreateFormLabel(''.$field_default->render().''));
            
// Field Key
            
$field_key_select = new XoopsFormSelect(_AM_TDMCREATE_FIELD_KEY'field_key['.$i.']'$this->getVar('field_key'));
            
$field_key_select->addOptionArray($fieldkeyHandler->getList());
            
$form->addElement(new TDMCreateFormLabel(''.$field_key_select->render().''));
            
// Field Autoincrement
            
if($i == 1)  {                
                
$field_autoincrement $this->isNew() ? $this->getVar('field_autoincrement');
                
$check_field_autoincrement = new XoopsFormCheckBox(' ''field_autoincrement['.$i.']'$field_autoincrement);
                
$check_field_autoincrement->addOption(1_AM_TDMCREATE_FIELD_AUTO_INCREMENT);
                
$form->addElement(new TDMCreateFormLabel(''.$check_field_autoincrement->render().''));
            } elseif(
$i 1) {                
                
// Box header row                
                
$parameters_tray = new XoopsFormElementTray('''');        
                
// Field Elements                
                
$field_elements_select = new XoopsFormSelect(_AM_TDMCREATE_FIELD_ELEMENT_NAME'field_element['.$i.']'$this->getVar('field_element'));                    
                    
$field_elements_select->addOptionArray($fieldelementsHandler->getList());                                        
                    
$criteria = new CriteriaCompo(new Criteria('table_id'$f_tid));
                    
$criteria->add(new Criteria('table_mid'$f_mid));                    
                    
$criteria->setSort('table_name');
                    
$criteria->setOrder('ASC');
                    
$table_arr $tablesHandler->getAll($criteria);
                    unset(
$criteria);
                    foreach (
array_keys($table_arr) as $xft_other
                    {                                  
                        
$form_table_name $table_arr[$xft_other]->getVar('table_name');
                        if ( 
$xft_other[$i] == 'XoopsFormTables-'.$form_table_name ) {                                
                            
$field_elements_select->addOption('XoopsFormTables-'.$form_table_name'Table : '.$form_table_name);                        
                        }                                                    
                    }
                    
$parameters_tray->addElement($field_elements_select);
                                
                
$field_inlist $this->isNew() ? $this->getVar('field_inlist');
                    
$check_field_inlist = new XoopsFormCheckBox(' ''field_inlist['.$i.']'$field_inlist);
                    
$check_field_inlist->addOption(1_AM_TDMCREATE_FIELD_INLIST);
                    
$parameters_tray->addElement($check_field_inlist);
                
                
$field_inform $this->isNew() ? $this->getVar('field_inform');
                    
$check_field_inform = new XoopsFormCheckBox(' ''field_inform['.$i.']'$field_inform);
                    
$check_field_inform->addOption(1_AM_TDMCREATE_FIELD_INFORM);
                    
$parameters_tray->addElement($check_field_inform);

                
$field_admin $this->isNew() ? $this->getVar('field_admin');
                    
$check_field_admin = new XoopsFormCheckBox(' ''field_admin['.$i.']'$field_admin);
                    
$check_field_admin->addOption(1_AM_TDMCREATE_FIELD_ADMIN);
                    
$parameters_tray->addElement($check_field_admin);

                
$field_user $this->isNew() ? $this->getVar('field_user');
                    
$check_field_user = new XoopsFormCheckBox(' ''field_user['.$i.']'$field_user);
                    
$check_field_user->addOption(1_AM_TDMCREATE_FIELD_USER);
                    
$parameters_tray->addElement($check_field_user);

                
$field_block $this->isNew() ? $this->getVar('field_block');
                    
$check_field_block = new XoopsFormCheckBox('''field_block['.$i.']'$field_block);
                    
$check_field_block->addOption(1_AM_TDMCREATE_FIELD_BLOCK);
                    
$parameters_tray->addElement($check_field_block);

                
$field_mnfield $this->isNew() ? $this->getVar('field_main');
                    
$field_main = new XoopsFormRadio('''field_main['.$i.']'$field_mnfield);
                    
$field_main->addOption$i_AM_TDMCREATE_FIELD_MAINFIELD );
                    
$parameters_tray->addElement($field_main);

                
$field_search $this->isNew() ? $this->getVar('field_search');
                    
$check_field_search = new XoopsFormCheckBox(' ''field_search['.$i.']'$field_search);
                    
$check_field_search->addOption(1_AM_TDMCREATE_FIELD_SEARCH);    
                    
$parameters_tray->addElement($check_field_search);                    

                
$field_required $this->isNew() ? $this->getVar('field_required');
                    
$check_field_required = new XoopsFormCheckBox(' ''field_required['.$i.']'$field_required);
                    
$check_field_required->addOption(1_AM_TDMCREATE_FIELD_REQUIRED);
                    
$parameters_tray->addElement($check_field_required);

                
$form->addElement(new TDMCreateFormLabel(''.$parameters_tray->render().''));
            }                
            
$form->addElement(new XoopsFormHidden('field_id['.$i.']'$i));        
        }
                
        
$form->addElement(new XoopsFormHidden('field_mid'$field_mid));
        
$form->addElement(new XoopsFormHidden('field_tid'$field_tid)); 
        
$form->addElement(new XoopsFormHidden('field_numb'$field_numb));        
        
$form->addElement(new TDMCreateFormLabel(''));
        
$form->addElement(new TDMCreateFormLabel(''));
        
$form_hidden = new XoopsFormHidden('op''save');
        
$form_button = new XoopsFormButton('''submit'_SUBMIT'submit');
        
$form->addElement(new TDMCreateFormLabel(''.$form_hidden->render().''));
        
$form->addElement(new TDMCreateFormLabel(''.$form_button->render().''));
        
$form->addElement(new TDMCreateFormLabel(''));
        return 
$form;
    }


I posted all the code so that can see even those who are not registered to the forum and the potential to help

15
redheadedrod
Re: Inserting multiple rows in database table

A little help here.. Your code is a little wrong...

A quick primer...
$data = array('one' => '1''two'  => '2');


If you do a variable dump should look something like this...

$data {
one = 1
two = 2
}


$data[] = array('one' => '1''two'  => '2');
$data[] = array('three' => '3''four' => '4');


If you do a variable dump should look something like this...

$data {
array() {
one = 1
two = 2
}
array(){
three = 3
four = 4
}
}

if we took this one step further and did this:
$data = array('one' => '1''two'  => '2');
$data = array('three' => '3''four' => '4');


The second $data replaces the first and you get a variable dump that looks like this:
$data {
three = 3
four = 4
}

Note the difference..

In this most recent variation of your code every time you go to the foreach loop you will step through each element of the $datas variable that has been loaded and you will send a large array of all of your key/value pairs to the setvars.

The fix SHOULD be simple... Just remove the $[] from the $datas[] line.

I had thought to suggest the $datas[] suggestion until I realized how the code was running.

By adding the [] you are creating a 3 dimension array...
Without it you are doing a 2 dimension array.

I BELIEVE then you will step through each key/value pair and send this to setvars and SHOULD work. Assuming that setVars can accept an array.


In brief I think it is getting made more complicated than it needs to be. The original post should have worked just by moving the foreach loop within the for loop.

But again, this type of bug can be figured out by doing a series of variable dumps at different stages and looking at the value. This is a coding issue and not a database issue.

I do not have time to run this code at this time but I should be reasonably accurate.

Rodney

16
timgno
Re: Inserting multiple rows in database table
  • 2014/4/21 20:10

  • timgno

  • Module Developer

  • Posts: 1504

  • Since: 2007/6/21


You were very explanatory Rodney, but I think we should Work it yet to find a solution.

In the previous versions of this module, it was easy to put in a textarea all fields in a table.

I wanted to separate them because, as seen in the image of a previous post, there are icons on the cross, just in the right place to insert the object you want to appear on the form when we're going to create it in our class.

For example, in previous versions it was all so that was created based on how the code was written in the file creators.

With this system, the same as the model system block in admin that you can move in different places, this can also move an object to where we want it.

I hope was clear

Also entering the separate fields from the tables, these are more readable in the database in case of changes or views

17
Mamba
Re: Inserting multiple rows in database table
  • 2014/4/21 20:16

  • Mamba

  • Moderator

  • Posts: 11409

  • Since: 2004/4/23


Quote:
Meanwhile, I found some very interesting tools:

http://marcelog.github.io/articles/ci ... ntegration_php_phing.html

We've been using them already in the development of XOOPS 2.6.0, thanks to hard work by Alain91. See this news and look for the part about Jenkins.

And you and I had many emails about testing tools like PHPUnit and Sahi

But there are new tools that we're starting to use, and there will be soon a separate article about it
Support XOOPS => DONATE
Use 2.5.11 | Docs | Modules | Bugs

18
Mamba
Re: Inserting multiple rows in database table
  • 2014/4/21 20:47

  • Mamba

  • Moderator

  • Posts: 11409

  • Since: 2004/4/23


Quote:
but I think we should Work it yet to find a solution.

As I suggested earlier, the best way to see what is wrong is to debug it, i.e. to set a breakpoint and check the status of the variables. Then you can see if your logic is correct and you have what you expect.

That's what I did, and it seems that your issue is that the "$table_nbfields" variable is empty at the point when you get to this code:

if ($table_nbfields 0) {
    
$datas = array();
    for( 
$i 0$i $table_nbfields$i++ ) {
        
$datas[] = array('field_mid' => $table_mid[$i],
                        
'field_tid' => $table_id[$i],
                        
'field_numb' => $table_nbfields[$i],
                        
'field_name' => $_POST['field_name'][$i],
                        
'field_type' => $_POST['field_type'][$i],
                        
'field_value' => $_POST['field_value'][$i],
                        
'field_attribute' => $_POST['field_attribute'][$i],
                        
'field_null' => $_POST['field_null'][$i],
                        
'field_default' => $_POST['field_default'][$i],
                        
'field_key' => $_POST['field_key'][$i],
                        
'field_autoincrement' => (($_REQUEST['field_autoincrement'][$i] == 1) ? '1' '0'),
                        
'field_element' => $_POST['field_element'][$i],
                        
'field_inlist' => (($_REQUEST['field_inlist'][$i] == 1) ? '1' '0'),
                        
'field_inform' => (($_REQUEST['field_inform'][$i] == 1) ? '1' '0'),
                        
'field_admin' => (($_REQUEST['field_admin'][$i] == 1) ? '1' '0'),
                        
'field_user' => (($_REQUEST['field_user'][$i] == 1) ? '1' '0'),
                        
'field_block' => (($_REQUEST['field_block'][$i] == 1) ? '1' '0'),
                        
'field_main' => (($i == $_REQUEST['field_main']) ? '1' '0'),
                        
'field_search' =>  (($_REQUEST['field_search'][$i] == 1) ? '1' '0'),
                        
'field_required' => (($_REQUEST['field_required'][$i] == 1) ? '1' '0')
                        );
    }
    foreach (
$datas as $value) {
        
$obj->setVars$value );
        
$fieldsHandler->insert($obj);
    }
}


so this:

if ($table_nbfields 0)

will never be true and you will never get to the code that you have shown us. And of course, you will never be able to test any changes you are making to it.

You define the variable as:
$table_nbfields TDMCreate_CleanVars($_REQUEST'table_nbfields');

But there is no variable of this name in the $_REQUEST.

There is the "field_numb", which seems to be the one that you're should be using.
Fix that, and then you'll be able to see if the whole array issue is working or not.

Always check your logic to make sure that you are getting what you expect to get, and that's why tools like PHPUnit are so helpful
Support XOOPS => DONATE
Use 2.5.11 | Docs | Modules | Bugs

19
timgno
Re: Inserting multiple rows in database table
  • 2014/4/21 21:03

  • timgno

  • Module Developer

  • Posts: 1504

  • Since: 2007/6/21


It's true

I run a dump of the variables:
var_dump($table_id);
var_dump($table_mid);
var_dump($table_nbfields);
var_dump($table_fieldname);
var_dump($field_id);
var_dump($field_mid);
var_dump($field_tid);
var_dump($field_numb);
var_dump($field_name);

I find this result:
string '' (length=0)
string '' (length=0)
string '' (length=0)
string '' (length=0)
string '' (length=0)
string '' (length=0)
string '' (length=0)
string '' (length=0)
string '' (length=0)


The functions that I use for the requests are as follows:
// Get table Variables
$table_id TDMCreate_CleanVars($_REQUEST'table_id');
$table_mid TDMCreate_CleanVars($_REQUEST'table_mid');
$table_nbfields TDMCreate_CleanVars($_REQUEST'table_nbfields');
$table_fieldname TDMCreate_CleanVars($_REQUEST'table_fieldname''''string');
// Get field Variables
$field_id TDMCreate_CleanVars($_REQUEST'field_id');
$field_mid TDMCreate_CleanVars($_REQUEST'field_mid');
$field_tid TDMCreate_CleanVars($_REQUEST'field_tid');
$field_numb TDMCreate_CleanVars($_REQUEST'field_numb');
$field_name TDMCreate_CleanVars($_REQUEST'field_name''''string');

OR
// Get table Variables
$table_id TDMCreateRequest::getInt('table_id');
$table_mid TDMCreateRequest::getInt('table_mid');
$table_nbfields TDMCreateRequest::getInt('table_nbfields');
$table_fieldname TDMCreateRequest::getString('table_fieldname''');
// Get field Variables
$field_id TDMCreateRequest::getInt('field_id');
$field_mid TDMCreateRequest::getInt('field_mid');
$field_tid TDMCreateRequest::getInt('field_tid');
$field_numb TDMCreateRequest::getInt('field_numb');
$field_name TDMCreateRequest::getString('field_name''');


The result is always the same

20
Mamba
Re: Inserting multiple rows in database table
  • 2014/4/21 21:18

  • Mamba

  • Moderator

  • Posts: 11409

  • Since: 2004/4/23


You need to go step by step backwards.

You want to assign a sanitized value of "table_nbfields" from $_REQUEST:

$table_nbfields TDMCreate_CleanVars($_REQUEST'table_nbfields');

But "table_nbfields" is not there. So you need to find out why it is not there, by finding the place where you are setting up this variable to "get" or "post".

The logic errors are the worst, because the syntax might be correct, and you won't get any PHP errors or warnings, but the result is still wrong. So go back through your logic step by step, set up breakpoints on the way to make sure that the variable is still there, and with the correct value. Then move to the next step...

This is one of the best and most funny pictures about debugging:

Resized Image
Support XOOPS => DONATE
Use 2.5.11 | Docs | Modules | Bugs

Login

Who's Online

349 user(s) are online (262 user(s) are browsing Support Forums)


Members: 0


Guests: 349


more...

Donat-O-Meter

Stats
Goal: $100.00
Due Date: Nov 30
Gross Amount: $0.00
Net Balance: $0.00
Left to go: $100.00
Make donations with PayPal!

Latest GitHub Commits