* @package Kernel * @version $Id$ * */ error_reporting(E_ERROR); // Include the compression libs .. require_once(dirname(__FILE__) . '/external/compression/tar.php'); require_once(dirname(__FILE__) . '/external/compression/zip.php'); require_once(dirname(__FILE__) . '/external/compression/pclzip.lib.php'); require_once(dirname(__FILE__) . '/adodb/adodb-xmlschema03.inc.php'); class VCDXMLImporter { /** * XSD to validate VCD-db XML Movie files. * */ CONST XSD_VCDDB_MOVIES = "includes/schema/vcddb-export.xsd"; CONST XSD_VCDDB_MOVIES_LEGACY = "includes/schema/vcddb-export-legacy.xsd"; /** * XSD to validate VCD-db XML Thumbnails files. * */ CONST XSD_VCDDB_THUMBS = "includes/schema/vcddb-thumbnails.xsd"; static private $isLegacy = false; /** * Get the number of movie entries in the XML file. * * @param string $strXmlFile | The XML file to load and read from. * @return int | The number of movie entries found in XML file. */ public static function getXmlMovieCount($strXmlFile) { try { $file = TEMP_FOLDER.$strXmlFile; if (!file_exists($file)) { // try without the TEMP_FOLDER if (!file_exists($strXmlFile)) { throw new Exception("Could not load file " . $file); } else { $file = $strXmlFile; } } $xml = simplexml_load_file($file); $movieCount = count($xml->xpath("//vcdmovies/movie")); if (is_numeric($movieCount)) { return $movieCount; } else { return 0; } } catch (Exception $ex) { throw $ex; } } /** * Get the number of entries in the XML file. * * @param string $strXmlFile | The XML file to load and read from. * @return int | The number of cover entries found in the XML file. */ public static function getXmlThumbnailCount($strXmlFile) { try { $file = TEMP_FOLDER.$strXmlFile; if (!file_exists($file)) { throw new Exception("Could not load file " . $file); } $xml = simplexml_load_file($file); $coverCount = count($xml->xpath("//cdcover")); if (is_numeric($coverCount)) { return $coverCount; } else { return 0; } } catch (Exception $ex) { throw $ex; } } /** * Get the Movie Titles from the XML Movie file * * @param string $strXmlFile | The XML Movie file to read from. * @return array | Array of movie titles. */ public static function getXmlTitles($strXmlFile) { try { $xml = simplexml_load_file(TEMP_FOLDER.$strXmlFile); if (strcmp(self::getVariable('islegacy'), "1") == 0) { $movies = $xml->movie; } else { $movies = $xml->vcdmovies->movie; } $arrMovies = array(); foreach ($movies as $movie) { if ( strcmp((string)$movie->title, "") != 0 ) { array_push($arrMovies, utf8_decode((string)$movie->title)); } } return $arrMovies; } catch (Exception $ex) { throw $ex; } } /** * Handle a XML Movie upload and import. * * @return string | The uploaded file name */ public static function validateXMLMovieImport() { // Set the allowed extensions for the upload $arrExt = array(VCDUploadedFile::FILE_XML , VCDUploadedFile::FILE_TGZ , VCDUploadedFile::FILE_ZIP ); $VCDUploader = new VCDFileUpload($arrExt); if ($VCDUploader->getFileCount() != 1) { throw new Exception("No File was uploaded."); } $fileObj = $VCDUploader->getFileAt(0); // Move the file to the TEMP Folder $fileObj->move(TEMP_FOLDER); // Get the full path including filename after it has been moved $fileLocation = $fileObj->getFileLocation(); // Check if this is a compressed file .. $filename = $fileObj->getFileName(); if (strpos($filename, ".tgz")) { // The file is a tar archive .. lets untar it ... $zipfile = new tar(); if ($zipfile->openTAR($fileLocation)) { if ($zipfile->numFiles != 1) { throw new Exception('Only one XML file is allowed per Tar archive'); } $tar_xmlfile = $zipfile->files[0]['file']; $tar_xmlfilename = VCDUtils::generateUniqueId().".xml"; // Write the contents to cache VCDUtils::write(TEMP_FOLDER.$tar_xmlfilename, $tar_xmlfile); $fileLocation = TEMP_FOLDER.$tar_xmlfilename; // delete the original Tar file $fileObj->delete(); } else { throw new Exception('The uploaded TAR file could not be opened.'); } } elseif (strpos($filename, ".zip")) { $archive = new PclZip($fileLocation); if (($list = $archive->listContent()) == 0) { throw new Exception("No files found in archive.". $archive->errorInfo(true)); } if (sizeof($list) > 1) { throw new Exception("Only one file is allowed within the zip archive."); } if ($archive->extract(PCLZIP_OPT_PATH, TEMP_FOLDER) == 0) { throw new Exception($archive->errorInfo(true)); } $fileLocation = TEMP_FOLDER.$list[0]['filename']; // delete the original Zip file $fileObj->delete(); } /* Process the XML Thumbnail file */ if (!fs_file_exists($fileLocation)) { throw new Exception('Failed to open the Xml file.'); } // Validate the document before processing it .. $dom = new domdocument(); $dom->load($fileLocation); if (!@$dom->schemaValidate(self::XSD_VCDDB_MOVIES)) { throw new Exception("XML Document does not validate to the VCD-db XSD import schema.Please fix the document or export a new one.The schema can be found under '/includes/schema/vcddb-export.xsd'"); } // Check for Doc Version $appversion = null; $nodeList = $dom->getElementsByTagName('vcddb'); if (count($nodeList) > 0) { foreach ($nodeList as $node) { $appversion = $node->getAttribute('appversion'); } } if (is_null($appversion)) { self::$isLegacy = true; } // Set variables into the state container self::setVariables(self::getXmlMovieCount($fileLocation), $fileLocation, self::$isLegacy, $appversion); return str_replace(TEMP_FOLDER, "", $fileLocation); } /** * Handle a XML Thumbnail upload and import. * * @return string | The name of the uploaded XML file. */ public static function validateXMLThumbsImport() { // Set the allowed extensions for the upload $arrExt = array(VCDUploadedFile::FILE_XML , VCDUploadedFile::FILE_TGZ, VCDUploadedFile::FILE_ZIP ); $VCDUploader = new VCDFileUpload($arrExt); if ($VCDUploader->getFileCount() != 1) { throw new Exception("No File was uploaded."); } $fileObj = $VCDUploader->getFileAt(0); // Move the file to the TEMP Folder $fileObj->move(TEMP_FOLDER); // Get the full path including filename after it has been moved $fileLocation = $fileObj->getFileLocation(); // Check if this is a compressed file .. $filename = $fileObj->getFileName(); if (strpos($filename, ".tgz")) { // The file is a tar archive .. lets untar it ... $zipfile = new tar(); if ($zipfile->openTAR($fileLocation)) { if ($zipfile->numFiles != 1) { throw new Exception('Only one XML file is allowed per Tar archive'); } $tar_xmlfile = $zipfile->files[0]['file']; $tar_xmlfilename = VCDUtils::generateUniqueId().".xml"; // Write the contents to cache VCDUtils::write(TEMP_FOLDER.$tar_xmlfilename, $tar_xmlfile); $fileLocation = TEMP_FOLDER.$tar_xmlfilename; // delete the original Tar file $fileObj->delete(); } else { throw new Exception('The uploaded TAR file could not be opened.'); } } elseif (strpos($filename, ".zip")) { $archive = new PclZip($fileLocation); if (($list = $archive->listContent()) == 0) { throw new Exception("No files found in archive.". $archive->errorInfo(true)); } if (sizeof($list) > 1) { throw new Exception("Only one file is allowed within the zip archive."); } if ($archive->extract(PCLZIP_OPT_PATH, TEMP_FOLDER) == 0) { throw new Exception($archive->errorInfo(true)); } $fileLocation = TEMP_FOLDER.$list[0]['filename']; // delete the original Zip file $fileObj->delete(); } /* Process the XML Thumbnail file */ if (!fs_file_exists($fileLocation)) { throw new Exception('Failed to open the thumbnails file.'); } // Validate the document before processing it .. $dom = new domdocument(); $dom->load($fileLocation); $schema = self::XSD_VCDDB_THUMBS; if (!@$dom->schemaValidate($schema)) { throw new Exception("XML Document does not validate to the VCD-db Thumbnails XSD import schema.Please fix the document or export a new one.The schema can be found under '/includes/schema/vcddb-thumbnails.xsd'"); } unset($dom); return str_replace(TEMP_FOLDER, "", $fileLocation); } /** * Add a single movie from the $xmlfilename into database. * * @param string $xmlfilename | The XML Movie file to read from * @param int $index | The item index to read in the XML Movie file. * @param string $xmlthumbsfilename | The XML Thumbnail file to read from. * @return array | Status array containing status information. * @throws AjaxException */ public function addMovie($xmlfilename, $index, $xmlthumbsfilename = null) { try { if ($index == 0) { self::beginImport($xmlfilename); } $xml = simplexml_load_file(TEMP_FOLDER.$xmlfilename); if (strcmp(self::getVariable('islegacy'), "1") == 0) { $movie = $xml->movie[$index]; } else { $movie = $xml->vcdmovies->movie[$index]; } $status = "1"; $thumb = "0"; if (count($movie) > 0) { $movie_id = (string)$movie->id; $vcdObj = $this->createMovieObject($movie); if (!is_null($xmlthumbsfilename)) { $xmlthumbnail = TEMP_FOLDER.$xmlthumbsfilename; $coverObj = $this->getThumbnail($movie_id, $xmlthumbnail); if ($coverObj instanceof cdcoverObj ) { $thumb = "1"; $vcdObj->addCovers(array($coverObj)); } } // Delegate the vcdObj to the facade MovieServices::disableErrorHandler(); $iResults = -1; try { $iResults = MovieServices::addVcd($vcdObj, false); } catch (Exception $vex) { VCDUtils::write(TEMP_FOLDER."import_errors.txt", $vex->getMessage(). '\n', true); $status = "0"; } if (!is_numeric($iResults) || $iResults == -1) { $status = "0"; } } else { throw new Exception("Array index out of bounds [".$index."]."); } $arr = array( 'name' => utf8_encode((string)$movie->title), 'status' => utf8_encode($status), 'thumb' => utf8_encode($thumb)); if ($index == (int)(self::getVariable('moviecount')-1)) { self::endImport(); } return $arr; } catch (Exception $ex) { throw new AjaxException($ex->getMessage(), $ex->getCode()); } } /** * Get the imported thumbnail as cdCoverObj is it exists, otherwise returns null. * * @param int $vcd_id | The MovieID to find the matching cover * @param string $xmlfilename | The XML file name of the cover file. * @return cdcoverObj */ private function getThumbnail($vcd_id, $xmlfilename) { try { if (file_exists($xmlfilename) && is_file($xmlfilename)) { $xml = simplexml_load_file($xmlfilename); $query = "//vcdthumbnails/cdcover/vcd_id[. = {$vcd_id}]"; $nodeList = $xml->xpath($query); if (isset($nodeList)) { if (!isset($nodeList[0])) { return null;} $node = $nodeList[0]; $parent = $node->xpath('parent::node()'); if (isset($parent[0])) { $cover = $parent[0]; return $this->createThumbnailObject($cover); } } } return null; } catch (Exception $ex) { throw $ex; } } /** * Create a CDcoverObj from the XMLElement, returns null if cover is not Ok. * * @param SimpleXMLElement $element * @return cdcoverObj */ private function createThumbnailObject(SimpleXMLElement $element) { try { $filename = (string)$element->filename; $data = (string)$element->data; $cdCoverObj = null; CoverServices::disableErrorHandler(); // Check if the data is not null and then write the image to temp folder if ((strlen($data) > 0) && VCDUtils::write(TEMP_FOLDER.$filename, base64_decode($data))) { $cdCoverObj = new cdcoverObj(); $coverTypeObj = CoverServices::getCoverTypeByName("thumbnail"); $cdCoverObj->setCoverTypeID($coverTypeObj->getCoverTypeID()); $cdCoverObj->setCoverTypeName("Thumbnail"); $cdCoverObj->setFilename($filename); } return $cdCoverObj; } catch (Exception $ex) { throw $ex; } } /** * Create a vcdObj from the XMLElement, returns null if the vcdObj is not ok. * * @param SimpleXMLElement $element * @return vcdObj */ private function createMovieObject(SimpleXMLElement $element) { try { VCDServices::disableErrorHandler(); $adult_cat = SettingsServices::getCategoryIDByName('adult'); // Create the basic CD obj $basic = array('', utf8_decode((string)$element->title), (string)$element->category_id, (string)$element->year); $vcd = new vcdObj($basic); // Add 1 instance | Find the media type by name $mediaTypeObj = SettingsServices::getMediaTypeByName((string)$element->mediatype); if (is_null($mediaTypeObj)) { // Non existing media type ..then lets create mediatype $newMediaTypeObj = new mediaTypeObj(array('',(string)$element->mediatype,'null','Created by XML importer.')); SettingsServices::addMediaType($newMediaTypeObj); $mediaTypeObj = SettingsServices::getMediaTypeByName((string)$element->mediatype); } $vcd->addInstance(VCDUtils::getCurrentUser(), $mediaTypeObj, (string)$element->cds, (string)$element->dateadded); $movieCatObj = SettingsServices::getMovieCategoryByID((string)$element->category_id); if ($movieCatObj instanceof movieCategoryObj ) { $vcd->setMovieCategory($movieCatObj); } $source_id = ''; if ($element->category_id == $adult_cat) { // Adult flick // Check if any pornstars are associated in the movie $pornstars = $element->pornstars->pornstar; if (isset($pornstars)) { foreach ($pornstars as $pornstar) { $starObj = null; $starObj = PornstarServices::getPornstarByName((string)$pornstar->name); if ($starObj instanceof pornstarObj ) { $vcd->addPornstars($starObj); } else { // Star was not found in DB | create the entry $s = new pornstarObj(array('',(string)$pornstar->name, (string)$pornstar->homepage, '')); $vcd->addPornstars(PornstarServices::addPornstar($s)); } } } // Set the studio if any $studio = $element->studio; if (sizeof($studio) > 0) { $studioObj = PornstarServices::getStudioByName((string)$studio->name); if ($studioObj instanceof studioObj ) { $vcd->setStudioID($studioObj->getID()); } else { $studioObj = new studioObj(array('', (string)$studio->name)); PornstarServices::addStudio($studioObj); // Find the just added studioObj $studioObj = PornstarServices::getStudioByName((string)$studio->name); // And add it to the movie if ($studioObj instanceof studioObj ) { $vcd->setStudioID($studioObj->getID()); } } } try { $sourceSiteObj = SettingsServices::getSourceSiteByID((string)$element->sourcesite_id); if ($sourceSiteObj instanceof sourceSiteObj ) { $source_id = $sourceSiteObj->getsiteID(); } } catch (Exception $ex) {} // Add the adult categories if any $adult_categories = $element->adult_category->category; if (!is_null($adult_categories) && sizeof($adult_categories > 0)) { foreach ($adult_categories as $xmlcat) { $catObj = new porncategoryObj(array((string)$xmlcat->id, (string)$xmlcat->name)); $vcd->addAdultCategory($catObj); } } } else { // Normal flick if (isset($element->imdb)) { $imdb = $element->imdb; // Create the IMDB obj $obj = new imdbObj(); $obj->setIMDB((string)$imdb->imdb_id); $obj->setTitle(utf8_decode((string)$imdb->title)); $obj->setYear((string)$imdb->year); $obj->setDirector((string)$imdb->director); $obj->setGenre((string)$imdb->genre); $obj->setRating((string)$imdb->rating); $obj->setCast(utf8_decode(ereg_replace("\|",13,(string)$imdb->cast))); $obj->setPlot((string)$imdb->plot); $obj->setRuntime((string)$imdb->runtime); $obj->setCountry((string)$imdb->country); // Add the imdbObj to the VCD $vcd->setIMDB($obj); } try { $sourceSiteObj = SettingsServices::getSourceSiteByID((string)$element->sourcesite_id); if ($sourceSiteObj instanceof sourceSiteObj ) { $source_id = $sourceSiteObj->getsiteID(); } } catch(Exception $ex) {} } $external_id = (string)$element->external_id; // Set the source site if ($source_id != '' && $external_id != '') { $vcd->setSourceSite($source_id, $external_id); } // Check for comments $comments = $element->comments->comment; if (isset($comments) && !is_null($comments)) { foreach ($comments as $xmlComment) { $commentData = array('', '', VCDUtils::getUserID(), (string)$xmlComment->date, utf8_decode((string)$xmlComment->text), (string)$xmlComment->isPrivate); $commentObj = new commentObj($commentData); $vcd->addComment($commentObj); } } // Check for metadata $metadata = $element->meta->metadata; if (isset($metadata) && !is_null($metadata)) { foreach ($metadata as $xmlMeta) { $metaArr = array('', '', VCDUtils::getUserID(),(string)$xmlMeta->type_name, (string)$xmlMeta->data, $mediaTypeObj->getmediaTypeID(), (string)$xmlMeta->type_id, (int)$xmlMeta->type_level, (string)$xmlMeta->type_desc); $metaObj = new metadataObj($metaArr); $vcd->addMetaData($metaObj); } } return $vcd; } catch (Exception $ex) { throw $ex; } } /** * Keep track of data during the import process since the Ajax calls are totally stateless. * * @param int $movieCount | Number of movie entries in the XML file * @param string $fileName | The XML filename * @param bool $isLegacy | Is the XML file a legacy file or of the new version * @param string $appversion | The VCD-db version of the exported file. */ private static function setVariables($movieCount, $fileName, $isLegacy, $appversion=null) { $arrData = array(); $arrData['moviecount'] = $movieCount; $arrData['filename'] = $fileName; $arrData['appversion'] = $appversion; $arrData['islegacy'] = $isLegacy ? "1" : "0"; $session_name = "importer".VCDUtils::getUserID(); $_SESSION[$session_name] = $arrData; } /** * Get a variable from the state container * * @param sting $varName | The key to request * @return string | The returned value toString() */ private static function getVariable($varName) { $session_name = "importer".VCDUtils::getUserID(); if (isset($_SESSION[$session_name])) { $arrData = $_SESSION[$session_name]; if (isset($arrData[$varName])) { return (string)$arrData[$varName]; } } return null; } /** * Prepare the import * */ private static function beginImport($xmlFilename) { try { $isLegacy = self::getVariable('islegacy'); // Prepare only if file is not XML legacy file if (strcmp($isLegacy, "0") == 0) { $xmlDoc = simplexml_load_file(TEMP_FOLDER.$xmlFilename); $sourceSites = $xmlDoc->sourcesites->sourcesite; foreach ($sourceSites as $sourceSiteXML) { $sourceSiteObj = sourceSiteObj::__loadFromXML($sourceSiteXML); // Check if this sourcesite exists .. SettingsServices::disableErrorHandler(); if (is_null(SettingsServices::getSourceSiteByAlias($sourceSiteObj->getAlias()))) { // Create the sourceSite since it was not found. SettingsServices::addSourceSite($sourceSiteObj); } } unset($xmlDoc); } } catch (Exception $ex) { throw $ex; } } /** * Cleanup after the import. * */ private static function endImport() { try { fs_unlink(self::getVariable('filename')); // finally kill the session $session_name = "importer".VCDUtils::getUserID(); $_SESSION[$session_name] = null; } catch (Exception $ex) { throw $ex; } } } class VCDXMLExporter { CONST EXP_XML = 1; CONST EXP_TGZ = 2; CONST EXP_ZIP = 3; CONST EXP_XLS = 4; CONST XML_ENCODING = "UTF-8"; public static function exportMovies($expMethod, $iUserID = null) { try { // Cut some (inifinite) slack .. @set_time_limit(0); $xml = ""; // Create the root XMLElement $xml .= ""; // Add the sourcesites XMLElements $xml .= self::getXMLSourceSites(); // Add the movies XMLElements $xml .= self::getXMLMovies($iUserID); // Close the root XMLElement $xml .= ""; // Pretty print the XML $xmlObj = simplexml_load_string($xml); // Generate XML filename $XmlFilename = self::generateFileName('xml'); // Select export routine .. switch ($expMethod) { case self::EXP_XML: // Write the XML file to cache folder VCDUtils::write(CACHE_FOLDER.$XmlFilename, $xmlObj->asXML()); // Stream the file to browser self::sendFile(CACHE_FOLDER.$XmlFilename); // Delete the XML file from cache fs_unlink(CACHE_FOLDER.$XmlFilename); break; case self::EXP_ZIP: // Generate Zip filename $ZipFilename = self::generateFileName('zip'); $zipfile = new zipfile(); $zipfile->addFile($xmlObj->asXML(), $XmlFilename); // Write the zip file to cache folder VCDUtils::write(CACHE_FOLDER.$ZipFilename, $zipfile->file()); // Stream the file to browser self::sendFile(CACHE_FOLDER.$ZipFilename); // Delete the Zip file from cache fs_unlink(CACHE_FOLDER.$ZipFilename); break; case self::EXP_TGZ: // Generate Tar filename $TarFilename = self::generateFileName('tgz'); VCDUtils::write(CACHE_FOLDER.$XmlFilename, $xmlObj->asXML()); $zipfile = new tar(); $zipfile->addFile(CACHE_FOLDER.$XmlFilename); fs_unlink(CACHE_FOLDER.$XmlFilename); // Write the TAR file to disk VCDUtils::write(CACHE_FOLDER.$TarFilename, $zipfile->toTarOutput("movie_export", true)); // Stream the file to browser self::sendFile(CACHE_FOLDER.$TarFilename); // Delete the tar file from cache fs_unlink(CACHE_FOLDER.$TarFilename); break; default: throw new Exception('Undefined export method'); break; } } catch (Exception $ex) { throw new VCDException($ex); } } public static function exportThumbnails($expMethod, $iUserID = null) { try { // Cut some (inifinite) slack .. @set_time_limit(0); $COVERClass = VCDClassFactory::getInstance('vcd_cdcover'); if (is_null($iUserID)) { $arrCovers = $COVERClass->getAllThumbnailsForXMLExport(VCDUtils::getUserID()); } else { $arrCovers = $COVERClass->getAllThumbnailsForXMLExport($iUserID); } $xml = ""; $xml .= ""; foreach ($arrCovers as $cdcover) { $xml .= $cdcover->toXML(); } $xml .= ""; // Generate XML filename $XmlFilename = self::generateThumbFileName('xml'); // Select export routine .. switch ($expMethod) { case self::EXP_XML: // Write the XML file to cache folder VCDUtils::write(CACHE_FOLDER.$XmlFilename, $xml); // Stream the file to browser self::sendFile(CACHE_FOLDER.$XmlFilename); // Delete the XML file from cache fs_unlink(CACHE_FOLDER.$XmlFilename); break; case self::EXP_ZIP: // Generate Zip filename $ZipFilename = self::generateThumbFileName('zip'); $zipfile = new zipfile(); $zipfile->addFile($xml, $XmlFilename); // Write the zip file to cache folder VCDUtils::write(CACHE_FOLDER.$ZipFilename, $zipfile->file()); // Stream the file to browser self::sendFile(CACHE_FOLDER.$ZipFilename); // Delete the Zip file from cache fs_unlink(CACHE_FOLDER.$ZipFilename); break; case self::EXP_TGZ: // Generate Tar filename $TarFilename = self::generateThumbFileName('tgz'); VCDUtils::write(CACHE_FOLDER.$XmlFilename, $xml); $zipfile = new tar(); $zipfile->addFile(CACHE_FOLDER.$XmlFilename); fs_unlink(CACHE_FOLDER.$XmlFilename); // Write the TAR file to disk VCDUtils::write(CACHE_FOLDER.$TarFilename, $zipfile->toTarOutput("thumbnail_export", true)); // Stream the file to browser self::sendFile(CACHE_FOLDER.$TarFilename); // Delete the tar file from cache fs_unlink(CACHE_FOLDER.$TarFilename); break; default: throw new Exception('Undefined export method'); break; } } catch (Exception $ex) { throw new VCDException($ex); } } /** * Get the XML representation of all the SourceSiteObjects in VCD-db * * @return string | XML formatted string */ private static function getXMLSourceSites() { $xml = ""; foreach(SettingsServices::getSourceSites() as $sourceSiteObj) { $xml .= $sourceSiteObj->toXML(); } $xml .= ""; return $xml; } /** * Get the XML representation of the movie Objects. * if $iUserID is null, the movies for the logged in user are returned. * * @param int $iUserID | The owner of the movies * @return string | The XML formatted string */ private static function getXMLMovies($iUserID = null) { $xml = ""; if (!is_null($iUserID)) { $arrMovies = MovieServices::getAllVcdByUserId($iUserID, false); } else { $arrMovies = MovieServices::getAllVcdByUserId(VCDUtils::getUserID(), false); } foreach ($arrMovies as $vcdObj) { $xml .= $vcdObj->toXML(); } $xml .= ""; return $xml; } /** * Generate a filename for the exported file * * @param string $extension | The extension of the file about to be exported * @return string */ private static function generateFileName($extension) { $filename = "VCDdb-Export-".date("d.m.Y").".".$extension; return $filename; } /** * Generate a filename for the exported thumbnails file * * @param string $extension | The extension of the file about to be exported * @return string */ private static function generateThumbFileName($extension) { $filename = "VCDdb-Thumbnails-".date("d.m.Y").".".$extension; return $filename; } /** * Stream file to browser. Return true on success * * @param string $path | The file to stream * @return bool */ private static function sendFile($path) { session_write_close(); @ob_end_clean(); if (!is_file($path) || connection_status()!=0) return(FALSE); //to prevent long file from getting cut off from //max_execution_time @set_time_limit(0); $name=basename($path); //filenames in IE containing dots will screw up the //filename unless we add this if (strstr($_SERVER['HTTP_USER_AGENT'], "MSIE")) $name = preg_replace('/\./', '%2e', $name, substr_count($name, '.') - 1); //required, or it might try to send the serving //document instead of the file header("Cache-Control: "); header("Pragma: "); header("Content-Type: application/octet-stream"); header("Content-Length: " .(string)(filesize($path)) ); header('Content-Disposition: attachment; filename="'.$name.'"'); header("Content-Transfer-Encoding: binary\n"); if($file = fopen($path, 'rb')){ while( (!feof($file)) && (connection_status()==0) ){ print(fread($file, 1024*8)); flush(); } fclose($file); } return((connection_status()==0) and !connection_aborted()); } } /** * Export VCD-db data in SQL format * */ class VCDSQLExporter extends VCDConnection { CONST SCHEMA = 'includes/schema/vcddb-db.xml'; private $exportFilename; /** * Class constructor * */ public function __construct() { parent::__construct(); $this->exportFilename = 'VCDdb-Export-'.date("d.m.Y").'.sql'; // Delete the old file if it exists if (file_exists(VCDDB_BASE.DIRECTORY_SEPARATOR.TEMP_FOLDER.$this->exportFilename)) { unlink(VCDDB_BASE.DIRECTORY_SEPARATOR.TEMP_FOLDER.$this->exportFilename); } } /** * Export the VCD-db data as SQL insert script * * @param bool $exportTables | Create SQL for CREATE TABLES */ public function export($exportTables=false) { try { // Cut the exporter some slack .. @set_time_limit(60*10); if ($exportTables) { $this->exportTables(); } $this->exportData(); $this->sendFile(VCDDB_BASE.DIRECTORY_SEPARATOR.TEMP_FOLDER.$this->exportFilename); // clean up unlink(VCDDB_BASE.DIRECTORY_SEPARATOR.TEMP_FOLDER.$this->exportFilename); } catch (Exception $ex) { throw $ex; } } /** * Create SQL CREATE TABLE for the exported data. * */ private function exportTables() { // Use the database connection to create a new adoSchema object. $schema = new adoSchema( $this->db ); // Parse the Schema - and supress errors to override the index not found errors $tableCreates = @$schema->ParseSchema(VCDDB_BASE.DIRECTORY_SEPARATOR.self::SCHEMA); foreach ($tableCreates as $sqlCreate) { $sqlCreate .= ";\n"; VCDUtils::write(VCDDB_BASE.DIRECTORY_SEPARATOR.TEMP_FOLDER.$this->exportFilename, $sqlCreate, true); } } /** * Create SQL INSERT commands for the exported data. * */ private function exportData() { try { $xml = simplexml_load_file(VCDDB_BASE.DIRECTORY_SEPARATOR.self::SCHEMA); $tables = $xml->table; foreach ($tables as $table) { $sqlOut = ''; unset($sqlColumns); unset($sqlColumnTypes); $sqlColumns = array(); $sqlColumnTypes = array(); $sqlTable = (string)$table['name']; // Get the field names foreach ($table->field as $column) { $sqlColumns[] = $column['name']; $sqlColumnTypes[] = $column['type']; } $query = 'SELECT * FROM ' . $sqlTable; $rs = $this->db->Execute($query); foreach ($rs as $rows) { $sqlOut = "INSERT INTO {$sqlTable} (".implode(',',$sqlColumns).") VALUES (".$this->getInsertValues($rows,$sqlColumnTypes).");\n"; VCDUtils::write(VCDDB_BASE.DIRECTORY_SEPARATOR.TEMP_FOLDER.$this->exportFilename, $sqlOut, true); } } unset($xml); } catch (Exception $ex) { throw $ex; } } /** * Get the correct values for the VALUES() syntax of the SQL INSERT Query * * @param array $data | Array of data * @param array $types | Array of column types * @return string | The SQL String in the VALUES() section */ private function getInsertValues($data, $types) { $res = array(); $count = count($data)/2; for ($i=0;$i<$count;$i++) { if ($types[$i]=='C' || $types[$i]=='X' || $types[$i]=='B' || $types[$i]=='D' || $types[$i]=='T' || $types[$i]=='L') { $res[$i] = $this->db->Quote($data[$i]); } else { if ($data[$i] == '') { $res[$i] = 'NULL'; } else { $res[$i] = $data[$i]; } } } return implode(',',$res); } /** * Stream file to browser. Return true on success * * @param string $path | The file to stream * @return bool */ private static function sendFile($path) { session_write_close(); @ob_end_clean(); if (!is_file($path) || connection_status()!=0) return(FALSE); //to prevent long file from getting cut off from //max_execution_time @set_time_limit(0); $name=basename($path); //filenames in IE containing dots will screw up the //filename unless we add this if (strstr($_SERVER['HTTP_USER_AGENT'], "MSIE")) $name = preg_replace('/\./', '%2e', $name, substr_count($name, '.') - 1); //required, or it might try to send the serving //document instead of the file header("Cache-Control: "); header("Pragma: "); header("Content-Type: application/octet-stream"); header("Content-Length: " .(string)(filesize($path)) ); header('Content-Disposition: attachment; filename="'.$name.'"'); header("Content-Transfer-Encoding: binary\n"); if($file = fopen($path, 'rb')){ while( (!feof($file)) && (connection_status()==0) ){ print(fread($file, 1024*8)); flush(); } fclose($file); } return((connection_status()==0) and !connection_aborted()); } } ?>