public function compileLess($inputFile, $outputFile) { if (!class_exists('lessc')) { require_once KPATH_FRAMEWORK . '/external/lessc/lessc.php'; } // Load the cache. $cacheDir = JPATH_CACHE . '/kunena'; if (!is_dir($cacheDir)) { KunenaFolder::create($cacheDir); } $cacheFile = "{$cacheDir}/kunena.bootstrap.{$inputFile}.cache"; if (is_file($cacheFile)) { $cache = unserialize(file_get_contents($cacheFile)); } else { $cache = KPATH_MEDIA . '/less/bootstrap/' . $inputFile; } $outputFile = KPATH_MEDIA . '/css/joomla25/' . $outputFile; $less = new lessc(); //$less->setVariables($this->style_variables); $newCache = $less->cachedCompile($cache); if (!is_array($cache) || $newCache['updated'] > $cache['updated'] || !is_file($outputFile)) { $cache = serialize($newCache); KunenaFile::write($cacheFile, $cache); KunenaFile::write($outputFile, $newCache['compiled']); } }
/** * Create new re-sized version of the original image. * * @param string $file Incoming file * @param string $folder Folder for the new image. * @param string $filename Filename for the new image. * @param int $maxWidth Maximum width for the image. * @param int $maxHeight Maximum height for the image. * @param int $quality Quality for the file (1-100). * @param int $scale See available KunenaImage constants. * @param int $crop Define if you want crop the image. * * @return bool True on success. */ public static function version($file, $folder, $filename, $maxWidth = 800, $maxHeight = 800, $quality = 70, $scale = KunenaImage::SCALE_INSIDE, $crop = 0) { try { // Create target directory if it does not exist. if (!KunenaFolder::exists($folder) && !KunenaFolder::create($folder)) { return false; } // Make sure that index.html exists in the folder. KunenaFolder::createIndex($folder); $info = KunenaImage::getImageFileProperties($file); if ($info->width > $maxWidth || $info->height > $maxHeight) { // Make sure that quality is in allowed range. if ($quality < 1 || $quality > 100) { $quality = 70; } // Calculate quality for PNG. if ($info->type == IMAGETYPE_PNG) { $quality = intval(($quality - 1) / 10); } $options = array('quality' => $quality); // Resize image and copy it to temporary file. $image = new KunenaImage($file); if ($crop && $info->width > $info->height) { $image = $image->resize($info->width * $maxHeight / $info->height, $maxHeight, false, $scale); $image = $image->crop($maxWidth, $maxHeight); } elseif ($crop && $info->width < $info->height) { $image = $image->resize($maxWidth, $info->height * $maxWidth / $info->width, false, $scale); $image = $image->crop($maxWidth, $maxHeight); } else { $image = $image->resize($maxWidth, $maxHeight, false, $scale); } $temp = KunenaPath::tmpdir() . '/kunena_' . md5(rand()); $image->toFile($temp, $info->type, $options); unset($image); // Move new file to its proper location. if (!KunenaFile::move($temp, "{$folder}/{$filename}")) { unlink($temp); return false; } } else { // Copy original file to the new location. if (!KunenaFile::copy($file, "{$folder}/{$filename}")) { return false; } } } catch (Exception $e) { return false; } return true; }
/** * Set attachment file. * * Copies the attachment into proper location and makes sure that all the unset fields get properly assigned. * * @param string $source Absolute path to the upcoming attachment. * @param string $basename Filename without extension. * @param string $extension File extension. * @param bool $unlink Whether to delete the original file or not. * @param bool $overwrite If not allowed, throw exception if the file exists. * * @return bool * @throws InvalidArgumentException * @throws RuntimeException * * @since K4.0 */ public function saveFile($source, $basename = null, $extension = null, $unlink = false, $overwrite = false) { if (!is_file($source)) { throw new InvalidArgumentException(__CLASS__ . '::' . __METHOD__ . '(): Attachment file not found.'); } // Hash, size and MIME are set during saving, so let's deal with all other variables. $this->userid = is_null($this->userid) ? KunenaUserHelper::getMyself() : $this->userid; $this->folder = is_null($this->folder) ? "media/kunena/attachments/{$this->userid}" : $this->folder; $this->protected = is_null($this->protected) ? (bool) KunenaConfig::getInstance()->attachment_protection : $this->protected; if (!$this->filename_real) { $this->filename_real = $this->filename; } if (!$this->filename || $this->filename == $this->filename_real) { if (!$basename || !$extension) { throw new InvalidArgumentException(__CLASS__ . '::' . __METHOD__ . '(): Parameters $basename or $extension not provided.'); } // Find available filename. $this->filename = KunenaAttachmentHelper::getAvailableFilename($this->folder, $basename, $extension, $this->protected); } // Create target directory if it does not exist. if (!KunenaFolder::exists(JPATH_ROOT . "/{$this->folder}") && !KunenaFolder::create(JPATH_ROOT . "/{$this->folder}")) { throw new RuntimeException(JText::_('Failed to create attachment directory.')); } $destination = JPATH_ROOT . "/{$this->folder}/{$this->filename}"; // Move the file into the final location (if not already in there). if ($source != $destination) { // Create target directory if it does not exist. if (!$overwrite && is_file($destination)) { throw new RuntimeException(JText::sprintf('Attachment %s already exists.'), $this->filename_real); } if ($unlink) { @chmod($source, 0644); } $success = KunenaFile::copy($source, $destination); if (!$success) { throw new RuntimeException(JText::sprintf('COM_KUNENA_UPLOAD_ERROR_NOT_MOVED', $destination)); } KunenaPath::setPermissions($destination); if ($unlink) { unlink($source); } } return $this->save(); }
/** * Upload a file via AJAX, supports chunks and fallback to regular file upload. * * @param array $options Upload options. * * @return array Updated options. * @throws Exception|RuntimeException */ public function ajaxUpload(array $options) { static $defaults = array('completed' => false, 'filename' => null, 'size' => 0, 'mime' => null, 'hash' => null, 'chunkStart' => 0, 'chunkEnd' => 0); $options += $defaults; $config = KunenaConfig::getInstance(); $exception = null; $in = null; $out = null; $size = $bytes = 0; $outFile = null; // Look for the content type header if (isset($_SERVER['HTTP_CONTENT_TYPE'])) { $contentType = $_SERVER['HTTP_CONTENT_TYPE']; } elseif (isset($_SERVER['CONTENT_TYPE'])) { $contentType = $_SERVER['CONTENT_TYPE']; } else { $contentType = ''; } try { // Set filename for future queries. $this->filename = $options['filename']; $folder = $this->getFolder(); // Create target directory if it does not exist. if (!KunenaFolder::exists($folder) && !KunenaFolder::create($folder)) { throw new RuntimeException(JText::_('Failed to create upload directory.'), 500); } // Calculate temporary filename. $outFile = $this->getProtectedFile(); if ($options['chunkEnd'] > $options['size'] || $options['chunkStart'] > $options['chunkEnd']) { throw new RuntimeException(JText::_('COM_KUNENA_UPLOAD_ERROR_EXTRA_CHUNK'), 400); } if ($options['size'] > max($config->filesize, $config->imagesize) * 1024) { throw new RuntimeException(JText::sprintf('COM_KUNENA_UPLOAD_ERROR_SIZE_X', $this->bytes($options['size'])), 400); } if (strpos($contentType, 'multipart') !== false) { // Older WebKit browsers didn't support multi-part in HTML5. $exception = $this->checkUpload($_FILES['file']); if ($exception) { throw $exception; } $in = fopen($_FILES['file']['tmp_name'], 'rb'); } else { // Multi-part upload. $in = fopen('php://input', 'rb'); } if (!$in) { throw new RuntimeException(JText::_('Failed to open upload input stream.'), 500); } // Open temporary file. $out = fopen($outFile, !$options['chunkStart'] ? 'wb' : 'r+b'); if (!$out) { throw new RuntimeException(JText::_('Failed to open upload output stream.'), 500); } // Get current size for the file. $stat = fstat($out); if (!$stat) { throw new RuntimeException(JText::_('COM_KUNENA_UPLOAD_ERROR_STAT', $options['filename']), 500); } $size = $stat['size']; if ($options['chunkStart'] > $size) { throw new RuntimeException(JText::sprintf('Missing data chunk at location %d.', $size), 500); } fseek($out, $options['chunkStart']); while (!feof($in)) { // Set script execution time to 8 seconds in order to interrupt stalled file transfers (< 1kb/sec). // Not sure if it works, though, needs some testing. :) @set_time_limit(8); $buff = fread($in, 8192); if ($buff === false) { throw new RuntimeException(JText::_('Failed to read from upload input stream.'), 500); } $bytes = fwrite($out, $buff); if ($bytes === false) { throw new RuntimeException(JText::_('Failed to write into upload output stream.'), 500); } $size += $bytes; if ($size > max($config->filesize, $config->imagesize) * 1024) { throw new RuntimeException(JText::sprintf('COM_KUNENA_UPLOAD_ERROR_SIZE_X', $this->bytes($size)), 400); } } } catch (Exception $exception) { } // Reset script execution time. @set_time_limit(25); if ($in) { fclose($in); } if ($out) { fclose($out); } if ($exception instanceof Exception) { $this->cleanup(); throw $exception; } // Generate response. if (is_null($options['size']) && $size || $size === $options['size']) { $options['size'] = (int) $size; $options['completed'] = true; } $options['chunkStart'] = (int) $size; $options['chunkEnd'] = min($size + 1024 * 1024, $size + $this->getMaxSize(), max($size, $options['size'], is_null($options['size']) ? $this->getMaxSize() : 0)) - 1; if ($options['completed']) { $options['mime'] = KunenaFile::getMime($outFile); $options['hash'] = md5_file($outFile); } else { if ($size) { $options['mime'] = KunenaFile::getMime($outFile); } } return $options; }
/** * Clear cached template files. */ public static function clearTemplateFiles() { // Delete all cached files. $cacheDir = JPATH_ROOT."/media/kunena/cache"; if (is_dir($cacheDir)) { KunenaFolder::delete($cacheDir); } KunenaFolder::create($cacheDir); }
function compileLess($inputFile, $outputFile) { if (!class_exists('lessc')) { require_once KPATH_FRAMEWORK . '/external/lessc/lessc.php'; } // Load the cache. $cacheDir = JPATH_CACHE . '/kunena'; if (!is_dir($cacheDir)) { KunenaFolder::create($cacheDir); } $cacheFile = "{$cacheDir}/kunena.{$this->name}.{$inputFile}.cache"; if (is_file($cacheFile)) { $cache = unserialize(file_get_contents($cacheFile)); } else { $cache = JPATH_SITE . '/' . $this->getFile($inputFile, false, 'less'); } $outputDir = KPATH_MEDIA . "/cache/{$this->name}/css"; if (!is_dir($outputDir)) { KunenaFolder::create($outputDir); } $outputFile = "{$outputDir}/{$outputFile}"; $less = new lessc(); $class = $this; $less->registerFunction('url', function ($arg) use($class) { list($type, $q, $values) = $arg; $value = reset($values); return "url({$q}{$class->getFile($value, true, 'media', 'media/kunena')}{$q})"; }); $less->setVariables($this->style_variables); $newCache = $less->cachedCompile($cache); if (!is_array($cache) || $newCache['updated'] > $cache['updated'] || !is_file($outputFile)) { $cache = serialize($newCache); KunenaFile::write($cacheFile, $cache); KunenaFile::write($outputFile, $newCache['compiled']); } }