Skip to content

Instantly share code, notes, and snippets.

@bohemima
Last active July 10, 2016 17:56
Show Gist options
  • Save bohemima/7a14b18797deadb3a9f9dabfb5b54de6 to your computer and use it in GitHub Desktop.
Save bohemima/7a14b18797deadb3a9f9dabfb5b54de6 to your computer and use it in GitHub Desktop.
Quick & dirty re-upload of pffiles, used to migrate files from hosted parse.com to self-hosted parse-server

Quick & dirty PFFiles migration script

Transfers PFFiles hosted on parse.com (files.parsetffs.com) to your self-hosted parse-server by simply downloading, re-uploading them and saving the object again. Beware that this will cause all of your rows containing a PFFile to get a new updatedAt date

Running

To run, make sure you install the dependencies using composer.phar install Edit the constants found in migrate.php, also edit the $mapping variable to match your classes and column names that contains PFFile's

define('SERVER_URL', 'http://example.com');
define('MOUNT_PATH', 'parse');
define('APPLICATION_ID', 'appid');
define('MASTER_KEY', 'masterkey');
define('OLD_PREFIX', 'http://files.parsetfss.com/'); // You can probably leave this one

$mapping = [
    '_User' => [
        'profileImage'
    ],
    'UserFiles' => [
        'SomeFileColumn', 'AnotherFileColumn'
    ]
];

With this setup, the script will connect to the parse-server at http://example.com/parse, loop over all profileImage's in the _User class and check if the files are still hosted at files.parsetfss.com, if they are, the file will be downloaded and then re-uploaded to your parse-server, after that, the object will be saved again - this time with the new URL to the file.

To run the script, simply open a terminal and enter php migrate.php and sit back, it might take some time on large datasets.

Caveats

  • Since the object will be saved again, all objects that have their PFFiles re-uploaded will get a new updatedAt date
  • Since objects are saved, any beforeSave and afterSave hooks will fire off. (These can return early if you simply check for usage of the masterKey)

Beer fund

If you found this simple script helpful, there is a beer fund located at paypal.me/mlmbrg

{
"name": "bohemima/pffilesmigration",
"authors": [
{
"name": "Henrik Malmberg",
"email": "henrik@funkar.nu"
}
],
"require": {
"parse/php-sdk": "^1.2"
}
}
<?php
require 'vendor/autoload.php';
define('SERVER_URL', 'https://your.server.here');
define('MOUNT_PATH', 'parse');
define('APPLICATION_ID', 'application id');
define('MASTER_KEY', 'master key');
define('OLD_PREFIX', 'http://files.parsetfss.com/');
$mapping = [
'_User' => [
'profileImage'
],
'UserFiles' => [
'SomeFileColumn', 'AnotherFileColumn'
]
];
\Parse\ParseClient::initialize(APPLICATION_ID, null, MASTER_KEY, true);
\Parse\ParseClient::setServerURL(SERVER_URL, MOUNT_PATH);
foreach ($mapping as $class => $columns) {
$lastCreatedAt = new DateTime('1983-07-11');
$query = new \Parse\ParseQuery($class);
$query->select($columns);
$query->ascending('createdAt');
$query->limit(500);
do {
$query->greaterThan('createdAt', $lastCreatedAt);
$results = $query->find(true);
foreach ($results as $result) {
$lastCreatedAt = $result->getCreatedAt();
foreach ($columns as $column) {
if ($result->has($column)) {
$file = $result->get($column);
if ($file instanceof \Parse\ParseFile) {
if (substr($file->getURL(), 0, strlen(OLD_PREFIX)) == OLD_PREFIX) {
$tempFile = tempnam(__DIR__, 'parse');
file_put_contents($tempFile, fopen($file->getURL(), 'r'));
$newFile = \Parse\ParseFile::createFromFile($tempFile, $file->getName(), $file->getMimeType());
if ($newFile->save()) {
$result->set($column, $newFile);
}
// Clean up
unlink($tempFile);
}
}
}
}
// This could probably be batched instead..
$result->save(true);
}
} while (sizeof($results) > 0);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment