function deleteTempFiles() { $configuration =& JoomlapackModelRegistry::getInstance(); $tempFiles = JoomlapackCUBETables::UnserializeVar('CUBETempFiles', array()); foreach ($tempFiles as $fileName) { $file = $configuration->getTemporaryDirectory() . DS . $fileName; if (file_exists($file)) { @unlink($file); } } JoomlapackCUBETables::DeleteVar('CUBETempFiles'); }
/** * The most basic file transaction: add a single entry (file or directory) to * the archive. * * @param bool $isVirtual If true, the next parameter contains file data instead of a file name * @param string $sourceNameOrData Absolute file name to read data from or the file data itself is $isVirtual is true * @param string $targetName The (relative) file name under which to store the file in the archive * @return True on success, false otherwise * @since 1.2.1 * @access protected * @abstract */ function _addFile($isVirtual, &$sourceNameOrData, $targetName) { static $configuration; if (!$configuration) { jpimport('models.registry', true); $configuration =& JoomlapackModelRegistry::getInstance(); } // See if it's a directory $isDir = $isVirtual ? false : is_dir($sourceNameOrData); // Get real size before compression if ($isVirtual) { $fileSize = strlen($sourceNameOrData); } else { $fileSize = $isDir ? 0 : filesize($sourceNameOrData); } // Decide if we will compress if ($isDir) { $compressionMethod = 0; // don't compress directories... } else { // Do we have plenty of memory left? $memLimit = ini_get("memory_limit"); if (is_numeric($memLimit) && $memLimit < 0) { $memLimit = ""; } // 1.2a3 -- Rare case with memory_limit < 0, e.g. -1Mb! if ($memLimit == "" || $fileSize >= _JoomlapackPackerZIP_COMPRESSION_THRESHOLD) { // No memory limit, or over 1Mb files => always compress up to 1Mb files (otherwise it times out) $compressionMethod = $fileSize <= _JoomlapackPackerZIP_COMPRESSION_THRESHOLD ? 1 : 0; } elseif (function_exists("memory_get_usage")) { // PHP can report memory usage, see if there's enough available memory; Joomla! alone eats about 5-6Mb! This code is called on files <= 1Mb $memLimit = $this->_return_bytes($memLimit); $availableRAM = $memLimit - memory_get_usage(); $compressionMethod = $availableRAM / 2.5 >= $fileSize ? 1 : 0; } else { // PHP can't report memory usage, compress only files up to 512Kb (conservative approach) and hope it doesn't break $compressionMethod = $fileSize <= 524288 ? 1 : 0; } } $compressionMethod = function_exists("gzcompress") ? $compressionMethod : 0; $storedName = $targetName; /* "Entity Description BLock" segment. */ $unc_len =& $fileSize; // File size $storedName .= $isDir ? "/" : ""; if ($compressionMethod == 1) { if ($isVirtual) { $udata =& $sourceNameOrData; } else { // Get uncompressed data if (function_exists("file_get_contents") && _JoomlapackPackerZIP_FORCE_FOPEN == false) { $udata = @file_get_contents($sourceNameOrData); // PHP > 4.3.0 saves us the trouble } else { // Argh... the hard way! $udatafp = @fopen($sourceNameOrData, "rb"); if (!($udatafp === false)) { $udata = ""; while (!feof($udatafp)) { // Keep-alive on file reading if ($configuration->get("enableMySQLKeepalive", false)) { list($usec, $sec) = explode(" ", microtime()); $endTime = (double) $usec + (double) $sec; if ($endTime - $this->startTime > 0.5) { $this->startTime = $endTime; JoomlapackCUBETables::WriteVar('dummy', 1); } } $udata .= fread($udatafp, JPPACK_CHUNK); } fclose($udatafp); } else { $udata = false; } } } if ($udata === FALSE) { // Unreadable file, skip it. JoomlapackLogger::WriteLog(_JP_LOG_WARNING, JText::sprintf('CUBE_WARN_UNREADABLEFILE', $sourceNameOrData)); return false; } else { // Proceed with compression $zdata = @gzcompress($udata); if ($zdata === false) { // If compression fails, let it behave like no compression was available $c_len =& $unc_len; $compressionMethod = 0; } else { unset($udata); $zdata = substr(substr($zdata, 0, strlen($zdata) - 4), 2); $c_len = strlen($zdata); } } } else { $c_len = $unc_len; } $this->_compressedSize += $c_len; // Update global data $this->_uncompressedSize += $fileSize; // Update global data $this->_fileCount++; // Get file permissions $perms = $isVirtual ? 0777 : @fileperms($sourceNameOrData); // Calculate Entity Description Block length $blockLength = 21 + strlen($storedName); // Open data file for output $fp = @fopen($this->_dataFileName, "ab"); if ($fp === false) { $this->setError("Could not open archive file '{$this->_dataFileName}' for append!"); return; } $this->_fwrite($fp, $this->_fileHeader); // Entity Description Block header if ($this->getError()) { return; } $this->_fwrite($fp, pack('v', $blockLength)); // Entity Description Block header length $this->_fwrite($fp, pack('v', strlen($storedName))); // Length of entity path $this->_fwrite($fp, $storedName); // Entity path $this->_fwrite($fp, pack('C', $isDir ? 0 : 1)); // Entity type $this->_fwrite($fp, pack('C', $compressionMethod)); // Compression method $this->_fwrite($fp, pack('V', $c_len)); // Compressed size $this->_fwrite($fp, pack('V', $unc_len)); // Uncompressed size $this->_fwrite($fp, pack('V', $perms)); // Entity permissions /* "File data" segment. */ if ($compressionMethod == 1) { // Just dump the compressed data $this->_fwrite($fp, $zdata); if ($this->getError()) { return; } unset($zdata); } elseif (!$isDir) { if ($isVirtual) { $this->_fwrite($fp, $sourceNameOrData); if ($this->getError()) { return; } } else { // Copy the file contents, ignore directories $zdatafp = @fopen($sourceNameOrData, "rb"); if ($zdatafp === FALSE) { JoomlapackLogger::WriteLog(_JP_LOG_WARNING, JText::sprintf('CUBE_WARN_UNREADABLEFILE', $sourceNameOrData)); return false; } else { while (!feof($zdatafp)) { $zdata = fread($zdatafp, JPPACK_CHUNK); $this->_fwrite($fp, $zdata); if ($this->getError()) { return; } } fclose($zdatafp); } } } fclose($fp); // ... and return TRUE = success return TRUE; }
/** * Returns the CRC32 of a file, selecting the more appropriate algorithm. * * @param string $filename Absolute path to the file being processed * @param integer $JoomlapackPackerZIP_CHUNK_SIZE Obsoleted * @return integer The CRC32 in numerical form */ function crc32_file($filename, $JoomlapackPackerZIP_CHUNK_SIZE) { static $configuration; if (!$configuration) { jpimport('models.registry', true); $configuration =& JoomlapackModelRegistry::getInstance(); } // Keep-alive before CRC32 calculation if ($configuration->get("enableMySQLKeepalive", false)) { list($usec, $sec) = explode(" ", microtime()); $endTime = (double) $usec + (double) $sec; if ($endTime - $this->startTime > 0.5) { $this->startTime = $endTime; JoomlapackCUBETables::WriteVar('dummy', 1); } } if (function_exists("hash_file")) { $res = $this->crc32_file_php512($filename); JoomlapackLogger::WriteLog(_JP_LOG_DEBUG, "File {$filename} - CRC32 = " . dechex($res) . " [PHP512]"); } else { if (function_exists("file_get_contents") && @filesize($filename) <= $JoomlapackPackerZIP_CHUNK_SIZE) { $res = $this->crc32_file_getcontents($filename); JoomlapackLogger::WriteLog(_JP_LOG_DEBUG, "File {$filename} - CRC32 = " . dechex($res) . " [GETCONTENTS]"); } else { $res = $this->crc32_file_php4($filename, $JoomlapackPackerZIP_CHUNK_SIZE); JoomlapackLogger::WriteLog(_JP_LOG_DEBUG, "File {$filename} - CRC32 = " . dechex($res) . " [PHP4]"); } } if ($res === FALSE) { $cube =& JoomlapackCUBE::getInstance(); $cube->addWarning("File {$filename} - NOT READABLE: CRC32 IS WRONG!"); } return $res; }
/** * Adds an entry to the engine includes table * * @param string $dottedNotation Dotted notation of class file to add to the list */ function _addEngineInclude($dottedNotation) { if (JoomlapackCUBETables::CountVar('CUBEEngineIncludes') >= 1) { // There is a db entry. Load, and unserialize $includes = JoomlapackCUBETables::UnserializeVar('CUBEEngineIncludes'); } else { // Start a new array $includes = array(); } // Append to the array $includes[] = $dottedNotation; // Serialize and save JoomlapackCUBETables::SerializeVar('CUBEEngineIncludes', $includes); }
function _deleteCUBEObject() { $tmpfile = JoomlapackCUBETables::_cubeTmpFile(1); if (!empty($tmpfile)) { JoomlapackLogger::WriteLog(_JP_LOG_INFO, "Removing CUBE temporary file: " . $tmpfile); @unlink($tmpfile); } JoomlapackCUBETables::DeleteVar('cubetmpfile'); }
/** * Caches the update.ini contents to database * @param $inidata string The update.ini data */ function _setUpdateINIcached($inidata) { JoomlapackCUBETables::WriteVar('updateini', $inidata); jimport('joomla.utilities.date'); $date = new JDate(); JoomlapackCUBETables::SerializeVar('lastupdatecheck', $date); }
/** * The most basic file transaction: add a single entry (file or directory) to * the archive. * * @param bool $isVirtual If true, the next parameter contains file data instead of a file name * @param string $sourceNameOrData Absolute file name to read data from or the file data itself is $isVirtual is true * @param string $targetName The (relative) file name under which to store the file in the archive * @return True on success, false otherwise * @since 1.2.1 * @access protected * @abstract */ function _addFile($isVirtual, &$sourceNameOrData, $targetName) { static $configuration; if (!$configuration) { jpimport('models.registry', true); $configuration =& JoomlapackModelRegistry::getInstance(); } // See if it's a directory $isDir = $isVirtual ? false : is_dir($sourceNameOrData); // See if it's a symlink (w/out dereference) $isSymlink = false; if ($this->_symlink_store_target) { $isSymlink = is_link($sourceNameOrData); } // Get real size before compression if ($isVirtual) { $fileSize = strlen($sourceNameOrData); } else { if ($isSymlink) { $fileSize = strlen(@readlink($sourceNameOrData)); } else { $fileSize = $isDir ? 0 : @filesize($sourceNameOrData); } } // Decide if we will compress if ($isDir || $isSymlink) { $compressionMethod = 0; // don't compress directories... } else { // Do we have plenty of memory left? $memLimit = ini_get("memory_limit"); if (is_numeric($memLimit) && $memLimit < 0) { $memLimit = ""; } // 1.2a3 -- Rare case with memory_limit < 0, e.g. -1Mb! if ($memLimit == "" || $fileSize >= _JoomlapackPackerZIP_COMPRESSION_THRESHOLD) { // No memory limit, or over 1Mb files => always compress up to 1Mb files (otherwise it times out) $compressionMethod = $fileSize <= _JoomlapackPackerZIP_COMPRESSION_THRESHOLD ? 1 : 0; } elseif (function_exists("memory_get_usage")) { // PHP can report memory usage, see if there's enough available memory; Joomla! alone eats about 5-6Mb! This code is called on files <= 1Mb $memLimit = $this->_return_bytes($memLimit); $availableRAM = $memLimit - memory_get_usage(); $compressionMethod = $availableRAM / 2.5 >= $fileSize ? 1 : 0; } else { // PHP can't report memory usage, compress only files up to 512Kb (conservative approach) and hope it doesn't break $compressionMethod = $fileSize <= 524288 ? 1 : 0; } } $compressionMethod = function_exists("gzcompress") ? $compressionMethod : 0; $storedName = $targetName; /* "Entity Description BLock" segment. */ $unc_len =& $fileSize; // File size $storedName .= $isDir ? "/" : ""; if ($compressionMethod == 1) { if ($isVirtual) { $udata =& $sourceNameOrData; } else { // Get uncompressed data if (function_exists("file_get_contents") && _JoomlapackPackerZIP_FORCE_FOPEN == false) { $udata = @file_get_contents($sourceNameOrData); // PHP > 4.3.0 saves us the trouble } else { // Argh... the hard way! $udatafp = @fopen($sourceNameOrData, "rb"); if (!($udatafp === false)) { $udata = ""; while (!feof($udatafp)) { // Keep-alive on file reading if ($configuration->get("enableMySQLKeepalive", false)) { list($usec, $sec) = explode(" ", microtime()); $endTime = (double) $usec + (double) $sec; if ($endTime - $this->startTime > 0.5) { $this->startTime = $endTime; JoomlapackCUBETables::WriteVar('dummy', 1); } } $udata .= fread($udatafp, JPPACK_CHUNK); } fclose($udatafp); } else { $udata = false; } } } if ($udata === FALSE) { // Unreadable file, skip it. JoomlapackLogger::WriteLog(_JP_LOG_WARNING, JText::sprintf('CUBE_WARN_UNREADABLEFILE', $sourceNameOrData)); return false; } else { // Proceed with compression $zdata = @gzcompress($udata); if ($zdata === false) { // If compression fails, let it behave like no compression was available $c_len =& $unc_len; $compressionMethod = 0; } else { unset($udata); $zdata = substr(substr($zdata, 0, strlen($zdata) - 4), 2); $c_len = strlen($zdata); } } } else { $c_len = $unc_len; } $this->_compressedSize += $c_len; // Update global data $this->_uncompressedSize += $fileSize; // Update global data $this->_fileCount++; // Get file permissions $perms = $isVirtual ? 0777 : @fileperms($sourceNameOrData); // Calculate Entity Description Block length $blockLength = 21 + strlen($storedName); // Get file type if (!$isDir && !$isSymlink) { $fileType = 1; } elseif ($isSymlink) { $fileType = 2; } elseif ($isDir) { $fileType = 0; } // If it's a split ZIP file, we've got to make sure that the header can fit in the part if ($this->_useSplitZIP) { // Compare to free part space clearstatcache(); $current_part_size = @filesize($this->_dataFileName); $free_space = $this->_fragmentSize - ($current_part_size === false ? 0 : $current_part_size); if ($free_space <= $blockLength) { // Not enough space on current part, create new part if (!$this->_createNewPart()) { $this->setError('Could not create new JPA part file ' . basename($this->_dataFileName)); return false; } } } // Open data file for output $fp = @fopen($this->_dataFileName, "ab"); if ($fp === false) { $this->setError("Could not open archive file '{$this->_dataFileName}' for append!"); return; } $this->_fwrite($fp, $this->_fileHeader); // Entity Description Block header if ($this->getError()) { return; } $this->_fwrite($fp, pack('v', $blockLength)); // Entity Description Block header length $this->_fwrite($fp, pack('v', strlen($storedName))); // Length of entity path $this->_fwrite($fp, $storedName); // Entity path $this->_fwrite($fp, pack('C', $fileType)); // Entity type $this->_fwrite($fp, pack('C', $compressionMethod)); // Compression method $this->_fwrite($fp, pack('V', $c_len)); // Compressed size $this->_fwrite($fp, pack('V', $unc_len)); // Uncompressed size $this->_fwrite($fp, pack('V', $perms)); // Entity permissions /* "File data" segment. */ if ($compressionMethod == 1) { if (!$this->_useSplitZIP) { // Just dump the compressed data $this->_fwrite($fp, $zdata); if ($this->getError()) { return; } } else { // Split ZIP. Check if we need to split the part in the middle of the data. clearstatcache(); $current_part_size = @filesize($this->_dataFileName); $free_space = $this->_fragmentSize - ($current_part_size === false ? 0 : $current_part_size); if ($free_space >= strlen($zdata)) { // Write in one part $this->_fwrite($fp, $zdata); if ($this->getError()) { return; } } else { $bytes_left = strlen($zdata); while ($bytes_left > 0) { clearstatcache(); $current_part_size = @filesize($this->_dataFileName); $free_space = $this->_fragmentSize - ($current_part_size === false ? 0 : $current_part_size); // Split between parts - Write first part $this->_fwrite($fp, $zdata, $free_space); if ($this->getError()) { return; } // Get the rest of the data $bytes_left = strlen($zdata) - $free_space; if ($bytes_left > 0) { // Create new part if (!$this->_createNewPart()) { // Die if we couldn't create the new part $this->setError('Could not create new JPA part file ' . basename($this->_dataFileName)); return false; } else { // Close the old data file fclose($fp); // Open data file for output $fp = @fopen($this->_dataFileName, "ab"); if ($fp === false) { $this->setError("Could not open archive file {$this->_dataFileName} for append!"); return false; } } $zdata = substr($zdata, -$bytes_left); } } } } unset($zdata); } elseif (!$isDir && !$isSymlink) { if ($isVirtual) { if (!$this->_useSplitZIP) { // Just dump the data $this->_fwrite($fp, $sourceNameOrData); if ($this->getError()) { return; } } else { // Split ZIP. Check if we need to split the part in the middle of the data. clearstatcache(); $current_part_size = @filesize($this->_dataFileName); $free_space = $this->_fragmentSize - ($current_part_size === false ? 0 : $current_part_size); if ($free_space >= strlen($sourceNameOrData)) { // Write in one part $this->_fwrite($fp, $sourceNameOrData); if ($this->getError()) { return; } } else { $bytes_left = strlen($sourceNameOrData); while ($bytes_left > 0) { clearstatcache(); $current_part_size = @filesize($this->_dataFileName); $free_space = $this->_fragmentSize - ($current_part_size === false ? 0 : $current_part_size); // Split between parts - Write first part $this->_fwrite($fp, $sourceNameOrData, $free_space); if ($this->getError()) { return; } // Get the rest of the data $rest_size = strlen($sourceNameOrData) - $free_space; if ($rest_size > 0) { // Create new part if (!$this->_createNewPart()) { // Die if we couldn't create the new part $this->setError('Could not create new JPA part file ' . basename($this->_dataFileName)); return false; } else { // Close the old data file fclose($fp); // Open data file for output $fp = @fopen($this->_dataFileName, "ab"); if ($fp === false) { $this->setError("Could not open archive file {$this->_dataFileName} for append!"); return false; } } $zdata = substr($sourceNameOrData, -$rest_size); } $bytes_left = $rest_size; } // end while } } } else { // Copy the file contents, ignore directories $zdatafp = @fopen($sourceNameOrData, "rb"); if ($zdatafp === FALSE) { JoomlapackLogger::WriteLog(_JP_LOG_WARNING, JText::sprintf('CUBE_WARN_UNREADABLEFILE', $sourceNameOrData)); return false; } else { if (!$this->_useSplitZIP) { while (!feof($zdatafp)) { $zdata = fread($zdatafp, JPPACK_CHUNK); $this->_fwrite($fp, $zdata); if ($this->getError()) { return; } } } else { // Split ZIP - Do we have enough space to host the whole file? clearstatcache(); $current_part_size = @filesize($this->_dataFileName); $free_space = $this->_fragmentSize - ($current_part_size === false ? 0 : $current_part_size); if ($free_space >= $unc_len) { // Yes, it will fit inside this part, do quick copy while (!feof($zdatafp)) { $zdata = fread($zdatafp, JPPACK_CHUNK); $this->_fwrite($fp, $zdata); if ($this->getError()) { return; } } } else { // No, we'll have to split between parts. We'll loop until we run // out of space. while (!feof($zdatafp)) { clearstatcache(); $current_part_size = @filesize($this->_dataFileName); $free_space = $this->_fragmentSize - ($current_part_size === false ? 0 : $current_part_size); // Find optimal chunk size $chunk_size_primary = min(JPPACK_CHUNK, $free_space); if ($chunk_size_primary <= 0) { $chunk_size_primary = max(JPPACK_CHUNK, $free_space); } // Calculate if we have to read some more data (smaller chunk size) // and how many times we must read w/ the primary chunk size $chunk_size_secondary = $free_space % $chunk_size_primary; $loop_times = ($free_space - $chunk_size_secondary) / $chunk_size_primary; // Read and write with the primary chunk size for ($i = 1; $i <= $loop_times; $i++) { $zdata = fread($zdatafp, $chunk_size_primary); $this->_fwrite($fp, $zdata); if ($this->getError()) { return; } } // Read and write w/ secondary chunk size, if non-zero if ($chunk_size_secondary > 0) { $zdata = fread($zdatafp, $chunk_size_secondary); $this->_fwrite($fp, $zdata); if ($this->getError()) { return; } } // Create new JPA part, but only if we'll have more data to write if (!feof($zdatafp)) { if (!$this->_createNewPart()) { // Die if we couldn't create the new part $this->setError('Could not create new JPA part file ' . basename($this->_dataFileName)); return false; } else { // Close the old data file fclose($fp); // Open data file for output $fp = @fopen($this->_dataFileName, "ab"); if ($fp === false) { $this->setError("Could not open archive file {$this->_dataFileName} for append!"); return false; } } } } // end while } } fclose($zdatafp); } } } elseif ($isSymlink) { $this->_fwrite($fp, @readlink($sourceNameOrData)); } fclose($fp); // ... and return TRUE = success return TRUE; }
/** * Write to file, defeating magic_quotes_runtime settings (pure binary write) * @param handle $fp Handle to a file * @param string $data The data to write to the file * @access protected */ function _fwrite($fp, $data, $p_len = null) { static $configuration; if (!$configuration) { jpimport('models.registry', true); $configuration =& JoomlapackModelRegistry::getInstance(); } if ($configuration->get("enableMySQLKeepalive", false)) { list($usec, $sec) = explode(" ", microtime()); $endTime = (double) $usec + (double) $sec; if ($endTime - $this->startTime > 0.5) { $this->startTime = $endTime; JoomlapackCUBETables::WriteVar('dummy', 1); } } $len = is_null($p_len) ? strlen($data) : $p_len; $ret = fwrite($fp, $data, $len); if ($ret === FALSE) { $this->setError(JText::_('CUBE_ARCHIVER_CANTWRITE')); return false; } return true; }
/** * Writes a serialized copy of the $contentVariable to the database, under the packvar * variable name of $varName. * * @param string $varName The packvar to create * @param mixed $contentVariable Any variable to serialize (e.g. object, array, other variables, etc) */ function SerializeVar($varName, &$contentVariable) { $serialized = serialize($contentVariable); JoomlapackCUBETables::WriteVar($varName, $serialized); }
/** * Saves the CUBE object and all of its attached objects * */ function save() { JoomlapackCUBETables::SerializeVar('CUBEObject', $this); }
/** * Saves the CUBE object and all of its attached objects * */ function save() { JoomlapackLogger::WriteLog(_JP_LOG_DEBUG, "Saving CUBEObject instance"); JoomlapackCUBETables::SerializeVar('CUBEObject', $this); }