We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 11858
    • 130 Posts
    I have read a CSV file and converted all values into an associative array. Print_r reads:

    
     Array
            (
                [] => 1
                [RegId] => 31519946
                [EventId] => 946203
                [EventTitle] => xxxxx
                [ClientEventId] => 
                [GroupId] => 31519946
                [StatusDescription] => Confirmed
                [RegTypeDescription] => xxxxxxx
                [first_Name] => xx
                [last_Name] => xx
                [FirstLastName] => xxxxx
                [City] => London
                [Country] => United Kingdom
                [HomePhone] => 12123112312
                [CellPhone] => 1212121212
                [Email_Address] => [email protected]
                [DateOfBirth] => 5-Mar-1980
                [Gender] => M
                [Nationality] => United Kingdom
                [BibNumber] => 
                [EmergencyContactName] => xxxxx
                [EmergencyContactPhone] => 12123132
            )
     
      Array
           (
                [] => 2
                [RegId] => 31520986
                [EventId] => 946203
                [EventTitle] => xxxxxxx
                [ClientEventId] => 
                [GroupId] => 31520986
                [StatusDescription] => Confirmed
                [RegTypeDescription] => xxxxxx
                [first_Name] => xxxx
                [last_Name] => xxxx
                [FirstLastName] => xxxxxx
                [City] => Smarden
                [Country] => United Kingdom
                [HomePhone] => 2324323323
                [CellPhone] => 123232133
                [Email_Address] => [email protected]
                [DateOfBirth] => 20-Jul-1962
                [Gender] => F
                [Nationality] => United Kingdom
                [BibNumber] => 
                [EmergencyContactName] => xxxxx
                [EmergencyContactPhone] => 23232323
            )
    
    


    Etc.

    I’d like to insert this data into the DB using xpdo. This is my code:

    
    <?php
    $path = MODX_CORE_PATH . 'components/athletes/';
    $result = $modx->addPackage('athletes',$path . 'model/','cr_');
    
    if (! $result) {
      echo 'failed to add package';
    } else {
      echo '<p>Connected to live DB!</p>';
    }
    
    
    
    function csvToArr($filepath)
    {
        $headings = array();    // Array of headings
        $filedata = array();    // Data Array    
        
        // Get file handle
        $handle = fopen($filepath, "r");
    
        // Get field headings
        $fileline = fgetcsv($handle, 5000, ",");
        foreach( $fileline as $field ) { $headings[] = $field; }
    
        // Get data
        $line = 0;
        while (($fileline = fgetcsv($handle, 5000, ",")) !== FALSE)
        {
            foreach( $headings as $k => $v )
            {
                // Store data against field headings
                $filedata[$line][$v] = $fileline[$k];
                
                
                
            }
    
                // echo to see if I am getting the correct array (I am) 
                echo "<pre>";
                print_r( $filedata[$line] );
                echo "</pre>";
    
                // Add to xpdo object and save
                $addEntrant = $modx->newObject('runnerentrant');
                $addEntrant->fromArray($filedata[$line]);
                $addEntrant->save();
    	
            $line++;
        }	
     
        return $filedata;
        
    }
        
    csvToArr("http://link.to.csv");
    
    
    


    It gives a fatal error

    Fatal error: Call to a member function newObject() on a non-object in /home1/centuri8/public_html/centurionrunning/core/cache/includes/elements/modsnippet/133.include.cache.php on line 48
    


    I’m relatively new to xpdo, I have created the schema for runnerentrant, so that’s ok. Can anyone point me to a working example of how to get a CSV or an associative array into a custom table using xpdo? TIA!
      • 3749
      • 24,544 Posts
      It looks like you are trying to run this code outside of MODX where the $modx object is not available.

      If you put the code in a snippet and a tag for that snippet on a page, previewing the page should run the code.

      If you need to do it outside of MODX, add code like this at the top:

      <?php
      define('MODX_CORE_PATH', 'full/path/to/your/modx/core/');
      define('MODX_CONFIG_KEY', 'config');
      require_once MODX_CORE_PATH . 'model/modx/modx.class.php';
      $modx= new modX();
      $modx->initialize('mgr');
      
        Did I help you? Buy me a beer
        Get my Book: MODX:The Official Guide
        MODX info for everyone: http://bobsguides.com/modx.html
        My MODX Extras
        Bob's Guides is now hosted at A2 MODX Hosting
        • 11858
        • 130 Posts
        Thanks for replying bobray.

        It is in a snippet and is called from within a MODx page. Could it be because it’s called in while loop and it’s out of scope? Can’t be as the $MODx object is global?

        I use the same $modx->addpackage code in other snippets to access tables and have no problems...
          • 21257 MODX Staff
          • 730 Posts
          You still have to reference the global modX object inside your function (e.g. global $modx), or preferably, pass it into your function.

          Once you can access it in your function, it looks like your code should work.
            Mike Schell
            Lead Developer, MODX Cloud
            Email: [email protected]
            GitHub: https://github.com/netProphET/
            Twitter: @mkschell
            • 11858
            • 130 Posts
            Thanks netphophet, I added global $modx; and away it went!

            I'd like it to update any records that are in there table - at the moment it adds records to the list every time the script is run. What's the best way to do this? RegId is the unique number that can be used to update a record. Basically I want it to INSERT if regid is not present, otherwise UPDATE if it is. I can't see an update() in the xpdo documentation...

            Thanks very much for your help.
              • 11858
              • 130 Posts
              Just found https://forums.modx.com/index.php?topic=58830.0

              Will see if I can implement this tonight...
                • 11858
                • 130 Posts
                I've updated my code:

                
                <?php
                function csvToArr($filepath)
                {
                    global $modx;
                    $path = MODX_CORE_PATH . 'components/athletes/';
                    $result = $modx->addPackage('athletes',$path . 'model/','cr_');
                    
                    $headings = array();    // Array of headings
                    $filedata = array();    // Data Array    
                    
                
                    if (! $result) {
                       echo '<p>failed to add package</p>';
                    } else {
                       echo '<p>Connected to live DB!</p>';
                    }
                
                
                    
                    // Get file handle
                    $handle = fopen($filepath, "r");
                
                    // Get field headings
                    $fileline = fgetcsv($handle, 5000, ",");
                    foreach( $fileline as $field ) { $headings[] = $field; }
                
                    // Get data
                    $line = 0;
                    while (($fileline = fgetcsv($handle, 5000, ",")) !== FALSE)
                    {
                        foreach( $headings as $k => $v )
                        {
                            // Store data against field headings
                            $filedata[$line][$v] = $fileline[$k]; 
                        }
                
                            // print out results
                            echo "<pre>";
                            print_r( $filedata[$line] );
                            echo "</pre>";
                            echo "<br />RegId: " . $filedata[$line]['RegId'] . "<br />";
                            
                        
                        	// get record that matches RegId already entered in the runnerEntrant table  
                			
                			$runnerEntrants = $modx->getCollection('RunnerEntrant',array(
                				'RegId' => $filedata[$line]['RegId'],
                			));
                			
                			
                			echo "<h1>runnerEntrants: count " . count($runnerEntrants) . "</h1><pre>";
                            print_r($runnerEntrants);
                            echo "</pre>";
                			
                			
                			
                			
                			if($enteredEntrants === null) {
                				echo "<br />INSERT<br />";
                 				$addEntrant = $modx->newObject('RunnerEntrant');
                            	$addEntrant->fromArray($filedata[$line]);
                            	$addEntrant->save();
                			} else {
                				echo "<br />UPDATE<br />";
                				$addEntrant = $modx->newObject('RunnerEntrant');
                            	$addEntrant->fromArray($filedata[$line]);
                            	$addEntrant->set('AutoId' , $runnerEntrants->get('AutoId'));
                            	$addEntrant->save();
                			}
                			
                	
                        $line++;
                	} //end while loop
                 
                  
                    
                }
                    
                
                csvToArr("www.xxxxx.com/xx.csv");
                




                When it runs first and there's no records in the runnerEntrant table, it runs fine and adds all the records, and I can see all my echo calls on the webpage. When it is then run a second time the page goes white and always adds only 57 records, all duplicates. Run it again, adds 27 duplicates.

                I am going wrong somewhere and because the page is white I can't see my debugging echo calls. There is nothing in the modx error log either. Anyone know where I am going wrong or how I can debug this?

                Thanks [ed. note: Hat-rack last edited this post 15 years, 1 month ago.]
                  • 11858
                  • 130 Posts
                  I'm a bit stuck on this still - any clues?
                    • 26903
                    • 1,336 Posts
                    echo "UPDATE";
                                    $addEntrant = $modx->newObject('RunnerEntrant');

                    This will add a record not update one, you have to get the record you want to update using getObject first, then update it, then save it.
                      Use MODx, or the cat gets it!
                      • 11858
                      • 130 Posts
                      Excellent, thanks Shamblett, NetProphet and Bobray - I got it working.

                      My final code if anyone is wondering:

                      <?php
                      function csvToArr($filepath)
                      {
                          global $modx;
                          $path = MODX_CORE_PATH . 'components/athletes/';
                          $result = $modx->addPackage('athletes',$path . 'model/','cr_');
                         
                          
                          $headings = array();    // Array of headings
                          $filedata = array();    // Data Array    
                          
                      
                          if (! $result) {
                             echo '<p>failed to add package</p>';
                          } else {
                             echo '<p>Connected to live DB!</p>';
                          }
                      
                      
                          
                          // Get file handle
                          $handle = fopen($filepath, "r");
                      
                          // Get field headings
                          $fileline = fgetcsv($handle, 5000, ",");
                          foreach( $fileline as $field ) { $headings[] = $field; }
                      
                          // Get data
                          $line = 0;
                          while (($fileline = fgetcsv($handle, 5000, ",")) !== FALSE)
                          {
                              foreach( $headings as $k => $v )
                              {
                                  // Store data against field headings
                                   $filedata[$line][$v] = ucwords(strtolower($fileline[$k])); 
                              }
                      
                                  // print out results
                                  /*
                                  echo "<pre>";
                                  print_r( $filedata[$line] );
                                  echo "</pre>";
                                  */
                                  $joggerId = $filedata[$line]['RegId'];
                                  // echo "<br />RegId: " . $filedata[$line]['RegId'] . "<br /> JoggerId: " . $joggerId . "<br />";
                                  
                              	// get record that matches RegId already entered in the runnerEntrant table  
                                  $jogger = $modx->getObject('RunnerEntrant',array('RegId' => $joggerId));
                      			
                      			// echo "<h1>jogger: count " . count($jogger) . "</h1>";
                      			
                      			
                      			if($jogger === null) {
                      				echo "<p><strong>INSERT</strong><br />" . $filedata[$line]['FirstLastName'] . "</p>";
                       				$addEntrant = $modx->newObject('RunnerEntrant');
                                  	$addEntrant->fromArray($filedata[$line]);
                                  	$addEntrant->save();
                      			} else {
                      				echo "<p><strong>UPDATE</strong><br />" . $filedata[$line]['FirstLastName'] . "</p>";
                      				$updateEntrant = $modx->getObject('RunnerEntrant',array('RegId' => $joggerId));
                                  	$updateEntrant->fromArray($filedata[$line]);
                                  	$updateEntrant->save();
                      			}
                      			
                      	
                              $line++;
                      	} //end while loop
                       
                        
                          fclose($handle);
                      }
                          
                      
                      
                      csvToArr("https://link.to.csv");