#!/usr/local/php/bin/php 1) { $a0 = str_replace('.bat', '', basename($_SERVER['argv'][0])); $a1 = str_replace('.bat', '', basename($_SERVER['argv'][1])); if ($a0 == $a1 && $a1 == 'paypal-sdk-update') { array_shift($_SERVER['argv']); } } // Process command line arguments. switch (count($_SERVER['argv'])) { case 2: if (isValidCommand($_SERVER['argv'][1])) { $command = $_SERVER['argv'][1]; } else { usage(); } break; case 4: switch ($_SERVER['argv'][1]) { case '-e': case '--environment': if (isValidEnvironment($_SERVER['argv'][2]) && isValidCommand($_SERVER['argv'][3])) { $environment = $_SERVER['argv'][2]; $command = $_SERVER['argv'][3]; } else { usage(); } break; default: usage(); } break; default: usage(); } // Run command. $command(); // Done with main flow. All other code in this file is implementation // of commands and helper functions. exit; /** * Update the dynamic elements of the SDK. */ function update() { // Make sure we can write to the live files before attempting // anything further. canWritePackage(); // Clear out the build dir. $packageDir = Services_PayPal::getPackageRoot(); $buildDir = $packageDir . '/build/ppsdk-new/'; recursiveDelete($buildDir); if (!mkdir($buildDir)) { echo "Can't write to the build directory ($buildDir) - check your permissions.\nAborting.\n"; return false; } // Download new files and eventually check if they've changed. $urlBase = xmlFileBaseUrl(); if (!$urlBase) { echo "Can't find an environment mapping for $environment.\nAborting.\n"; return false; } foreach (xmlFiles() as $file) { // XXX remove this code block when paypal-endpoints.xml is in // the right place on PayPsl's webservers. if ($file == 'paypal-endpoints.xml') { if (!copy($packageDir . '/wsdl/paypal-endpoints.xml', $buildDir . $file)) { echo "Failed to download the latest version of $file.\nAborting.\n"; } continue; } if (!copy($urlBase . $file, $buildDir . $file)) { echo "Failed to download the latest version of $file.\nAborting.\n"; return false; } } // Get the SDK object. $sdk =& new PayPal_SDK($buildDir . 'PayPalSvc.wsdl'); // Write the new CallerServices.php. dieOnError($sdk->writeCallerServices($buildDir . 'CallerServices.php')); // Write the new types. mkdir($buildDir . '/Type'); dieOnError($sdk->writeTypes($buildDir . '/Type')); // Write the endpoint file. dieOnError($sdk->writeEndpointMap($buildDir . 'paypal-endpoints.php', $buildDir . 'paypal-endpoints.xml')); // Once the new SDK is successfully generated, back up the current // SDK. if (!backup(true)) { echo "Backup of the current SDK failed. Not overwriting files without a current backup. Exiting.\n"; return false; } // Finally overwrite the existing production files. // CallerServices.php. rollbackOnError(copy($buildDir . 'CallerServices.php', $packageDir . '/CallerServices.php')); // wsdl/* files. rollbackOnError(copy($buildDir . 'paypal-endpoints.php', $packageDir . '/wsdl/paypal-endpoints.php')); foreach (xmlFiles() as $file) { rollbackOnError(copy($buildDir . $file, $packageDir . '/wsdl/' . $file)); } // Types. $types = glob($buildDir . 'Type/*.php'); foreach ($types as $typeFile) { rollbackOnError(copy($typeFile, $packageDir . '/Type/' . basename($typeFile))); } // Clean up the build. recursiveDelete($buildDir); echo "The PayPal SDK has successfully been updated.\nThe new version is:\n"; version(); return true; } /** * Roll back to the last version of the SDK. */ function rollback() { echo "Attempting to roll back the PayPal SDK to the last saved version.\n"; // Check for an existing SDK backup. $packageDir = Services_PayPal::getPackageRoot(); $rollbackDir = $packageDir . '/build/ppsdk-backup/'; if (!is_dir($rollbackDir)) { echo "No SDK backup was found - perhaps you've never run the update?\nUnable to revert, exiting.\n"; return false; } // Make sure the backup contains all files. $expectedFiles = array_merge(xmlFiles(), array('CallerServices.php', 'Type')); foreach ($expectedFiles as $file) { if (!file_exists($rollbackDir . $file)) { echo "Expected to have $file backed up and it is not present. Not rolling back.\n"; return false; } } // Make sure we can write to the live files before attempting // anything further. canWritePackage(); // CallerServices.php. copy($rollbackDir . 'CallerServices.php', $packageDir . '/CallerServices.php'); // wsdl/* files. copy($rollbackDir . 'paypal-endpoints.php', $packageDir . '/wsdl/paypal-endpoints.php'); foreach (xmlFiles() as $file) { copy($rollbackDir . $file, $packageDir . '/wsdl/' . $file); } // Types. $types = glob($rollbackDir . 'Type/*.php'); foreach ($types as $typeFile) { copy($typeFile, $packageDir . '/Type/' . basename($typeFile)); } echo "The PayPal SDK has successfully been reverted.\nThe new version is:\n"; version(); return true; } /** * Print version information. */ function version() { $sdk = &new PayPal_SDK_Generator(); $wsdl_version = $sdk->getWSDLVersion(); $sdk_version = Services_PayPal::getPackageVersion(); echo <<getMessage() . "\n\nAborting.\n"); } elseif (!$result) { die(wordwrap("Fatal error - unable to continue. The SDK may be in an inconsistent state if we were in the middle of rolling back. Check file permissions, backups, and code integrity.\n")); } } /** * Check the result of a file operation, and initiate an automatic * rollback if it failed. * * @param boolean $result The result of an operation that might fail. */ function rollbackOnError($result) { if (!$result) { echo "Failed a file operation while installing new SDK - rolling back.\n"; rollback(); exit; } } /** * Die if we can't write to the live package files. */ function canWritePackage() { $packageDir = Services_PayPal::getPackageRoot(); if (!is_writable($packageDir . '/CallerServices.php')) { die("Unable to write to the live SDK files - insufficient permissions?\nAborting - fix permissions before continuing.\n"); } } /** * Get the URL base for WSDL files for the current environment. */ function xmlFileBaseUrl() { switch ($GLOBALS['environment']) { case 'Live': return 'http://www.paypal.com/wsdl/'; case 'Sandbox': return 'http://www.sandbox.paypal.com/wsdl/'; case 'beta-sandbox': return 'http://www.beta-sandbox.paypal.com/wsdl/'; default: return false; } }