src/Blob/BlobUtil.php
public static function blob2file($file_id)
    {
        global $CFG, $PDOX;

        if ( !isset($CFG->dataroot) || strlen($CFG->dataroot) < 1 ) return;

        $stmt = $PDOX->prepare("SELECT file_sha256, blob_id
            FROM {$CFG->dbprefix}blob_file
            WHERE path IS NULL AND file_id = :ID");
        $stmt->execute(array(':ID' => $file_id));

        $row = $stmt->fetch(\PDO::FETCH_ASSOC);
        if ( ! $row ) return false;

        $blob_id = $row['blob_id'];
        $file_sha256 = $row['file_sha256'];
        $blob_folder = BlobUtil::mkdirSha256($file_sha256);
        if ( ! $blob_folder ) {
            return "Error: migrate=$file_id folder failed sha=$file_sha256";
        }
        $blob_name =  $blob_folder . '/' . $file_sha256;

        $lob = false;
        if ( ! $blob_id ) {
            // Cope gracefully when there is no content column in blob_file
            try {
                $lstmt = $PDOX->prepare("SELECT content FROM {$CFG->dbprefix}blob_file WHERE file_id = :ID");
                $lstmt->execute(array(":ID" => $file_id));
                $lstmt->bindColumn(1, $lob, \PDO::PARAM_LOB);
                $lstmt->fetch(\PDO::FETCH_BOUND);
            } catch (\Exception $e) {
                return "Error: No content to migrate for legacy blob file_id=$file_id";
            }
        } else {
            $lstmt = $PDOX->prepare("SELECT content FROM {$CFG->dbprefix}blob_blob WHERE blob_id = :ID");
            $lstmt->execute(array(":ID" => $blob_id));
            $lstmt->bindColumn(1, $lob, \PDO::PARAM_LOB);
            $lstmt->fetch(\PDO::FETCH_BOUND);
        }

        if ( ! is_string($lob) ) {
            return "Error: LOB is not a string. fi=$file_id bi=$blob_id";
        }

        $retval = file_put_contents($blob_name, $lob);
        if ( $retval != strlen($lob) ) {
            return "Error: Failed to write fi=$file_id (".strlen($lob).") to $blob_name";
        }
        error_log("Migrated fi=$file_id (".strlen($lob).") to $blob_name");
        $lstmt = $PDOX->prepare("UPDATE {$CFG->dbprefix}blob_file
            SET path=:PATH, blob_id=NULL WHERE file_id = :ID");
        $lstmt->execute(array(
            ":ID" => $file_id,
            ":PATH" => $blob_name
        ));

        // Make sure to handle the fact that content might not be there...
        try {
            $lstmt = $PDOX->prepare("UPDATE {$CFG->dbprefix}blob_file
                SET content=NULL WHERE file_id = :ID");
            $lstmt->execute(array( ":ID" => $file_id));
        } catch (\Exception $e ) {
            // No problem - the column won't be there...
        }
        return true;
    }
public static function blob2file($file_id)
    {
        global $CFG, $PDOX;

        if ( !isset($CFG->dataroot) || strlen($CFG->dataroot) < 1 ) return;

        $stmt = $PDOX->prepare("SELECT file_sha256, blob_id
            FROM {$CFG->dbprefix}blob_file
            WHERE path IS NULL AND file_id = :ID");
        $stmt->execute(array(':ID' => $file_id));

        $row = $stmt->fetch(\PDO::FETCH_ASSOC);
        if ( ! $row ) return false;

        $blob_id = $row['blob_id'];
        $file_sha256 = $row['file_sha256'];
        $blob_folder = BlobUtil::mkdirSha256($file_sha256);
        if ( ! $blob_folder ) {
            return "Error: migrate=$file_id folder failed sha=$file_sha256";
        }
        $blob_name =  $blob_folder . '/' . $file_sha256;

        $lob = false;
        if ( ! $blob_id ) {
            // Cope gracefully when there is no content column in blob_file
            try {
                $lstmt = $PDOX->prepare("SELECT content FROM {$CFG->dbprefix}blob_file WHERE file_id = :ID");
                $lstmt->execute(array(":ID" => $file_id));
                $lstmt->bindColumn(1, $lob, \PDO::PARAM_LOB);
                $lstmt->fetch(\PDO::FETCH_BOUND);
            } catch (\Exception $e) {
                return "Error: No content to migrate for legacy blob file_id=$file_id";
            }
        } else {
            $lstmt = $PDOX->prepare("SELECT content FROM {$CFG->dbprefix}blob_blob WHERE blob_id = :ID");
            $lstmt->execute(array(":ID" => $blob_id));
            $lstmt->bindColumn(1, $lob, \PDO::PARAM_LOB);
            $lstmt->fetch(\PDO::FETCH_BOUND);
        }

        if ( ! is_string($lob) ) {
            return "Error: LOB is not a string. fi=$file_id bi=$blob_id";
        }

        $retval = file_put_contents($blob_name, $lob);
        if ( $retval != strlen($lob) ) {
            return "Error: Failed to write fi=$file_id (".strlen($lob).") to $blob_name";
        }
        error_log("Migrated fi=$file_id (".strlen($lob).") to $blob_name");
        $lstmt = $PDOX->prepare("UPDATE {$CFG->dbprefix}blob_file
            SET path=:PATH, blob_id=NULL WHERE file_id = :ID");
        $lstmt->execute(array(
            ":ID" => $file_id,
            ":PATH" => $blob_name
        ));

        // Make sure to handle the fact that content might not be there...
        try {
            $lstmt = $PDOX->prepare("UPDATE {$CFG->dbprefix}blob_file
                SET content=NULL WHERE file_id = :ID");
            $lstmt->execute(array( ":ID" => $file_id));
        } catch (\Exception $e ) {
            // No problem - the column won't be there...
        }
        return true;
    }
public static function blob2file ( $ file_id ) { global $ CFG , $ PDOX ; if ( ! isset ( $ CFG -> dataroot ) || strlen ( $ CFG -> dataroot ) < 1 ) return ; $ stmt = $ PDOX -> prepare ( "SELECT file_sha256, blob_id
            FROM {$CFG->dbprefix}blob_file
            WHERE path IS NULL AND file_id = :ID" ) ; $ stmt -> execute ( array ( ':ID' => $ file_id ) ) ; $ row = $ stmt -> fetch ( \ PDO :: FETCH_ASSOC ) ; if ( ! $ row ) return false ; $ blob_id = $ row [ 'blob_id' ] ; $ file_sha256 = $ row [ 'file_sha256' ] ; $ blob_folder = BlobUtil :: mkdirSha256 ( $ file_sha256 ) ; if ( ! $ blob_folder ) { return "Error: migrate=$file_id folder failed sha=$file_sha256" ; } $ blob_name = $ blob_folder . '/' . $ file_sha256 ; $ lob = false ; if ( ! $ blob_id ) { // Cope gracefully when there is no content column in blob_file try { $ lstmt = $ PDOX -> prepare ( "SELECT content FROM {$CFG->dbprefix}blob_file WHERE file_id = :ID" ) ; $ lstmt -> execute ( array ( ":ID" => $ file_id ) ) ; $ lstmt -> bindColumn ( 1 , $ lob , \ PDO :: PARAM_LOB ) ; $ lstmt -> fetch ( \ PDO :: FETCH_BOUND ) ; } catch ( \ Exception $ e ) { return "Error: No content to migrate for legacy blob file_id=$file_id" ; } } else { $ lstmt = $ PDOX -> prepare ( "SELECT content FROM {$CFG->dbprefix}blob_blob WHERE blob_id = :ID" ) ; $ lstmt -> execute ( array ( ":ID" => $ blob_id ) ) ; $ lstmt -> bindColumn ( 1 , $ lob , \ PDO :: PARAM_LOB ) ; $ lstmt -> fetch ( \ PDO :: FETCH_BOUND ) ; } if ( ! is_string ( $ lob ) ) { return "Error: LOB is not a string. fi=$file_id bi=$blob_id" ; } $ retval = file_put_contents ( $ blob_name , $ lob ) ; if ( $ retval != strlen ( $ lob ) ) { return "Error: Failed to write fi=$file_id (" . strlen ( $ lob ) . ") to $blob_name" ; } error_log ( "Migrated fi=$file_id (" . strlen ( $ lob ) . ") to $blob_name" ) ; $ lstmt = $ PDOX -> prepare ( "UPDATE {$CFG->dbprefix}blob_file
            SET path=:PATH, blob_id=NULL WHERE file_id = :ID" ) ; $ lstmt -> execute ( array ( ":ID" => $ file_id , ":PATH" => $ blob_name ) ) ; // Make sure to handle the fact that content might not be there... try { $ lstmt = $ PDOX -> prepare ( "UPDATE {$CFG->dbprefix}blob_file
                SET content=NULL WHERE file_id = :ID" ) ; $ lstmt -> execute ( array ( ":ID" => $ file_id ) ) ; } catch ( \ Exception $ e ) { // No problem - the column won't be there... } return true ; }
Check and migrate a blob to its corresponding file

@return mixed true if the file was migrated, false if the file
was not migrated, and a string if an error was enountered
Check and migrate a blob to its corresponding file