Home > Software design >  Update XML element text with PHP
Update XML element text with PHP

Time:01-02

I'm trying to update XML element text based upon a form submission. It is a userdatabase and im using the user's password as a reference to update their user id. The passwords all all unique so I thought it would be an easy element to reference. However whenever I attempt to edit a UID it fails and sends me to my error page I created if the function fails. Im not sure where I went wrong any assistance would be great.

Update UID Function

function updateUID($pass, $file, $new)
{
    $xml = new DOMDocument();
    $xml->load($file);
    $record = $xml->getElementsByTagName('UniqueLogin');
    foreach ($record as $person) {
        $password_id = $person->getElementsByTagName('Password')->item(0)->nodeValue;
        //$person_name=$person->getElementsByTagName('name')->item(0)->nodeValue;
        if ($password_id == $password) {
            $id_matched = true;
            $updated  = $xml->createTextNode($new);
            $person->parentNode->replaceChild($person, $updated);
            
            break;
        }
    }
    if ($id_matched == true) {
        if ($xml->save($file)) {
            return true;
        }
    }
    
}

Code that calls the function

session_start();
include_once "includes/functions.inc.php";
include_once "includes/jdbh.inc.php";
include_once "includes/dbh.inc.php";
include_once "includes/ftpconn2.inc.php";
$file = $_SESSION['fileNameXML'];
if (file_exists($file)) {
    if (isset($_POST['submit'])) {
        $pass = $_POST['id'];
        //$uid = $_SESSION['userid'];
        $new  = $_POST['uid'];
        //$entry = getUsername($jconn, $uid)." deleted a server ban for".$name;
        //if (isset($_GET['confirm'])) {
            if (updateUID($pass, $file, $new)) {
                //createLogEntry($conn, $uid, $entry);
                if (1 < 2) { //This is intentional to get around the $message varible below that is not required. 
                    $message = $affectedRow . " records inserted";
                    try {
                        $ftp_connection = ftp_connect($ftp_server);
                        if (false === $ftp_connection) {
                            throw new Exception("Unable to connect");
                            
                        }
                        $loggedIn = ftp_login($ftp_connection, $ftp_user, $ftp_password);
                        if (true === $loggedIn) {
                            //echo "Success!";
                        } else {
                            throw new Exception('unable to log in');
                        }
                        $local_file1  = "HostSecurity.xml";
                        $remote_file1 = "HostSecurity.xml";
                        if (ftp_put($ftp_connection, $local_file1, $remote_file1, FTP_BINARY)) {
                            //echo "Successfully written to $local_file\n";
                            
                        } else {
                            echo "There was a problem";
                        }
                        ftp_close($ftp_connection);
                        header("location: ../serverPasswords.php");
                    }
                    catch (Exception $e) {
                        echo "Failure:" . $e->getMessage();
                    }
                }
                header("location: ../serverPasswords.php");
            } else {
                header("location: ../serverPasswords.php?e=UIDNPD");
            }
    } else {
        echo "id missing";
    }
} else {
    echo "$file missing";
}
<Unique_Logins>
<UniqueLogin>
  <UID>AA23GHRDS657FGGRSF126</UID>
  <Password>iMs0Az2Zqh</Password>
</UniqueLogin>
<UniqueLogin>
  <UID>AA23GSDGFHJKDS483FGGRSF126</UID>
  <Password>Ab7wz77kM</Password>
</UniqueLogin>
</Unique_Logins>

CodePudding user response:

I believe the issue was caused by the undeclared variable $password in the logic test and the fact that the function never returns an alternative value if things go wrong.

As per the comment regarding XPath - perhaps the following might be of interest.

<?php

    $pass='xiMs0Az2Zqh';
    $file='logins.xml';
    $new='banana';



    function updateUID( $pass=false, $file=false, $new=false ){
        if( $pass & $file & $new ){
            $dom = new DOMDocument();
            $dom->load( $file );
            
            # attempt to match the password with this XPath expression
            $expr=sprintf( '//Unique_Logins/UniqueLogin/Password[ contains(.,"%s") ]', $pass );

            $xp=new DOMXPath( $dom );
            $col=$xp->query( $expr );
            
            # We have a match, change the UID ( & return a Truthy value )
            if( $col && $col->length===1 ){
                $xp->query('UID', $col->item(0)->parentNode )->item(0)->nodeValue=$new;
                return $dom->save( $file );
            }
        }
        # otherwise return false
        return false;
    }
    
    
    $res=updateUID( $pass, $file, $new );
    
    if( $res ){
        echo 'excellent';
    }else{
        echo 'bogus';
    }

?>

CodePudding user response:

I'm still not clear on exactly what's wrong, but if I understand you correctly, try making these changes in your code and see if it works:

#just some dummy values
$oldPass = "Ab7wz77kM";
$newUid  = "whatever";

$record = $xml->getElementsByTagName('UniqueLogin');
foreach ($record as $person) {
    $password_id = $person->getElementsByTagName('Password');
    $user_id     = $person->getElementsByTagName('UID');
    if ($password_id[0]->nodeValue == $oldPass) {
        $user_id[0]->nodeValue = $newUid;
    }
}
  • Related